我有一个看起来像这样的表:
DAPPUDRAFT_194440 Phosphorous
DAPPUDRAFT_194440 Temperature
DAPPUDRAFT_194472 Phosphorous Fishkairomones
DAPPUDRAFT_194472 Temperature
DAPPUDRAFT_194512 Fishkairomones
DAPPUDRAFT_194512 Cadmium Zinc Quantumdots
DAPPUDRAFT_195644 Salinity
DAPPUDRAFT_195644 Phosphorous
DAPPUDRAFT_196131 Salinity
DAPPUDRAFT_196131 Phosphorous
DAPPUDRAFT_196131 hypoxia
DAPPUDRAFT_196694 Salinity
正如您所看到的,它可以在可变数量的列中包含数据(由制表符分隔)。
应删除以“DAPPUDRAFT_”开头的第一列中的重复条目,并且多行中出现的所有其他值应出现在单行中。
例如,在我的输入表中,“DAPPUDRAFT_194440”在表中出现了 2 次,并且它在一行中有两个值“温度”,第二行有“磷”,如此处的数据子集所示:
DAPPUDRAFT_194440 Phosphorous
DAPPUDRAFT_194440 Temperature
我希望看到的是:“DAPPUDRAFT_”应该只出现一次,并且两个条目“温度”和“磷”应该出现在同一行中,并用选项卡分隔,如下所示:
DAPPUDRAFT_194440 Phosphorous Temperature
预期输出:
DAPPUDRAFT_194440 Phosphorous Temperature
DAPPUDRAFT_194472 Phosphorous Fishkairomones Temperature
DAPPUDRAFT_194512 Fishkairomones Cadmium Zinc Quantumdots
DAPPUDRAFT_195644 Salinity Phosphorous
DAPPUDRAFT_196694 Salinity
DAPPUDRAFT_196131 Salinity Phosphorous hypoxia
我尝试使用 R 中的“reshape2”包和 dcast 函数。但它所做的事情与我想要的完全不同。命令行、R 或 perl 有没有办法可以帮助解决这个问题?
答案1
简单地与awk:
awk '{ r=$0; sub($1,"",r); a[$1]=(a[$1])? a[$1]"\t"r : r }
END{ for(i in a) { gsub(/[[:space:]]{2,}/," ",a[i]); print i,a[i] } }' file
r=$0
- 捕获记录的副本sub($1,"",r)
- 删除副本中的第一个字段以将剩余字段存储在r
变量中a[$1]=(a[$1])? a[$1]"\t"r : r
- 累积相同的值团体(由第1场提出)for(i in a)
- 迭代所有分组的项目gsub(/[[:space:]]{2,}/," ",a[i])
- 删除单词之间过多的空格print i,a[i]
- 打印组名称及其值
输出:
DAPPUDRAFT_194440 Phosphorous Temperature
DAPPUDRAFT_196694 Salinity
DAPPUDRAFT_194512 Fishkairomones Cadmium Zinc Quantumdots
DAPPUDRAFT_194472 Phosphorous Fishkairomones Temperature
DAPPUDRAFT_196131 Salinity Phosphorous hypoxia
DAPPUDRAFT_195644 Salinity Phosphorous
答案2
或者
$ perl -e 'while(<ARGV>){chomp;($x,$y)=split(/\s+/,$_,2);$hash{$x}.=$y;}for(keys %hash){print "$_ $hash{$_}\n";}' test1
DAPPUDRAFT_196694 Salinity
DAPPUDRAFT_194440 Phosphorous Temperature
DAPPUDRAFT_195644 Salinity Phosphorous
DAPPUDRAFT_194472 Phosphorous Fishkairomones Temperature
DAPPUDRAFT_194512 Fishkairomones Cadmium Zinc Quantumdots
DAPPUDRAFT_196131 Salinity Phosphorous hypoxia
答案3
如果您不关心行和元素的排序方式:
sed 'G;s/^\(.*\)\(\t.*\)\n\(.*\)\1/\3\1\2/;h;$!d;s/\n$//' file
对于非 GNU,sed
将 替换\t
为文字 TAB。