行を複数の列に変換

行を複数の列に変換

次の形式の1505496行を含む大きなテキストファイルがあります。

PAN     rs1  G    G 
PAB     rs1  G    G 
PAC     rs1  G    G 
PAE     rs1  G    G 
PAT     rs1  G    G 
PAN     rs2  T    T 
PAB     rs2  T    T 
PAC     rs2  T    T 
PAE     rs2  T    T 
PAT     rs2  T    T 
PAN     rs3  A    C 
PAB     rs3  A    C 
PAC     rs3  A    C 
PAE     rs3  A    C 
PAT     rs3  A    C 
. 
. 

希望の出力が次のようになります。

          Rs1   rs1       rs2   rs2       rs3   rs3      ....
PAN        G    G          T        T       A      C
PAB        G    G          T        T       A      C
PAC        G    G          T        T       A      C
PAE        G    G          T        T       A      C
PAT        G    G          T        T       A      C

「rs」の数字は1153個で、各「rs」にはrefとaltの値があります(各rsに最初の列がrefで2番目の列がaltの場合)。

ベストアンサー1

配列の配列を処理するには、GNU awkを使用します。

$ cat tst.awk
BEGIN { OFS="\t" }
!seen[$1]++ { rowIds[++numRows] = $1 }
!seen[$2]++ { colIds[++numCols] = $2 }
{ vals[$1][$2] = $3 OFS $4 }
END {
    printf "%s%s", "", OFS
    for (colNr=1; colNr<=numCols; colNr++) {
        colId = colIds[colNr]
        printf "%s%s%s%s", colId, OFS, colId, (colNr<numCols ? OFS : ORS)
    }
    for (rowNr=1; rowNr<=numRows; rowNr++) {
        rowId = rowIds[rowNr]
        printf "%s%s", rowId, OFS
        for (colNr=1; colNr<=numCols; colNr++) {
            colId = colIds[colNr]
            printf "%s%s", vals[rowId][colId], (colNr<numCols ? OFS : ORS)
        }
    }
}

$ awk -f tst.awk file
        rs1     rs1     rs2     rs2     rs3     rs3
PAN     G       G       T       T       A       C
PAB     G       G       T       T       A       C
PAC     G       G       T       T       A       C
PAE     G       G       T       T       A       C
PAT     G       G       T       T       A       C

おすすめ記事