【问题标题】:If column A in file 1 = column A in file 2, replace with column B from file 2如果文件 1 中的 A 列 = 文件 2 中的 A 列,则替换为文件 2 中的 B 列
【发布时间】:2013-06-03 16:43:25
【问题描述】:

通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何计算机都无法处理这个问题! (为从事遗传学工作的任何人提供的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,而我只剩下 Chromosome:Position 信息。所以我用我想要的所有 rs 数字创建了一个链接文件,并想用文件 2 中的 rs 数字替换文件 1 中的 Chr:Pos 列。

所以我在想办法编码:

If $3 of file 1 = $5 of file 2, replace $3 file 1 with $2 of file 2.

文件 1 看起来像

1111 1111 1:10583  G G
1112 1112 1:10583  G G
1113 1113 1:10583  G G
1114 1114 1:10583  G G
1115 1115 1:10583  G G

文件 2 看起来像

1   rs58108140  0   10583       1:10583
1   rs192319073 0   105830003   1:105830003
1   rs190151039 0   10583005    1:10583005
1   rs2809302   0   105830229   1:105830229
1   rs191085550 0   105830291   1:105830291

期望的输出是:

1111 1111 rs58108140  G G
1112 1112 rs58108140  G G
1113 1113 rs58108140  G G
1114 1114 rs58108140  G G
1115 1115 rs58108140  G G

【问题讨论】:

  • 文件 2 可以有多大?您可以从第 5 列和第 2 列创建 dict 吗?
  • 每个文件有多大?
  • 如果文件 1 的第 3 列总是以与文件 2 的第 5 列相同的顺序出现在组中,则每当在 file1 中遇到新组时,请使用 awk 并执行 file2 的 getline。现在不能提供详细信息,必须运行。 sudo_o 可以提供详细信息。
  • 文件 1 为 12.3 GB,文件 2 为 410.5MB

标签: python linux awk


【解决方案1】:

从file2创建字典

with open('file2', 'r') as file2:
   replacement = {}
   for line in file2:
       splited_line = line.split()
       replacement[splited_line[4]] = splited_line[1]

with open('file1', 'r') as file1:
    with open('file1_new', 'w') as file1_new:
        for line in file1:
            splitted_line = line.split()
            splitted_line[2] = replacement.get(splitted_line[1], splitted_line[1])
            file1_new.write(' '.join(splitted_line)+'\n')

【讨论】:

    【解决方案2】:

    简单的awk:

    $ awk 'FNR==NR{a[$5]=$2;next}$3 in a{$3=a[$3]}1' file2 file1
    1111 1111 rs58108140 G G
    1112 1112 rs58108140 G G
    1113 1113 rs58108140 G G
    1114 1114 rs58108140 G G
    1115 1115 rs58108140 G G
    

    【讨论】:

    • 我不太确定是不是.. The file seems to big 没有卖给我。
    • 我的电脑似乎已经达到了这个极限,而且它已经工作了!非常感谢您的帮助。
    • 太棒了。这是因为我们只在file2 的一列上构建了一个数组,因此该数组将小于 > 410.5MB,虽然现在很大,但这不会成为问题。因为我们只逐行阅读file1,所以这不是问题。
    • a[$3] 条件应为 $3 in a 以避免在该条目不存在时创建该条目。
    • @Kevin 在语义上并没有什么不同,因为空值将评估为 false,但是是的,$3 in a 更好。
    【解决方案3】:

    joinawk 可以做到这一点。您也可以使用cut 代替awk,但之后您必须以其他方式重新排序字段。

    join -1 3 -2 5 file1 file2 | awk '{print $2, $3, $7, $4, $5}'
    

    警告:如 sudo_O 所述,这仅在文件已排序时才有效 - 我假设它们是基于给定示例的。如果他们不是,这不会很快。如果它们已经排序,则不需要将它们读入内存,因为这两个命令都会在读取数据时对其进行处理。

    【讨论】:

    • 加入需要对文件进行排序。您真的不想对 2 个大文件进行排序,然后加入它们,然后运行 ​​awk。
    • 也许我假设太多,但它们看起来确实在示例中排序。
    • file2 未排序运行diff file2 <(sort file2)
    • 在给定的示例中,它按我们尝试加入的最后一列排序。 (这里的命令应该是sort -k5 file2
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-16
    • 2021-03-14
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多