.txt 파일에 있는 특정 열의 중앙값을 계산하고 해당 값을 출력하고 출력 값이 정상인지 확인하고 싶습니다. 초기 단계를 수행하고 중앙값을 출력할 수 있지만 출력값이 허용 범위 내에 있는지 여부를 알 수 없습니다.
다음 코드가 포함된 구문 오류 메시지가 나타납니다.
sort -nk9 filename | awk '{a[i++]=$9;} END {x=int((i+1)/2); y=((a[x-1] + a[x])/2); z=(a[x-1]);
if ((y >= 0.5 && y <= 2) || (z >= 0.5 && z <=2));
{if (x < (i+1)/2)
print "Median OR =", y "ALL OK";
else print "Median OR =", z "ALL OK"};
else print "ERROR - OR outside range 0.5 - 2.0"}'
답변1
내 생각엔 이게 네가 원하는 거야
awk '{sum+=$9;a[x++]=$9;b[$9]++}b[$9]>Mode{Mode=$9}END{print "Mean: " sum/x "\nMedian: "a[int((x-1)/2)]"\nMode: " Mode}' file
비교적 깔끔하게 정리되어 있어요
awk '
{
sum+=$9
a[x++]=$9
b[$9]++
}
b[$9]>Mode{Mode=$9}
END{
print "Mean: " sum/x
print "Median: "a[int((x-1)/2)]
print "Mode: " Mode
}' file
또한 비교에 몇 가지 논리를 추가하고 싶지만 변수가 x, y, z라고 불리며 올바른 방정식이 있을 수도 있고 없을 수도 있기 때문에 무엇을 비교하고 있는지 실제로 알 수 없습니다.
답변2
user78605
쿼리에서 중앙값을 찾는 방법을 안내해 주는 코드를 제공해 주셔서 감사합니다 . 그러나 위 코드는 중앙값을 올바르게 계산하는 데 필요한 특정 조건을 무시합니다.
질문:
- 빈 후행 행이 파일에 존재하는 경우 이를 계산하면 데이터 크기, 즉 평균, 중앙값, 모드 및 기타 통계에 영향을 미치기 때문에 계산해서는 안 됩니다. 숫자 값이 없는 행(id est: , ,
"abc"
등"28b"
) 에 대해서도 동일한 작업을 수행해야 합니다 ."h2f"
""
- 중앙값은 원래 데이터 세트의 중간 값이 아니라 정렬된 데이터 세트의 중간 값입니다. 즉, 중앙값을 찾으려면 먼저 데이터를 정렬해야 합니다.
- 정렬된 데이터 세트의 값 개수가 짝수인 경우에는 가운데 두 값의 평균을 취해야 합니다.
- 모드는 주파수가 가장 높은 값입니다. 데이터 세트에는 둘 이상의 모드가 있을 수 있으며, 이 경우 둘 이상의 값이 모드로 나열되어야 합니다.
위의 조건을 고려한 코드 확장은 다음과 같습니다.
awk -F',' '
{col=$1}{if((col ~ /^-?[0-9]*([.][0-9]+)?$/) && ($0!=""))
{
sum+=col;
a[x++]=col;
b[col]++
if(b[col]>hf){hf=b[col]}
}
}
END{n = asort(a);idx=int((x+1)/2)
print "Mean: " sum/x
print "Median: " ((idx==(x+1)/2) ? a[idx] : (a[idx]+a[idx+1])/2)
for (i in b){if(b[i]==hf){(k=="") ? (k=i):(k=k FS i)}{FS=","}}
print "Mode: " k
}' file
설명하다:
문제 #1에 대한 해결책:
col=$1
#변수에 저장하면 열을 변경하기가 더 쉽습니다.
(col ~ /^-?[0-9]*([.][0-9]+)?$/)
#Strings에는 숫자, 마침표(소수 구분 기호) 또는 대시(빼기 기호)만 포함될 수 있습니다. [과학적 표기법만 무시합니다. ]
($0!="")
#전체 줄을 비워 둘 수 없습니다.
기준을 충족하는 행에 대해 다음 루프 작업을 수행합니다.
sum+=col
# (약어sum=sum+col
.) 모든 값의 합계입니다.
a[x++]=col
#각 값은 배열에 저장됩니다.
b[col]++
#의 값은col
배열의 대리 키로 처리됩니다b
. 따라서b
에 고유한 값이 있는 만큼 에 많은 요소가 있습니다col
. 이 반복자는 빈도 수의 배열을 생성합니다. (약어b[col]=b[col]+1
.)
if(b[col]>hf){hf=b[col]}
#hf
"가장 높은 주파수"를 뜻합니다. 모든 주파수를 반복하고hf
더 높은 주파수가 발견된 경우에만 업데이트합니다.hf
처음에는 ""(아무것도 없음)입니다.
문제 #2에 대한 해결 방법:
루프 작업이 완료된 후:
배열에 저장된 값을 정렬합니다.
배열의 원래 인덱스 범위가n = asort(a)
a
"0"에서 "x-1"까지라는 점은 주목할 가치가 있습니다. 정렬 외에도 새 인덱스 범위는 "1"부터 "x"까지입니다. 그렇기 때문에 중앙값 또는 중앙값의 평균을 계산할 두 숫자 중 더 작은 숫자를 보유하는 인덱스로int((x+1)/2)
대신 사용하고 있습니다.int((x-1)/2)
문제 #3에 대한 해결책:
((idx == (x+1)/2) ? a[idx] : (a[idx]+a[idx+1])/2)
이것은 if-else 구조에 대한 약칭 표기법입니다. 동일
하면 값의 개수는 홀수이고 중앙값은 입니다 . 그렇지 않은 경우 가장 가까운 정수로 반내림되어 값의 개수가 짝수임을 나타냅니다. 이 경우 합계의 평균이 중앙값이 됩니다.int((x+1)/2)
(x+1)/2
a[idx]
int()
(x+1)/2
a[idx]
a[idx]+1
문제 #4에 대한 해결책:
for (i in b) {if(b[i]==hf){(k=="") ? (k=i):(k=k FS i)}{FS=","}}
hf
는 데이터 세트에서 가장 높은 빈도를 나타내는 값이므로 b의 값이 와 같으면 대리hf
키는 모드이거나 모드 중 적어도 하나입니다.
이 코드는i
조건과 일치하는 모든 대리 키를 연결하고 이를k
"Mode"라는 줄에 인쇄할 수 있는 변수에 저장합니다.
추가 조정:
-F
파일에서 열 구분 기호로 사용되는 문자를 기준으로 조정해야 합니다.
NR > 1
파일의 첫 번째 줄 에 헤더가 있으면 {col=$1}
.
FS
두 변수를 결합하는 데 사용됩니다. FS
Use는 구분 기호를 사용하지 않기로 선택한 경우에 특히 유용합니다. 그건, FS=""
.
데이터
스크립트를 작성하기 위해 실험에서 다음 데이터가 사용되었습니다.
10
20
10
20.5
50
30
40
50
10
30
20.5
-h
h
4.35
-537
0
-0
30
d
.
결과:
Mean: -13.2281
Median: 20.25
Mode: 10,30