각 그룹의 다수값을 기준으로 데이터 추정

각 그룹의 다수값을 기준으로 데이터 추정

col1에 기기가 있고 col2에 변수가 있고 col3에 호출이 있습니다. 이 예에는 17개의 INS와 3개의 M 유형이 있습니다. 17 x 3 행이 있을 수 있습니다. 그러나 일부는 누락되었습니다.

INS1    M1  AA
INS2    M1  AA
INS3    M1  AA
INS4    M1  GG
INS5    M1  GG
INS6    M1  GG
INS7    M1  AA
INS8    M1  GG
INS9    M1  GG
INS10   M1  AA
INS11   M1  AA
INS12   M1  GG
INS13   M1  AA
INS14   M1  AA
INS15   M1  AA
INS1    M2  GG
INS3    M2  TT
INS4    M2  GG
INS5    M2  GG
INS6    M2  TT
INS7    M2  TT
INS8    M2  TT
INS9    M2  TT
INS10   M2  GG
INS11   M2  GG
INS14   M2  GG
INS15   M2  TT
INS1    M3  AA
INS2    M3  TT
INS3    M3  AA
INS4    M3  TT
INS5    M3  TT
INS7    M3  AA
INS8    M3  TT
INS9    M3  AA
INS10   M3  TT
INS15   M3  TT

이 악기가 속한 그룹을 포함하는 또 다른 조회 파일이 있습니다. 예를 들어 INS(1,2,3,7,14,16 및 17)은 그룹 1에 속합니다.

GR1 INS1
GR1 INS2
GR1 INS3
GR1 INS7
GR1 INS14
GR1 INS16
GR1 INS17
GR2 INS5
GR2 INS6
GR2 INS8
GR2 INS9
GR2 INS15
GR3 INS4
GR3 INS10
GR3 INS11
GR3 INS12
GR3 INS13

70% 임계값을 초과하는 대부분의 그룹 통화를 기반으로 손실된 통화를 추정하려고 합니다. (예상 행은 별표로 표시되어 있지만 출력에는 필요하지 않습니다.)

그룹1 내에서 동일한 M 값의 호출 빈도가 AA=80%(3/4)이고 호출 빈도가 GG=20%(1/4)인 경우 그룹1 내에서 누락된 모든 INS를 80%의 INS로 간주할 수 있습니다. AA 다수는 70% 기준을 충족합니다.

AA의 빈도가 66%(2/3)이고 GG의 빈도가 33%(1/3)인 경우 66%가 70% 임계값을 충족하지 않으므로 AA로 추정하지 않습니다.

INS1    M1  AA
INS2    M1  AA
INS3    M1  AA
INS4    M1  GG
INS5    M1  GG
INS6    M1  GG
INS7    M1  AA
INS8    M1  GG
INS9    M1  GG
INS10   M1  AA
INS11   M1  AA
INS12   M1  GG
INS13   M1  AA
INS14   M1  AA
INS15   M1  AA
**INS16 M1  AA
INS17   M1  AA**
INS1    M2  GG
INS3    M2  TT
INS4    M2  GG
INS5    M2  GG
INS6    M2  TT
INS7    M2  TT
INS8    M2  TT
INS9    M2  TT
INS10   M2  GG
INS11   M2  GG
**INS12 M2  GG
INS13   M2  GG**
INS14   M2  GG
INS15   M2  TT
INS1    M3  AA
INS2    M3  TT
INS3    M3  AA
INS4    M3  TT
INS5    M3  TT
**INS6  M3  TT**
INS7    M3  AA
INS8    M3  TT
INS9    M3  AA
INS10   M3  TT
**INS11 M3  TT
INS12   M3  TT
INS13   M3  TT
INS14   M3  AA**
INS15   M3  TT
**INS16 M3  AA
INS17   M3  AA**

예를 들어 Grp1 M1(INS1,2,3,7,14)에는 빈도가 100%인 5개의 AA 호출이 있습니다. 따라서 M1의 INS16과 INS17(이들은 누락되어 Grp 1에 속하므로)은 호출 빈도가 70%보다 높으므로 AA로 추론할 수 있습니다.

Grp1 M2의 경우 GG(2/4) 및 TT(2/4) 호출이 모두 50%에서 이루어졌으므로 70% 이상의 신뢰도 대치는 불가능했습니다. Grp1 M2의 경우 명확한 다수 호출(70% 이상)이 없기 때문에 INS2, 16 및 17이 여전히 누락되어 있습니다.

