ヘッダーに基づく列の合計

ヘッダーに基づく列の合計

次のようにタブ区切りのファイル1があります(表示サブセット、実際の行列60x60000)。

rowname   header1 header2 header3 header4 header5 header6 header7 header8
rowname1    1       1        10       2     3       1       10       2 
rowname2    0       7        200      3     37      1        2       1 

次のような別のfile2があります。

header1,header2
header3
header4,header5
header6,header8
header7

file2の各行に指定された列を合計したいと思います。

rowname    header1 header3 header4 header6 header7 
rowname1    2        10        5     3       10
rowname2    7        200       40    2       2

つまり、1列+列2、3列、4列+5列、6列+8列、7列...

合計する必要がある列もあり、そうでない列もあり、合計する列が常に連続しているわけではありません。

列を合計する場合は、最初の列のヘッダーを出力ファイルに保持する必要があります。

解決策があるかどうか疑問に思うアッ。これまでは、ヘッダー項目を保存する方法だけを知っています。

awk '
NR==1 {
    for (i=1; i<=NF; i++) {
        f[$i] = i
    }

ベストアンサー1

awk '
  FNR==NR{
    newhdr[FNR]=$1       # new header name
    newhdrcnt++          # number of new header names
    for (i=1;i<=NF;i++)
      hdrnames[FNR]=$0   # save new header names comma-separated
    next
  }
  FNR==1{
    # save column numbers for new header names in array hdrcols
    for (i=1;i<=newhdrcnt;i++){
      n=split(hdrnames[i], oldhdr, ",")
      for(j=1;j<=n;j++){
        for(k=2;k<=NF;k++){
          if ($(k) == oldhdr[j]){
            hdrcols[i]=(j==1 ? "" : hdrcols[i] ",") k;
            if (j==n) break
          }
        }
      }
    }
    # print header
    printf $1
    for (i=1;i<=newhdrcnt;i++)
      printf FS newhdr[i]
    printf ORS
    next
  }
  { # print data
    printf $1
    for (i=1;i<=newhdrcnt;i++){
      n=split(hdrcols[i], cols, ",")
      res=0
      for(j=1;j<=n;j++)
        res=res+$(cols[j])
      printf FS res
    }
    printf ORS
  }
' FS="," file2 FS="\t" file1

出力:

rowname header1 header3 header4 header6 header7
rowname1        2       10      5       3       10
rowname2        7       200     40      2       2

おすすめ記事