複数の列の合計

複数の列の合計

複数の合計を計算する必要があります。入力ファイルは次のとおりです。

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フィールドが表示されるようにゼロを追加します。

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つは各レコードにありません)。また、後に総収益を計算するために使用される一時値も計算します。その後、次のデータがあります。ROADSTIMESROADSNYCput

日付 都市 頻度 投資する 連帯 回転速度
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より簡単な方法を提供します。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

次に、他のレコードのフィールドが欠落しているすべてのレコードにそのフィールドの値としてゼロを追加するように最終的にスパースします。

日付 総速度 TIMES_sum ROADS_sum ニューヨーク島
20170807 2012027 1919150 92877 92877
20170808 494626 361625 133001 0

関連情報