chr position value 형식의 파일이 여러 개 있습니다.
"chr", "position", "samp1", "samp2", "samp3", "samp4" 형식으로 변환하고 싶습니다.
예를 들어:
샘플 1:
chr position value
1 3774318 1
1 3774319 1
1 3775200 2
1 3775201 7
1 3775202 70
1 3775203 7
1 3775204 270
1 3775205 3
1 3775206 5
샘플 2:
chr position value
1 3775200 1
1 3775201 1
1 3775202 10
1 3775203 1
1 3775204 12
1 3775205 1
1 3775206 13
1 3775207 1
1 3775208 1
1 3775209 18
(등...)
원하는 출력 파일: / 출력 파일에 임의의 값을 넣었습니다.
chr, position, value-samp1, value-samp2, value-samp3, value-samp4
1 50204 2 17 5 2
1 50205 2 17 5 2
1 50206 2 18 5 2
1 50207 2 19 5 3
1 50208 3 19 5 3
1 50209 3 19 5 3
Join, merge, cat을 시도했지만 예상대로 작동하지 않았습니다. 나는 초보자입니다. 이 작업을 어떻게 수행할 수 있는지 아이디어가 있습니까?
(편집자 주: 귀하가 제공한 실제 데이터를 사용하여 설명한 작업의 예입니다.)
chr position samp1 samp2
1 3774318 1 0
1 3774319 1 0
1 3775200 2 1
1 3775201 0 1
1 3775202 70 10
1 3775203 7 1
1 3775204 270 12
1 3775205 3 1
1 3775206 5 13
1 3775207 7 1
1 3775208 0 1
1 3775209 0 18
답변1
또 다른 awk
방법. NA
입력 파일 중 하나에 특정 변형이 존재하지 않는 경우 이 파일이 인쇄됩니다.
awk '{ if(FNR==1){files[fnum++]=FILENAME}else{var[$1"\t"$2][FILENAME]=$3}} END{ for(v in var){for(file in files){if(! var[v][files[file]]){var[v][files[file]]="NA"}}}printf "chr\tposition "; for(i=1;i<=fnum;i++){printf "value-samp%s\t",i;} print "";for(v in var){ printf "%s ",v; for(file in var[v]){if(file in var[v]); else{var[v][file]="NA";} printf "%s\t", var[v][file] } print ""}}' s1 s2
또는 간결성을 그다지 좋아하지 않는 경우:
awk '{
if(FNR==1){
files[fnum++]=FILENAME
}
else{
var[$1"\t"$2][FILENAME]=$3
}
}
END{
for(v in var){
for(file in files){
if(! var[v][files[file]]){
var[v][files[file]]="NA"
}
}
}
printf "chr\tposition ";
for(i=1;i<=fnum;i++){
printf "value-samp%s\t",i;
}
print "";
for(v in var){
printf "%s ",v;
for(file in var[v]){
if(file in var[v]);
else{
var[v][file]="NA";
}
printf "%s\t", var[v][file];
}
print "";
}
}' s1 s2
s1
및를 s2
사용 중인 실제 파일 이름으로 변경합니다. 샘플 입력에서 위 명령을 실행하면 다음이 반환됩니다.
chr position value-samp1 value-samp2
1 3774318 1 NA
1 3775200 2 1
1 3774319 1 NA
1 3775201 7 1
1 3775202 70 10
1 3775203 7 1
1 3775204 270 12
1 3775205 3 1
1 3775206 5 13
1 3775207 NA 1
1 3775208 NA 1
1 3775209 NA 18
답변2
가져가다이 솔루션베이스와 같은 문제의 경우 원하는 결과를 얻으려면 미세 조정이 필요합니다. 이것은 답변이 아니며 단지 개요일 뿐이며 일부를 사용합니다.의사코드(sic?) 수행해야 할 작업을 간략하게 설명합니다.
리눅스 검토가입하다명령과그 능력성공적인 솔루션에 매우 중요합니다. 각 입력 파일은 결합하기 전에 특정 필드(여기에서는 염색체 번호가 사용됨, 필드 2)를 기준으로 정렬되어야 합니다.
조인은 두 개의 파일만 조인할 수 있기 때문에 조인을 여러 번 진행해야 하므로 일부 프로그래밍 구조와 제어 메커니즘이 필요합니다. 또한 지정한 공백(비어 있는) 값을 0으로 바꿔야 하므로 데이터 자체를 수정해야 합니다.
1) 첫 번째 데이터 파일을 다른 이름으로 복사하십시오.샘플_0
2) 각 라인을 확인하십시오샘플_0 필드 3의 값입니다. null인 경우 0으로 바꿉니다.
3) 초기화 값엑스데이터 파일의 번호와 일치하도록 합니다.
4) 각 데이터 파일을 연속적으로 사용하려면 for/next 루프를 만듭니다. 얼마나 많은 데이터 파일을 가지고 있나요? 글쎄, 실행할 때마다 스크립트를 편집할 필요 없이 이 작업을 수행하려면 for/next 루프를 사용하여 데이터 파일이 부족할 때까지 스크립트를 실행하십시오.
5) for/next 루프에서는 두 가지 작업을 수행합니다.
5A) 다음 파일의 각 줄에서 필드 3의 값을 확인합니다. null인 경우 0으로 바꿉니다.
5B) 실행가입하다페어링할 수 없는 회선을 포함합니다(-ㅏ옵션) 파일의 염색체 번호(필드 2)에샘플_0및 파일샘플_x 자동 서식 기능이 있습니다(옵션 사용).-o 자동) 따라서 두 파일에 데이터가 있는 염색체뿐만 아니라 모든 염색체에 대한 데이터 행을 병합합니다.샘플_0및 파일샘플_x. 파일에 출력 쓰기샘플_0.
6) 다른 데이터 파일이 있는 경우 추가엑스그런 다음 돌아가서 3)을 다시 수행하십시오. 모든 데이터 파일이 연결되면 완료되었으므로 for/next 루프를 종료합니다.
답변3
chr
항상 1이면 무시해도 안전하기 때문에 지금은 무시하고 있습니다. 그렇지 않으면 OP에서 그것이 어떻게 맞는지 설명해야 합니다.
awk 'BEGIN {printf "position " }
FNR>1{
if (FNR==2) {nof+=1; printf ("%s%s " ,"Sam", nof )};
pos[$2]=$2; data[$2, nof]=$3}
END { printf "\n"; for (p in pos) {printf ("%s ", pos[p]);
for (d=1;d<=nof;d++) printf ("%s ", data[p,d]+0); print "\n"}
}' file1 file2 | column -t
산출
position Sam1 Sam2
3774318 1 0
3774319 1 0
3775200 2 1
3775201 7 1
3775202 70 10
3775203 7 1
3775204 270 12
3775205 3 1
3775206 5 13
3775207 0 1
3775208 0 1
3775209 0 18
송곳
첫 번째 열 머리글을 인쇄하여 시작하세요.
awk 'BEGIN {printf "position " }
모든 첫 번째 줄을 헤더로 무시합니다.
FNR>1{
각 파일의 두 번째 줄에서 파일 수를 늘리고 헤더를 인쇄합니다.
if (FNR==2) {nof+=1; printf ("%s%s " ,"Sam", nof )};
헤더 뒤의 각 줄에 대해 위치를 배열에 넣습니다 . 파일(샘플) 번호로 인덱스된 값을 포함하는 pos
다른 배열을 설정합니다.data
sam
pos
pos[$2]=$2; data[$2, nof]=$3}
모든 파일을 읽은 후 newline
헤더에 a를 인쇄한 다음 pos
각 위치를 반복적으로 인쇄합니다.
END { printf "\n"; for (p in pos ) {printf ("%s ", pos[p]);
그런 다음 및 /file 번호 data
로 인덱스된 배열을 반복하여 데이터가 없더라도 무언가가 인쇄되도록 null 값에 0을 추가한 다음 a를 인쇄합니다.p
sam
data
newline
for (d=1;d<=nof;d++) printf ("%s ", data[p,d]+0); print "\n"}
파일을 입력하고 출력을 파이프하여 column
보기 좋게 만드세요.
}' file1 file2 | column -t
추가된 캐릭터다른 인덱스라고 가정
awk 'BEGIN {printf "chr position " }
FNR>1{
if (FNR==2) {nof+=1; printf ("%s%s " ,"Sam", nof )};
chr[$1]=$1; pos[$2]=$2; data[$1, $2, nof]=$3}
END { printf "\n"; for (c in chr) {for (p in pos ) {printf ("%s %s ", chr[c], pos[p]);
for (d=1;d<=nof;d++) printf ("%s ", data[c, p, d]+0); print "\n"}
}}' file1 file2 | column -t
답변4
밀러 사용(https://github.com/johnkerl/miller) 당신은 실행할 수 있습니다
mlr --c2p --ifs ' ' --repifs \
sort -f chr,position,value \
then nest --implode --values --across-records -f value \
then nest --explode --across-fields --values -f value \
then unsparsify then clean-whitespace input0*.csv >output.csv
그리고 얻다
chr position value_1 value_2
1 3774318 1 -
1 3774319 1 -
1 3775200 1 2
1 3775201 1 7
1 3775202 10 70
1 3775203 1 7
1 3775204 12 270
1 3775205 1 3
1 3775206 13 5
1 3775207 1 -
1 3775208 1 -
1 3775209 18 -
노트:
- 명령을 입력 파일의 이름에 맞게 조정해야 합니다. 내 예에서는
input0*.csv
- 진정한 CSV 출력을 원하면
--c2p
으로 변경하세요--csv
.