如果所有列中的值相同,则删除行

Posted

技术标签:

【中文标题】如果所有列中的值相同,则删除行【英文标题】:Delete row if same value in all columns 【发布时间】:2018-10-09 14:51:37 【问题描述】:

我有一个包含数千行和列的以空格分隔的大文件。我想删除除第一列之外的所有列中具有相同值的所有行。

输入:

CHROM   108 139 159 265 350 351
SNP1    -1  -1  -1  -1  -1  -1
SNP2    2   2   2   2   2   2
SNP3    0   0   0   -1  -1  -1
SNP4    1   1   1   1   1   1
SNP5    0   0   0   0   0   0

想要的

CHROM   108 139 159 265 350 351
SNP3    0   0   0   -1  -1  -1

对于 Panda 框架 (Delete duplicate rows with the same value in all columns in pandas) 提出了类似的问题,我找到了一个部分解决方案,它删除了仅包含零的行

awk 'NR > 1s=0; for (i=3;i<=NF;i++) s+=$i; if (s!=0)print' input > outfile

但我想一次性对数字 -1、0、1 和 2 执行此操作,并将标题和第一列作为标识符。

我们将不胜感激。

【问题讨论】:

【参考方案1】:

我相信你可以这样做:

awk 's=$0; gsub(FS $2,FS) (NF > 1) print s' file

哪些输出:

CHROM   108 139 159 265 350 351
SNP3    0   0   0   -1  -1  -1

这是如何工作的?

    s=$0; gsub(FS $2,FS):这个动作包含两部分:

    将当前行存储在变量s中 用字段分隔符FS 替换当前行$0 第二个字段的所有值,包括其起始字段分隔符FS (FS $2)。这会产生副作用,重新定义 $0,并重新定义所有字段变量和字段总数 NF。如果$2=x,则需要字段分隔符FS 以避免匹配xx

    (NF &gt; 1) print s:如果您还剩 1 个以上的字段,请打印该行,这意味着您有不同的数字。

【讨论】:

如果我们有一行SNP1 -1 -11 -1 -1 -1 -1,这将失败,它也会打印这一行。 @RavinderSingh13 应该如此。 -11 与 -1 不同 我的意思是这也会在输出中打印这一行,即使它不应该被打印。 @kvantour 找到最大长度的数字作为模式。但它会比我们在每个列中比较值要慢。 @RavinderSingh13 是的,我已经检查了所有解决方案,它们都运行良好。我非常感谢所有海报的努力:-)【参考方案2】:

你可以试试这个:

awk 'NR==1;NR>1for(i=2;i<NF;i++)if($(i+1)!=$i) print;next' file

它打印标题行。 它循环遍历字段,直到找到与下一个的差异,然后打印它,然后转到下一个。

【讨论】:

【参考方案3】:

请您尝试关注一下。

awk 'val=$2;count=1;for(i=3;i<=NF;i++)if(val==$i)count++;if(count!=(NF-1))print'  Input_file

【讨论】:

为什么不直接设置val = $2,然后从3开始循环for i?也不需要计数 - 一旦你找到不等于 val 的列,打印该行并跳出循环。 @Barmar,先生,现在肯定做到了,谢谢你让我知道。【参考方案4】:

便携式 Perl 解决方案:

$ cat all_row
CHROM   108 139 159 265 350 351
SNP1    -1  -1  -1  -1  -1  -1
SNP2    2   2   2   2   2   2
SNP3    0   0   0   -1  -1  -1
SNP4    1   1   1   1   1   1
SNP5    0   0   0   0   0   0

$ perl -F"\s+" -ane '  print "$_" if @F[1 .. $#F-1] != $F[1]  ' all_row
CHROM   108 139 159 265 350 351
SNP3    0   0   0   -1  -1  -1

$

如果询问是如果所有列中的值相同,则不要删除,那么

$ perl -F"\s+" -ane '  print "$_" if @F[1 .. $#F-1] == $F[1]  ' all_row
SNP1    -1  -1  -1  -1  -1  -1
SNP2    2   2   2   2   2   2
SNP4    1   1   1   1   1   1
SNP5    0   0   0   0   0   0

【讨论】:

以上是关于如果所有列中的值相同,则删除行的主要内容,如果未能解决你的问题,请参考以下文章

pandas:删除两列中具有相同索引的行中的重复值

如果单元格值包含列名,则 Excel 行中的值的平均值

如果特定列中的值不是熊猫数据框中的整数,则删除行

R:仅当同一列中的两行中的值为真时才将值添加到 [row,column]

用R中不同数据帧中具有相同ID的行中的值替换列中的NA

SQL 删除行,其中一个值与 DIFFERENT 列中的值匹配