awk 또는 Perl에서 이를 달성하는 방법을 안내해 주십시오. 내가 시도한 해결책은 데이터에 그룹을 추가한 다음 임계값을 확인하기 위해 가장 높은 호출의 빈도를 찾는 것이었습니다. 해시 배열을 사용하면 약간 손실됩니다.

awk 'NR==FNR{a[$2]=$1;next} $1 in a { print $0 FS a[$1]}' groups data > tmp
awk '{count[$4 FS $1]++}END{for(j in count) print j":"count[j]}' tmp > tmp2
awk -F, '{if (a[$2]< $3)a[$2]=$3;}END{for(i in a){print i,a[i];}}' tmp2 > tmp3

답변1

이는 한 줄의 코드로 읽기에는 너무 복잡하므로 주석이 달린 gawk스크립트는 다음과 같습니다.

#!/usr/bin/gawk -f
## Save the data in array data: data[M][INS]=dinucleotide
NR==FNR{
    data[$2][$1]=$3;
    next
}
## Save the groups in array groups: groups[GRN][INS]
{
    groups[$1][$2]++
}
## Now that everything is stored in memory, analyze
END{
    ## Get averages: for each group
    for(group in groups){
        ## For each INS in this group
        for(ins in groups[group]){
            ## For each MN in the data file
            for(m in data){
                ## If this INS had a value for this M
                if(data[m][ins]){
                    ## This counts the number of times this dinucleotide
                    ## (data[m][ins]) was found in this M among the INSs 
                    ## of this group.
                    num[group][m][data[m][ins]]++
                    ## My version of gawk doesn't seem to support
                    ## length for multidimensional arrays, so this array
                    ## only exists to count the number of Ms of this group.
                    len[group][m]++;
                }
            }
        }
    }
    ## Foreach group of the groups file
    for(group in num){
        ## For each M of this group 
        for(m in num[group]){
            ## For each INS of this group
            for(ins in groups[group]){
                ## If this INS has a value for this m in
                ## the data file, print it. 
                if(data[m][ins]){
                    printf "%-5s %s %s\n", ins,m,data[m][ins]
                }
                ## If it doesn't, check if there's an nt at
                ## >=70% for this group and print that
                else{
                    for(nt in num[group][m]){
                        if(num[group][m][nt]*100/len[group][m] >= 70){
                            printf "%-5s %s %s\n", ins,m,nt
                        }
                    }
                }
            }
        }
    }
}

파일을 로 저장하고 foo.awk실행 가능하게 만든 다음 chmod +x foo.awk파일에서 실행하십시오.

$ ./foo.awk data groups 
INS1  M1 AA
INS2  M1 AA
INS14 M1 AA
INS3  M1 AA
INS16 M1 AA
INS17 M1 AA
INS7  M1 AA
INS1  M2 GG
INS14 M2 GG
INS3  M2 TT
INS7  M2 TT
INS1  M3 AA
INS2  M3 TT
INS14 M3 AA
INS3  M3 AA
INS16 M3 AA
INS17 M3 AA
INS7  M3 AA
INS9  M1 GG
INS15 M1 AA
INS5  M1 GG
INS6  M1 GG
INS8  M1 GG
INS9  M2 TT
INS15 M2 TT
INS5  M2 GG
INS6  M2 TT
INS8  M2 TT
INS9  M3 AA
INS15 M3 TT
INS5  M3 TT
INS6  M3 TT
INS8  M3 TT
INS10 M1 AA
INS11 M1 AA
INS12 M1 GG
INS13 M1 AA
INS4  M1 GG
INS10 M2 GG
INS11 M2 GG
INS12 M2 GG
INS13 M2 GG
INS4  M2 GG
INS10 M3 TT
INS11 M3 TT
INS12 M3 TT
INS13 M3 TT
INS4  M3 TT

이 방법을 사용하려면 전체 데이터세트(파일 2개)를 메모리에 로드해야 합니다. 하지만 실제로 해결책을 찾지 못했습니다. 사례의 70% 이상이 존재하는지 알기 전에 전체 기사를 읽어야 하기 때문입니다. 내가 생각할 수 있는 유일한 다른 방법은 파일을 여러 번 처리하는 것입니다. 메모리에 로딩하는 데 문제가 있으면 알려주세요. 다른 옵션이 있는지 알아보겠습니다.

관련 정보