在大数据集中基于亚组(A,B,C)的命中



我有大量数据要分析。

在此示例文件中,我需要知道所有命中("样本"(

  • 仅在B中,
  • 仅在C中,
  • 在A和C或
  • 在A和B中,

但不是找到的

  • 在B和C或C或
  • 在a,b和c。

[编辑:保持更简单:B和C]

不应同时存在

这些字母在第8列中找到。

前两列可以一起用作每个"样本"的标识符。

示例:您可以看到" 463; 88",我们在第8列中找到A和C,这将使" 463; 88"成为我在单独的输出文件中需要的命中。在A,B和C中发现了" 348; 64",因此将被丢弃/忽略。

file1.csv

463;88;1;193187729;280062;CDC73;IS;A;0.0
463;88;1;193188065;280062;CDC73;IS;A;0.0
463;88;1;193188527;280062;CDC73;IS;A;0.0
463;88;1;193188542;280062;CDC73;IS;C;0.0
348;64;1;155219446;384172;GBAP1;IS;B;0.0
348;64;1;155224629;384172;GBAP1;IS;C;0.0
348;64;1;155224965;384172;GBAP1;IS;A;0.0
71;35;2;27400461;145220;PPM1G;IS;A;0.0
71;35;2;27400930;145220;PPM1G;IS;A;0.0
71;35;2;27401162;145220;PPM1G;IS;A;0.0
71;35;2;27403518;145220;PPM1G;IS;B;0.0
71;35;2;27403545;145220;PPM1G;IS;B;0.0
71;35;2;27404353;145220;PPM1G;IS;B;0.0
71;35;2;27419156;145220;NRBP1;IS;B;0.0
7;14;20;2894103;92099;PTPRA;IS;B;0.0
7;14;20;2906211;92099;PTPRA;IS;C;0.0
7;14;20;2907301;92099;PTPRA;IS;C;0.0
...

有人有建议如何执行此操作,例如bash,awk,grep ...?

它不需要非常有效或快速,只需要可靠。

编辑:

i生成了一个CSV表,其中包含< 3列中的3列条目的第1和2列的CSV表,以几个步骤$ 8。

尴尬打印$ 1,$ 2,$ 8 |排序–N |uniq> file.tmp1

awk打印$ 1,$ 2来自file.tmp1 |排序–N |UNIC –C |用于CSV格式> file.tmp2

最后,
awk仅在file.tmp2中打印标识符列,其中计数为< 3(=原始文件的列8列中的$ 8中的一个或两个不同的字母(。

file2.csv
6; 3;
12; 9;
348; 40;463; 88;...

然后,我想使用fgrep -file = file2.csv file1.csv

但这似乎无法正常工作。而且它仍然需要手动分析,因为它也给了我错误的命中。

另一种替代

仅保留要删除的行的键,但两次扫描文件。另外,不需要对文件进行排序。

$ awk -F';' '{k=$1 FS $2} 
     NR==FNR {if($8=="B") b[k]; 
              else if($8=="C") c[k]; 
              if(k in b && k in c) d[k]; 
              next}  
    !(k in d)' file{,}
463;88;1;193187729;280062;CDC73;IS;A;0.0
463;88;1;193188065;280062;CDC73;IS;A;0.0
463;88;1;193188527;280062;CDC73;IS;A;0.0
463;88;1;193188542;280062;CDC73;IS;C;0.0
71;35;2;27400461;145220;PPM1G;IS;A;0.0
71;35;2;27400930;145220;PPM1G;IS;A;0.0
71;35;2;27401162;145220;PPM1G;IS;A;0.0
71;35;2;27403518;145220;PPM1G;IS;B;0.0
71;35;2;27403545;145220;PPM1G;IS;B;0.0
71;35;2;27404353;145220;PPM1G;IS;B;0.0
71;35;2;27419156;145220;NRBP1;IS;B;0.0

使用gawk S位操作,可以进一步简化为

$ awk -F';' 'BEGIN {c["B"]=1; c["C"]=2} 
                   {k=$1 FS $2} 
           NR==FNR {d[k]=or(d[k],c[$8]); next}  
           d[k]!=3' file{,}

or是一个IDEMPOTENT函数,如果可以看到" B"或" C",则更新数组。如果两者都看到该值是3,则在第二轮中打印所有其他内容。

您没有在问题中显示预期的输出,所以这是一个猜测,但是这是您要寻找的吗?

$ cat tst.awk
BEGIN { FS=OFS=";" }
{ curr = $1 FS $2 }
curr != prev { prt(); prev=curr }
{ lines[++numLines]=$0; seen[$8]++ }
END { prt() }
function prt() {
    if ( !(seen["B"] && seen["C"]) ) {
        for ( lineNr=1; lineNr<=numLines; lineNr++) {
            print lines[lineNr]
        }
    }
    delete seen
    numLines=0
}
$ awk -f tst.awk file
463;88;1;193187729;280062;CDC73;IS;A;0.0
463;88;1;193188065;280062;CDC73;IS;A;0.0
463;88;1;193188527;280062;CDC73;IS;A;0.0
463;88;1;193188542;280062;CDC73;IS;C;0.0
71;35;2;27400461;145220;PPM1G;IS;A;0.0
71;35;2;27400930;145220;PPM1G;IS;A;0.0
71;35;2;27401162;145220;PPM1G;IS;A;0.0
71;35;2;27403518;145220;PPM1G;IS;B;0.0
71;35;2;27403545;145220;PPM1G;IS;B;0.0
71;35;2;27404353;145220;PPM1G;IS;B;0.0
71;35;2;27419156;145220;NRBP1;IS;B;0.0

这样的东西应该有效,除非您的内存用完了:

BEGIN { FS=";"; }
{
    keys[$1,$2] = 1;
    data[$1,$2,$8] = $0;
}
END {
    for (key in keys) {
        a = data[key,"A"];
        b = data[key,"B"];
        c = data[key,"C"];
        if (!(b && c)) {
            if (a) { print a; }
            if (b) { print b; }
            if (c) { print c; }
        }
    }
}

假设所有具有相同键的线都是连续的,这应该有效:

BEGIN { FS=";"; }
$1";"$2 != key {
    if (!(data["B"] && data["C"])) {
        print key;
    }
    delete data;
    key = $1";"$2;
}
{
    data[$8] = 1;
}

相关内容

  • 没有找到相关文章

最新更新