【问题标题】:Merge 2 files with awk while filling in missing values with 'NA'用 awk 合并 2 个文件,同时用 'NA' 填充缺失值
【发布时间】:2021-02-21 20:43:19
【问题描述】:

文件 1:

chr1:763668:T:C, C, T, 0.002, 0.001, 0, 0.001, 0.002, 0.002, 0.003, 0, 0.002, 0.690
chr1:775340:A:G, G, A, 0, 0, 0, 0, 0, 0, 0, 0, 0.001, 0
chr1:781598:C:T, T, C, 0, 0, 0, 0.001, 0.001, 0.001, 0.002, 0, 0, 0.688
chr1:781706:A:C, C, A, 0, 0, 0.687, 0, 0, 0.003, 0, 0, 0.002, 0
chr1:782519:A:G, G, A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.001

文件 2:

chr1:763668:T:C, C, T, 0.004, 0.001, 0, 0.002, 0, 0.001, 0.003, 0, 0.001, 0
chr1:775340:A:G, G, A, 0, 0, 0.687, 0, 0.02, 0, 0, 0, 0, 0
chr1:781706:A:C, C, A, 0.771, 0, 0, 0, 0, 0, 0, 0, 0.003, 0.001
chr1:782519:A:G, G, A, 0, 0, 0, 0.802, 0, 0, 0, 0.002, 0, 0.002
chr1:787139:A:G, G, A, 0.001, 0.001, 0, 0.001, 0.003, 0.006, 0.002, 0, 0.003, 0.011

在合并文件中,对于每个第 1 列标识符(在文件 1 和/或文件 2 中),存在于一个文件中但不存在于另一个文件中的数据需要用 NA 表示。文件需要按第1列的数值排序(如chr1:763668:T:C)

所需的输出文件:

chr1:763668:T:C, C, T, 0.002, 0.001, 0, 0.001, 0.002, 0.002, 0.003, 0, 0.002, 0.690, 0.004, 0.001, 0, 0.002, 0, 0.001, 0.003, 0, 0.001, 0
chr1:775340:A:G, G, A, 0, 0, 0, 0, 0, 0, 0, 0, 0.001, 0, 0, 0, 0.687, 0, 0.02, 0, 0, 0, 0, 0
chr1:781598:C:T, T, C, 0, 0, 0, 0.001, 0.001, 0.001, 0.002, 0, 0, 0.688, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA
chr1:781706:A:C, C, A, 0, 0, 0.687, 0, 0, 0.003, 0, 0, 0.002, 0, 0, 0, 0.687, 0, 0, 0.003, 0, 0, 0.002, 0
chr1:782519:A:G, G, A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.001, 0, 0, 0, 0.802, 0, 0, 0, 0.002, 0, 0.002
chr1:787139:A:G, G, A, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.001, 0.001, 0, 0.001, 0.003, 0.006, 0.002, 0, 0.003, 0.011

代码基于先前对类似请求的帮助:

awk 'BEGIN{filler="NA, NA, NA, NA, NA, NA, NA, NA, NA, NA"}
 {
                c1[$1]=$1
                c2[$1]=$2
                rest=substr($0, index($0, $3))

                if(NR==FNR){
                crest[$2]=rest
        }
        else{
                if(crest[$2]==""){
                        crest[$2]=filler OFS rest}
                else{
                        crest[$2]=crest[$2] OFS rest
                }
        }
        }
        END{
                for(i in c2){
                        print c1[i],c2[i],crest[i],filler
        }
}' file1 file2 | awk 'NF=26' | sort -k 1

【问题讨论】:

    标签: arrays sorting awk merge


    【解决方案1】:

    你可以使用这个awk:

    cat merge.awk
    
    BEGIN {
       filler = "NA, NA, NA, NA, NA, NA, NA, NA, NA, NA"
       FS = OFS = ", "
    }
    {
       k = $1 OFS $2 OFS $3
    }
    FNR == NR {
       sub(/^([^,]+, ){3}/, "")
       map[k] = $0
       next
    }
    {
       print $0, (k in map ? map[k] : filler)
       delete map[k]
    }
    END {
       for (i in map)
          print i, filler, map[i]
    }
    

    然后将其用作:

    awk -f merge.awk file2 file1
    
    chr1:763668:T:C, C, T, 0.002, 0.001, 0, 0.001, 0.002, 0.002, 0.003, 0, 0.002, 0.690, 0.004, 0.001, 0, 0.002, 0, 0.001, 0.003, 0, 0.001, 0
    chr1:775340:A:G, G, A, 0, 0, 0, 0, 0, 0, 0, 0, 0.001, 0, 0, 0, 0.687, 0, 0.02, 0, 0, 0, 0, 0
    chr1:781598:C:T, T, C, 0, 0, 0, 0.001, 0.001, 0.001, 0.002, 0, 0, 0.688, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA
    chr1:781706:A:C, C, A, 0, 0, 0.687, 0, 0, 0.003, 0, 0, 0.002, 0, 0.771, 0, 0, 0, 0, 0, 0, 0, 0.003, 0.001
    chr1:782519:A:G, G, A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.001, 0, 0, 0, 0.802, 0, 0, 0, 0.002, 0, 0.002
    chr1:787139:A:G, G, A, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.001, 0.001, 0, 0.001, 0.003, 0.006, 0.002, 0, 0.003, 0.011
    

    【讨论】:

    • 嗨@anubhava,我做了一些调整,并且能够让代码以所需的输出运行。是否可以更改此代码以调整任一输入文件(即要合并的文件 1 和文件 2)中可变数量的列?例如,我们是否可以“计算”文件 1 或文件 2 中的数据列数,并在缺少字段(即没有“固定”填充符)时用尽可能多的 NA 填充它们?
    • 答案基于您提出的问题和您提供的样本数据。如果您的实际数据与此处发布的数据不同,请更新您的问题并提供预期输出
    猜你喜欢
    • 2018-12-13
    • 2020-12-12
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多