複数の合計を計算する必要があります。入力ファイルは次のとおりです。
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
- uniq(日付)で1ドルにつき5ドルの合計
- $4=="TIMES" である各ユニークの合計 $5
- 各ユニークの合計は5ドルです。ここで $4=="ROADS"
- 各ユニークの合計は5ドルです。ここで $4=="ROADS" と $3=="NYC"
- $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
フィールドが表示されるようにゼロを追加します。
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
。これは次のレコードを提供します(一部のレコードには特定のフィールドがないため、3つの別々のコレクションにあります)。
日付 | 国 | 都市 | 頻度 | 投資する | 連帯 |
---|---|---|---|---|---|
20170807 | アメリカ | 女性名 | 1779 | 282075 | 1919150 |
日付 | 国 | 都市 | 頻度 | 投資する | 方法 |
---|---|---|---|---|---|
20170807 | アメリカ | ニューヨーク市 | 41 | 1599年 | 92877 |
20170808 | アメリカ | ペン | 7 | 1 | 133001 |
日付 | 国 | 都市 | 頻度 | 投資する | 連帯 |
---|---|---|---|---|---|
20170808 | アメリカ | ニューヨーク市 | 1592年 | 0 | 361625 |
このput
操作はREV
合計値を合計して各レコードのフィールドを計算します(そのうちの1つは各レコードにありません)。また、後に総収益を計算するために使用される一時値も計算します。その後、次のデータがあります。ROADS
TIMES
ROADS
NYC
put
日付 | 国 | 都市 | 頻度 | 投資する | 連帯 | 回転速度 |
---|---|---|---|---|---|---|
20170807 | アメリカ | 女性名 | 1779 | 282075 | 1919150 | 1919150 |
日付 | 国 | 都市 | 頻度 | 投資する | 方法 | tmp | 回転速度 |
---|---|---|---|---|---|---|---|
20170807 | アメリカ | ニューヨーク市 | 41 | 1599年 | 92877 | 92877 | 92877 |
20170808 | アメリカ | ペン | 7 | 1 | 133001 | 133001 | 133001 |
日付 | 国 | 都市 | 頻度 | 投資する | 連帯 | 回転速度 |
---|---|---|---|---|---|---|
20170808 | アメリカ | ニューヨーク市 | 1592年 | 0 | 361625 | 361625 |
2番目の方法は、合計を計算するreshape
より簡単な方法を提供します。ROADS
NYC
日付 | 国 | 都市 | 頻度 | 投資する | 連帯 | 回転速度 |
---|---|---|---|---|---|---|
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 |
次に、他のレコードのフィールドが欠落しているすべてのレコードにそのフィールドの値としてゼロを追加するように最終的にスパースします。
日付 | 総速度 | TIMES_sum | ROADS_sum | ニューヨーク島 |
---|---|---|---|---|
20170807 | 2012027 | 1919150 | 92877 | 92877 |
20170808 | 494626 | 361625 | 133001 | 0 |