다른 필드의 변수를 기반으로 한 필드의 평균을 구합니다.

다른 필드의 변수를 기반으로 한 필드의 평균을 구합니다.

다른 필드의 변수를 기반으로 한 필드의 평균을 구하는 방법이 있습니까? 예를 들어 다음 입력의 경우

a x 3
b y 4
a y 2
b x 5
b x 20

이 출력을 원합니다

a 2.5
b 9.67

열의 값 평균을 구하는 awk 스크립트를 찾았습니다.

awk '{ total += $3; count++ } END { print total/count }' file.txt

하지만 첫 번째 열에 있는 각 변수의 평균을 얻으려면 거기에 for 루프를 어떻게 추가해야 합니까?

파일은 탭으로 구분됩니다.

감사해요

답변1

당신은 이것에서 그리 멀지 않습니다. 다음으로 색인화된 배열을 사용해 보세요 $1.

awk '{ total[$1] += $3; count[$1]++ } END {for (t in total) print t, total[t]/count[t]}' file
a 2.5
b 9.66667

또는 질문과 같이 소수점 이하 두 자리까지 원하는 경우:

$ awk '{ total[$1] += $3; count[$1]++ } END {for (t in total) printf "%s %.2f\n", t, total[t]/count[t]}' file
a 2.50
b 9.67

답변2

GNU 사용 datamash:

$ datamash -R2 -W -s -g 1 mean 3 <file
a       2.50
b       9.67

$ datamash -W -s -g 1 mean 3 <file
a       2.5
b       9.6666666666667
  • -R2소수점 이하 두 자리까지 반올림
  • -W공백 및/또는 탭을 필드 구분 기호로 사용
  • -s그룹화하기 전에 정렬
  • -g 1첫 번째 필드의 그룹
  • mean 3값의 평균, 세 번째 필드

출력에서 탭 문자를 공백 문자로 바꾸려면 -W탭 문자가 구분 기호로 추가하는 내용을 제거하면 됩니다.--output-delimiter=' '

답변3

밀러이와 같은 작업에도 편리합니다.

$ mlr --nidx stats1 -a mean -f 3 -g 1 file.txt
a 2.500000
b 9.666667

또는 (동사를 포함한 최신 버전 format-values)

$ mlr --nidx stats1 -a mean -f 3 -g 1 then format-values -f '%.2f' file.txt
a 2.50
b 9.67

답변4

   #!/bin/bash
counta=`awk '$1 ~ /^a$/{print NR}' filename| awk 'END{print NR}'`
countb=`awk '$1 ~ /^b$/{print NR}' filename| awk 'END{print NR}'`

awk -v counta="$counta" '{if ($1 == "a"){sum=sum+$NF}}END{print "a" " " sum/counta}'  filename

awk -v countb="$countb" '{if ($1 == "b"){sum=sum+$NF}}END{print "b" " " sum/countb}'  filename

산출

a 2.5
b 9.66667

관련 정보