각 행의 값을 두 행의 합으로 나누는 방법(bash를 perl 또는 python으로 변환)

각 행의 값을 두 행의 합으로 나누는 방법(bash를 perl 또는 python으로 변환)

다음과 같은 인구 대립 유전자 수 데이터가 있습니다.

1   0   0   0   0   0   0   0   0   0   1   2   1   0   0   0   0
0   2   0   0   0   0   0   0   0   0   0   4   0   2   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
2   2   0   0   2   1   0   0   0   0   2   4   0   0   0   2   0

열은 모집단이고 행은 SNP입니다. 각 SNP에는 2개의 행이 있습니다(한 행은 각 모집단에서 대립유전자 "1"의 사본 수를 나타내고 한 행은 대립유전자 "2"의 사본 수를 나타냄). 위 예에서 첫 번째와 두 번째 행은 SNP1에 대한 대립 유전자 1과 2의 개수이고, 세 번째와 네 번째 행은 SNP 2에 대한 대립 유전자의 개수이며, 전체 데이터 세트에서도 마찬가지입니다. 모든 모집단에 대한 각 SNP의 모집단 대립유전자 빈도를 계산하고 싶습니다. frequency of allele 1 at SNP1 in population 1 =Number of copies of allele 1 in population/Total number of 1+2 alleles copies in population이는 frequency of allele 2 at SNP1 in population 1 =Number of copies of allele a in population/Total number of 1+2 gene copies in population 각 SNP에 대해 각 대립유전자의 사본 수를 각 모집단에 대한 대립유전자 "1"과 "2"의 수로 나누어야 함을 의미합니다. 숫자. 이것이 내가 원하는 결과입니다:

1   0   0   0   0   0   0   0   0   0   1   0.333333    1   0   0   0   0
0   1   0   0   0   0   0   0   0   0   0   0.666667    0   1   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0           0   0   0   0   0
1   1   0   0   1   1   0   0   0   0   1   1           0   0   0   1   0

R과 bash 솔루션이 있는데 Perl이나 Python에서 이 추정을 수행할 수 있는 방법이 있습니까? 도움을 주시면 감사하겠습니다.

여기에 bash 솔루션이 있습니다

awk '{for(i=1; i<=NF; i++) tally[i]+=$i}; (NR%2)==1{for(i=1; i<=NF; i++) allele1[i]=$i}; (NR%2)==0{for(i=1; i<=NF; i++) allele2[i]=$i; for(i=1; i<=NF; i++) if(tally[i]==0) tally[i]=1; for(i=1; i<=NF; i++) printf allele1[i]/tally[i]"\t"; printf "\n"; for(i=1; i<=NF; i++) printf allele2[i]/tally[i]"\t"; printf "\n"; for(i=1; i<=NF; i++) tally[i]=0}' MyData | sed 's/\t$//g'

하지만 Perl이나 Python으로 변환하는 방법을 모르겠습니다.>

답변1

다음은 귀하가 찾고 있는 것과 매우 유사한 기본 Python 솔루션(멋진 타사 패키지 없음)입니다.

#!/usr/bin/env python2

# snp.py

import sys

# Get the name of the data file from the command-line
data_file = sys.argv[1]

# Read and parse the data from the text file
data = []
with open(data_file, 'r') as file_handle:
    for line in file_handle:
        data.append([float(n) for n in line.split()])

# Get the number of rows and columns
rows = len(data)
cols = len(data[0])

# Iterate over adjacent pairs of rows
for r in range(rows//2):

    # Iterate over columns
    for c in range(cols):

        # Compute the sum of the two matching entries the pair of rows
        t = data[2*r][c] + data[2*r+1][c]
        if t:

            # Divide each entry by the sum of the pair
            data[2*r][c] /= t
            data[2*r+1][c] /= t

# Convert the data array back into formatted strings and print the results
for row in data:
    print(' '.join(['{0: <8}'.format(round(x,6)) for x in row]))

그게 당신에게 효과가 있나요? 형식이 조금 어긋나도 조정하기 쉬울 것입니다.

관련 정보