행을 여러 열로 변환

행을 여러 열로 변환

다음 형식의 1,505,496줄을 포함하는 큰 텍스트 파일이 있습니다.

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이고 두 번째 열이 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

답변2

gawk(다차원 배열 기능 사용):

{
    if($2 ~ "rs[0-9]+")
    {
        idx = substr($2, 3)
        max_rs = idx > max_rs ? idx : max_rs
        a[$1][idx * 2 - 1] = $3
        a[$1][idx * 2] = $4
    }
}

END{

    # header
    printf "\t"
    for (i = 1; i <= max_rs; ++i) {
       printf "rs" i "\trs" i "\t"
    }
    printf "\n"

    # entries
    for (entry in a) {
        printf entry "\t"
        for (i = 1; i <= max_rs*2; ++i) {
            printf a[entry][i] "\t"
        }
        printf "\n"
    }
}

rs[index]모든 열을 a[key][index*2-1]합계 로 저장 a[key][index*2]하고 최대 수를 저장하는 데 사용되는 END로 출력하는 방식 으로 작동합니다 .max_rsrs

관련 정보