여러 열 합계

여러 열 합계

여러 합계를 계산해야 합니다. 입력 파일은 다음과 같습니다.

DATE|NATION|CITY|FILES|REVENUE|FREQUENCY|INVESTMENT
20170807|USA|VIRGINIA|TIMES|1919150|1779|282075
20170807|USA|NYC|ROADS|92877|41|1599
20170808|USA|PENS|ROADS|133001|7|1
20170808|USA|NYC|TIMES|361625|1592|0
  1. uniq(날짜)로 1달러당 5달러 합계
  2. $4=="TIMES"인 각 유니크의 합계 $5
  3. 각 유니크의 합계는 $5입니다. 여기서 $4=="ROADS"
  4. 각 유니크의 합계는 $5입니다. 여기서 $4=="ROADS" 및 $3=="NYC"
  5. $1 열 기준으로 정렬

내 예상 결과

DATE|REV|TIMES|ROADS|ROADS&NYC
20170807|2012027|1919150|92877|92877
20170808|494626|361625|133001|0

1개의 열을 기준으로 합산하는 방법만 알고 있습니다.

awk -F"|" '{FS=OFS="|"}{col[$1]+=$5} END {for (i in col) print i, col[i]}'

답변1

awk해결책 은 다음과 같습니다 .

awk -F'[|]' 'NR>1             { I[$1]+=$5 }
    ($4=="TIMES")             { T[$1]+=$5 }
    ($4=="ROADS")             { R[$1]+=$5 }
    ($4=="ROADS" && $3=="NYC"){ RN[$1]+=$5 }
END{ print "DATE|REV|TIMES|ROADS|ROADS&NYC"
     for (x in I) printf"%d|%d|%d|%d|%d\n", x, I[x], T[x], R[x], RN[x]
}' infile.txt

답변2

복잡한멍하니목표 달성을 위한 솔루션:

awk 'BEGIN{ FS=OFS="|" }NR==1{ next }{ sum[$1]+=$5 }
     $4=="TIMES"{ d[$1]["t"]+=$5 }
     $4=="ROADS"{ d[$1]["r"]+=$5 }$3=="NYC" && $4=="ROADS"{ d[$1]["r&n"]+=$5 }
     END{ print "DATE|REV|TIMES|ROADS|ROADS&NYC"; 
     for(i in d) print i, sum[i], int(d[i]["t"]), int(d[i]["r"]), int(d[i]["r&n"]) }' file

산출:

DATE|REV|TIMES|ROADS|ROADS&NYC
20170807|2012027|1919150|92877|92877
20170808|494626|361625|133001|0

답변3

여러 배열이 필요하지 않습니다. 필드에 인덱스를 쓰고 모든 것을 합산한 다음 원하는 합계 인덱스만 반환하고 NULL필드가 표시되도록 0을 추가하면 됩니다.

awk 'BEGIN{FS=OFS="|"; print "DATE|REV|TIMES|ROADS|ROADS&NYC"}
    NR>1{rev[$1]+=$5; sum[$1$4]+=$5; sum[$1$4$3]+=$5}
    END{for (dt in rev) print dt, rev[dt], sum[dt"TIMES"]+0, sum[dt"ROADS"]+0, sum[dt"ROADSNYC"]+0}' file

가독성도 더 좋고...

답변4

사용밀러( mlr):

mlr --csv --fs pipe \
    reshape -s FILES,REVENUE then \
    put '$tmp=$ROADS; $REV=$ROADS+$TIMES' then \
    reshape -s CITY,tmp then \
    stats1 -a sum -g DATE -f REV,TIMES,ROADS,NYC then \
    unsparsify --fill-with 0 file.csv

질문의 데이터가 주어지면 다음이 생성됩니다.

DATE|REV_sum|TIMES_sum|ROADS_sum|NYC_sum
20170807|2012027|1919150|92877|92877
20170808|494626|361625|133001|0

첫 번째 작업( reshape작업)은 필드에서 값을 가져오고 의 FILES값을 사용하여 해당 필드에서 새 필드를 생성합니다 REVENUE. 이는 다음과 같은 레코드를 제공합니다(일부 레코드에는 특정 필드가 누락되어 있으므로 세 개의 별도 컬렉션에 있음).

날짜 국가 도시 빈도 투자하다 연대
20170807 미국 여자 이름 1779 화 282075 1919150
날짜 국가 도시 빈도 투자하다 방법
20170807 미국 뉴욕시 41 1599년 92877
20170808 미국 7 1 133001
날짜 국가 도시 빈도 투자하다 연대
20170808 미국 뉴욕시 1592 화 0 361625

put작업은 REV합계 값을 합산하여 각 레코드의 필드를 계산합니다(이 중 하나는 각 레코드에서 누락됩니다). 또한 나중에 총 수익을 계산하는 데 사용될 임시 값도 계산합니다. 그 후에는 다음과 같은 데이터가 있습니다.ROADSTIMESROADSNYCput

날짜 국가 도시 빈도 투자하다 연대 회전 속도
20170807 미국 여자 이름 1779 화 282075 1919150 1919150
날짜 국가 도시 빈도 투자하다 방법 tmp 회전 속도
20170807 미국 뉴욕시 41 1599년 92877 92877 92877
20170808 미국 7 1 133001 133001 133001
날짜 국가 도시 빈도 투자하다 연대 회전 속도
20170808 미국 뉴욕시 1592 화 0 361625 361625

두 번째 방법은 합계를 계산하는 reshape더 쉬운 방법을 제공합니다 .ROADSNYC

날짜 국가 도시 빈도 투자하다 연대 회전 속도
20170807 미국 여자 이름 1779 화 282075 1919150 1919150
20170808 미국 뉴욕시 1592 화 0 361625 361625
날짜 국가 빈도 투자하다 방법 회전 속도 뉴욕시
20170807 미국 41 1599년 92877 92877 92877
날짜 국가 빈도 투자하다 방법 회전 속도
20170808 미국 7 1 133001 133001 133001

그런 다음 이 stats1명령을 사용하여 다음과 같은 방식으로 그룹화된 필수 필드의 합계를 계산합니다 DATE.

날짜 총 속도 TIMES_sum ROADS_sum 뉴욕섬
20170807 2012027 1919150 92877 92877
날짜 총 속도 TIMES_sum ROADS_sum
20170808 494626 361625 133001

그런 다음 다른 레코드에 있는 필드가 누락된 모든 레코드에 해당 필드의 값으로 0이 추가되도록 최종적으로 희소화합니다.

날짜 총 속도 TIMES_sum ROADS_sum 뉴욕섬
20170807 2012027 1919150 92877 92877
20170808 494626 361625 133001 0

관련 정보