unix将long转换为宽

时间:2017-02-10 23:15:39

标签: shell unix join

我知道如何在R中执行此操作,但遗憾的是我的数据集太大,因此我尝试使用shell将数据集从长格式转换为宽格式。

目前的格式是这样的:

Name1 A 3
Name2 A 6
Name3 A 10
Name3 B 2
Name4 A 4
Name5 B 1

我想将其转换为宽格式,以便第二列成为新列,第三列成为计数。如果没有谷,我想在它的位置插入一个0:

Name A B
Name1 3 0
Name2 6 0
Name3 10 2
Name4 4 0
Name5 0 1

根据我对linux和我的在线搜索的有限知识,我真的不知道如何处理这个问题。

我尝试解决此问题的一件事是使用grep将文件分组为两个单独的文件,然后尝试长连接。

grep A file | sort -k 1 > file_A
grep B file | sort -k 1 > file_B
join  -o '0,1.2,1.3,2.2,2.3' -e "0" -a1 -a2 <(sort -k 1 file_A) <(sort -k 1 file_B) > output
如果我只是运行join命令,

出现。但是,当我尝试将输出定向到文件时,我收到以下错误消息:

join: /dev/fd/63:63: is not sorted: Name4   A 83
join: /dev/fd/62:15: is not sorted: Name5   B 3

我在网上看到的所有内容都表明,当文件排序不正确时会出现此错误,但实际上我认为我按第1列对它们进行了两次排序。

关于从广泛到长格式的最佳方式的任何想法,或者如何解决我制作摘要表的麻烦都将非常感激。谢谢。

1 个答案:

答案 0 :(得分:2)

这是而非join的更多工具。您希望拥有一个二维数据结构来保存信息。我使用GNU awk按排序顺序迭代数组键。

gawk '
    {val[$1][$2] = $3} 
    END {
        PROCINFO["sorted_in"] = "@ind_str_asc"
        print "NAME A B"
        for (name in val) 
            print name, 0+val[name]["A"], 0+val[name]["B"]
    }
' file

我将该值添加到零,以便将未设置的数组元素视为数字零而不是空字符串。