使用 DataFramesMeta 包中的 @linq 在 Julia 中整理数据

Tidying data in Julia using @linq from the DataFramesMeta package

我想使用 DataFramesMeta 包中的 @linq 宏整理我的数据。

结果应该与下面的代码给出相同的结果:

using CSV, DataFrames, Dates

url = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv"
download(url, joinpath(pwd(), "confirmed.csv"))

df = CSV.read(joinpath(pwd(), "confirmed.csv"))
rename!(df, 1 => :Province, 2 => :Country)
select!(df, Not([:Province, :Lat, :Long]))
df = combine(groupby(df, :Country), names(df)[2:end] .=> sum .=> names(df)[2:end])
df = stack(df, Not(:Country), :Country, variable_name=:Date, value_name=:Confirmed)
df[:Date] = parse.(Dates.Date, String.(df[:Date]), Dates.DateFormat("m/d/Y")) .+ Dates.Year(2000)

println(last(df, 10))

结果:

10×3 DataFrame
│ Row │ Country            │ Date       │ Confirmed │
│     │ String             │ Date       │ Int64     │
├─────┼────────────────────┼────────────┼───────────┤
│ 1   │ United Kingdom     │ 2020-10-29 │ 968456    │
│ 2   │ Uruguay            │ 2020-10-29 │ 3044      │
│ 3   │ Uzbekistan         │ 2020-10-29 │ 66392     │
│ 4   │ Venezuela          │ 2020-10-29 │ 91280     │
│ 5   │ Vietnam            │ 2020-10-29 │ 1177      │
│ 6   │ West Bank and Gaza │ 2020-10-29 │ 52571     │
│ 7   │ Western Sahara     │ 2020-10-29 │ 10        │
│ 8   │ Yemen              │ 2020-10-29 │ 2062      │
│ 9   │ Zambia             │ 2020-10-29 │ 16325     │
│ 10  │ Zimbabwe           │ 2020-10-29 │ 8349      │

到目前为止,我使用 @linq 的代码是:

using DataFramesMeta

df = @linq CSV.read(joinpath(pwd(), "data", "time_series_covid19_confirmed_global.csv")) |>
    rename(1 => :Province, 2 => :Country) |>
    select(vcat(names(df)[2], names(df)[5:end]))

然而,我卡在了分组和汇总数据的点上。 对如何完成此 linq 查询有何建议?

DataFramesMeta.jl 现在正在进行重大重构。也许@pdeffebach 可以建议使用 master 上的功能来惯用它。

以下是我将如何使用原始 DataFrames.jl 和 Pipe.jl 重写您的代码:

df = CSV.read(joinpath(pwd(), "confirmed.csv"), DataFrame)

@pipe df |>
      rename(_, 1 => :Province, 2 => :Country) |> # avoid ! to make sure we do not mutate the source
      select!(_, Not([:Province, :Lat, :Long])) |>
      groupby(_, :Country) |>
      combine(_, valuecols(_) .=> sum .=> valuecols(_)) |>
      stack(_, Not(:Country), :Country, variable_name=:Date, value_name=:Confirmed) |>
      transform!(_, :Date => ByRow(x -> parse(Date, string(x), DateFormat("m/d/Y")) + Year(2000)) => :Date) |>
      last(_, 10)

请注意,在您的代码中:

  • CSV.read(joinpath(pwd(), "confirmed.csv"))(在我的代码中添加 DataFrame 作为第二个参数)
  • df[:Date] 应为 df.Datedf."Date"(第二种样式是为了防止名称包含空格)

已弃用。