다음과 같은 데이터 목록이 있습니다 data.txt
.
Sample A
12
0
29
238
0
4
기본적으로 생물학적 샘플(단일 열)과 특정 유전자의 발현(320개 이상의 행)입니다. 각 행의 각 값을 서로 곱하여 output.txt
다음과 같은 결과를 얻고 싶습니다 .
- - - - - -
0 - - - - -
348 0 - - - -
2856 0 82824 - - -
0 0 0 0 - -
48 0 116 952 0 -
저는 현재 Excel에서 수동으로 이 작업을 수행하고 있는데 이는 고통스럽습니다. (저는 생물학자이고 UNIX나 코딩 전반에 능숙하지 않습니다.) awk
(또는 다른 명령을) 사용하여 이를 수행할 수 있는 방법이 있습니까 ?
또한 실제로 약 300개의 샘플(즉, 300개의 개별 파일)이 있는데 data.txt
, 300개의 샘플(즉, 300개 열, 320개 행, 각 행과 열의 값)이 모두 포함된 파일에 대해 스크립트를 실행할 수 있다면 더 좋은 점은 data.txt
각 output.txt
샘플(열)에 대해 300개의 개별 파일을 얻는 것입니다.
답변1
실제로 그렇게 어렵지는 않습니다 awk
. 예를 들어 전체 파일을 (1d) 배열에 넣고 단일 데이터 파일에 대해 이중 루프를 수행할 수 있습니다.
awk '
NR > 1 {
x[NR-1] = $1;
}
END {
for (i=1; ;i++) {
if (!(i in x))
break;
for (j=1; ;j++) {
if (!(j in x))
break;
if (j < i)
printf "%-6d", x[j]*x[i];
else
printf "%-6s", "-";
}
printf "\n";
}
}
' data.txt
위쪽 삼각형을 대시로 채우려고 하지 않으면 즉시 선을 사용하여 작업하는 것이 더 쉽습니다.즉, 전체 파일을 로드하지 않습니다.
awk '
NR > 1 {
x[NR-1] = $1;
for (j=1;j<NR-1;j++)
printf "%-6d", $1*x[j];
printf "%-6s\n", "-";
}
' data.txt
-
0 -
348 0 -
2856 0 6902 -
0 0 0 0 -
48 0 116 952 0 -
데이터 세트가 큰 경우 이 접근 방식은 메모리 사용량 측면에서 이점을 제공할 수 있습니다.
여러 파일 인수를 처리하려면 약간의 조정이 필요합니다. GNU awk가 있으면 다음과 같은 규칙을 사용할 수 BEGINFILE
있습니다 ENDFILE
.
gawk '
BEGINFILE {
delete x;
}
FNR > 1 {
x[FNR-1] = $1;
next;
}
ENDFILE {
n = length(x);
for (i=1;i<=n;i++) {
for (j=1;j<=n;j++) {
if (j < i)
printf "%-6d", x[j]*x[i];
else
printf "%-6s", "-";
}
printf "\n";
}
printf "\n";
}
' data1.txt data2.txt
그렇지 않은 경우 gawk
FNR이 1로 롤백되는 시점을 확인하여 BEGINFILE/ENDFILE을 시뮬레이션할 수 있습니다.
그러나 데이터 세트가 크다면 GNU와 같은 행렬 연산용으로 구축된 것을 사용하는 것이 좋습니다 octave
(기본적으로 제품의 아래쪽 삼각형을 원하는 것 같죠?)
대화형 Octave 인터프리터 또는 다음과 같이 "배치" 모드에서 이 작업을 수행할 수 있습니다.
$ octave -q << 'EOF'
> x = textread('data.txt', '%f', 'headerlines', 1);
> M = tril(x * x', -1);
> disp(M);
> EOF
0 0 0 0 0 0
0 0 0 0 0 0
348 0 0 0 0 0
2856 0 6902 0 0 0
0 0 0 0 0 0
48 0 116 952 0 0
특정 출력 요구 사항에 따라 간단한 save
또는 기능을 사용하여 파일 dlmwrite
에 쓸 수 있거나 매우 세밀한 출력 형식 제어를 원할 경우 사용할 수 있습니다. 위의 삼각형 0을 대시로 바꾸려면 셀 배열을 살펴보는 것이 좋습니다.M
fprintf
답변2
이 특정 작업을 수행할 수 있는 단일 프로그램이 없으므로 일부(초급 수준) 코딩이 필요합니다.
이 작업을 위해 awk 스크립트를 작성하는 것이 가능하더라도 awk는 프로그래밍 언어로 특별히 적합하지 않습니다. Perl이 해당 작업에 더 나은 언어일 수 있지만 범용 프로그래밍이나 스크립팅 언어라면 모두 가능합니다. 당신은 코딩을 좋아하지 않기 때문에 당신을 위해 프로그램을 작성하고 언어 선택을 그들에게 맡겨줄 누군가를 찾아야 할 것입니다(그들의 제안이 너무 많은 설정 노력을 요구하지 않는 한).
내가 아는 한 SE의 답변에는 특정 작업에 대한 완전한 코드가 포함되어서는 안 되지만, 누군가 그러한 코드를 게시하면 귀하는 그 사람의 답변을 선호할 수도 있습니다. :-)