In R, one would use tidyverse to, for example, aggregate daily deaths of COVID-19 by day and by country [0].
How would one do it in Julia? Is there a package that is similar to Rโs tidyverse? Or does one write a couple of loops self?
Thanks!
In R, one would use tidyverse to, for example, aggregate daily deaths of COVID-19 by day and by country [0].
How would one do it in Julia? Is there a package that is similar to Rโs tidyverse? Or does one write a couple of loops self?
Thanks!
DataFrames.jl
The Queryverse package supports piping data around through transformations, grouping, etc.
Though for this kind of thing I often like to push the data to SQLite and run a SQL query. I find SQL actually quite expressive.
julia> using Dates, DataFrames
julia> data = DataFrame(day = [Date(2020,4,1), Date(2020,4,2), Date(2020,4,1), Date(2020,4,2)], country = [:a, :a, :b, :b], deaths = [10, 20, 30, 40])
4ร3 DataFrame
โ Row โ day โ country โ deaths โ
โ โ Date โ Symbol โ Int64 โ
โโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโผโโโโโโโโโค
โ 1 โ 2020-04-01 โ a โ 10 โ
โ 2 โ 2020-04-02 โ a โ 20 โ
โ 3 โ 2020-04-01 โ b โ 30 โ
โ 4 โ 2020-04-02 โ b โ 40 โ
julia> transform(groupby(data, :country), :deaths => cumsum => :deaths)
4ร3 DataFrame
โ Row โ country โ day โ deaths โ
โ โ Symbol โ Date โ Int64 โ
โโโโโโโผโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโค
โ 1 โ a โ 2020-04-01 โ 10 โ
โ 2 โ a โ 2020-04-02 โ 30 โ
โ 3 โ b โ 2020-04-01 โ 30 โ
โ 4 โ b โ 2020-04-02 โ 70 โ
The analogue of tidyverse would be queryverse. See e.g.,
DataFrames + a few other helper packages will have all you need for this.
The anonymoys function syntax is probably the hardest part to understand coming from R. But hopefully we can make easier syntax soon.
I downloaded the excel file you posted and turned it into a CSV just by opening it in excel and saving it as a .csv
file.
using CSV, DataFrames, Pipe, Statistics
df = CSV.File("COVID-19-geographic-disbtribution-worldwide-2020-06-24.csv") |> DataFrame
df_country_month = @pipe df |>
groupby(_, ["countriesAndTerritories", "month", "year"]) |>
combine(_,
"cases" => (t -> mean(skipmissing(t))) => "cases",
"deaths" => (t -> mean(skipmissing(t))) => "deaths")
Arguable, but I think the nicer syntax already exists through function composition:
:cases => mean โ skipmissing => :cases
Thank you!
How do u type that symbol in between mean and missing?
\circ
How do you type the \circ with reasonable ease if youโre writing code in emacs?
You just need to type \circ[TAB]
(assuming emacs is in julia-mode
). The first time you do that in a session, it may take time to display the character, but it does work.
Thank you.
Do you then store data in an SQL database?
Thank you! Which package contains the transform() function?
I got the following error:
julia> @time transform(groupby(data, :country), :deaths => cumsum => :deaths)
ERROR: UndefVarError: transform not defined
Stacktrace:
[1] top-level scope at ./util.jl:175
Ah sorry, assumed that as a given as my post was meant to amend Peterโs - itโs in DataFrames, but only as of version 0.21, so make sure youโve got the latest!
You could, but CSV loading and writing is pretty fast. If your data fits in memory, and youโre using DataFrames to manipulate it, Iโd just stick with CSV
Thank you, @Rudy79.
My Gentoo Linux amd64 cannot install ParquetFiles.jl, which is required by Queryverse. I opened an issue on Github: https://github.com/queryverse/ParquetFiles.jl/issues/33
Otherwise, yeah, Queryverse looks great!
DataFrames has the transform function.
Please see my code example above for a MWE with your data.
Thank you!
I think I need to update my DataFrames.jl. However, I do not know what is preventing it from updated to the latest version. My hunch is that a package that depends on an older version of DataFrames.jl prevents DataFrames.jl from being updated.
julia> @time using CSV, DataFrames, Pipe, Statistics
0.001125 seconds (1.48 k allocations: 78.219 KiB)
julia> @time df = CSV.File("/home/c/Downloads/COVID-19-geographic-disbtribution-worldwide-2020-06-24.csv") |> DataFrame
0.145597 seconds (27.87 k allocations: 6.840 MiB, 56.48% gc time)
25517ร11 DataFrame. Omitted printing of 5 columns
โ Row โ dateRep โ day โ month โ year โ cases โ deaths โ
โ โ String โ Int64 โ Int64 โ Int64 โ Int64 โ Int64 โ
โโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโผโโโโโโโโผโโโโโโโโผโโโโโโโโผโโโโโโโโโค
โ 1 โ 6/24/2020 โ 24 โ 6 โ 2020 โ 338 โ 20 โ
โ 2 โ 6/23/2020 โ 23 โ 6 โ 2020 โ 310 โ 17 โ
โ 3 โ 6/22/2020 โ 22 โ 6 โ 2020 โ 409 โ 12 โ
โ 4 โ 6/21/2020 โ 21 โ 6 โ 2020 โ 546 โ 21 โ
โ 5 โ 6/20/2020 โ 20 โ 6 โ 2020 โ 346 โ 2 โ
โ 6 โ 6/19/2020 โ 19 โ 6 โ 2020 โ 658 โ 42 โ
โ 7 โ 6/18/2020 โ 18 โ 6 โ 2020 โ 564 โ 13 โ
โ 8 โ 6/17/2020 โ 17 โ 6 โ 2020 โ 783 โ 13 โ
โ 9 โ 6/16/2020 โ 16 โ 6 โ 2020 โ 761 โ 7 โ
โ 10 โ 6/15/2020 โ 15 โ 6 โ 2020 โ 664 โ 20 โ
โ 11 โ 6/14/2020 โ 14 โ 6 โ 2020 โ 556 โ 5 โ
โ 12 โ 6/13/2020 โ 13 โ 6 โ 2020 โ 656 โ 20 โ
โ 13 โ 6/12/2020 โ 12 โ 6 โ 2020 โ 747 โ 21 โ
โ 14 โ 6/11/2020 โ 11 โ 6 โ 2020 โ 684 โ 21 โ
โ 15 โ 6/10/2020 โ 10 โ 6 โ 2020 โ 542 โ 15 โ
โ 16 โ 6/9/2020 โ 9 โ 6 โ 2020 โ 575 โ 12 โ
โ 17 โ 6/8/2020 โ 8 โ 6 โ 2020 โ 791 โ 30 โ
โฎ
โ 25500 โ 4/7/2020 โ 7 โ 4 โ 2020 โ 0 โ 0 โ
โ 25501 โ 4/6/2020 โ 6 โ 4 โ 2020 โ 0 โ 0 โ
โ 25502 โ 4/5/2020 โ 5 โ 4 โ 2020 โ 0 โ 0 โ
โ 25503 โ 4/4/2020 โ 4 โ 4 โ 2020 โ 1 โ 0 โ
โ 25504 โ 4/3/2020 โ 3 โ 4 โ 2020 โ 0 โ 0 โ
โ 25505 โ 4/2/2020 โ 2 โ 4 โ 2020 โ 0 โ 0 โ
โ 25506 โ 4/1/2020 โ 1 โ 4 โ 2020 โ 1 โ 0 โ
โ 25507 โ 3/31/2020 โ 31 โ 3 โ 2020 โ 0 โ 0 โ
โ 25508 โ 3/30/2020 โ 30 โ 3 โ 2020 โ 0 โ 0 โ
โ 25509 โ 3/29/2020 โ 29 โ 3 โ 2020 โ 2 โ 0 โ
โ 25510 โ 3/28/2020 โ 28 โ 3 โ 2020 โ 2 โ 0 โ
โ 25511 โ 3/27/2020 โ 27 โ 3 โ 2020 โ 0 โ 0 โ
โ 25512 โ 3/26/2020 โ 26 โ 3 โ 2020 โ 1 โ 0 โ
โ 25513 โ 3/25/2020 โ 25 โ 3 โ 2020 โ 0 โ 0 โ
โ 25514 โ 3/24/2020 โ 24 โ 3 โ 2020 โ 0 โ 1 โ
โ 25515 โ 3/23/2020 โ 23 โ 3 โ 2020 โ 0 โ 0 โ
โ 25516 โ 3/22/2020 โ 22 โ 3 โ 2020 โ 1 โ 0 โ
โ 25517 โ 3/21/2020 โ 21 โ 3 โ 2020 โ 1 โ 0 โ
julia> @time df_country_month = @pipe df |>
groupby(_, ["countriesAndTerritories", "month", "year"]) |>
combine(_,
"cases" => (t -> mean(skipmissing(t))) => "cases",
"deaths" => (t -> mean(skipmissing(t))) => "deaths")
ERROR: ArgumentError: idxs[1] has type String; Only Integer or Symbol values allowed when indexing by vector
Stacktrace:
[1] getindex at /home/c/.julia/packages/DataFrames/S3ZFo/src/other/index.jl:222 [inlined]
[2] groupby(::DataFrame, ::Array{String,1}; sort::Bool, skipmissing::Bool) at /home/c/.julia/packages/DataFrames/S3ZFo/src/groupeddataframe/grouping.jl:168
[3] groupby(::DataFrame, ::Array{String,1}) at /home/c/.julia/packages/DataFrames/S3ZFo/src/groupeddataframe/grouping.jl:167
[4] top-level scope at util.jl:175
julia> @time Pkg.add("DataFrames")
Resolving package versions...
Updating `~/.julia/environments/v1.4/Project.toml`
[no changes]
Updating `~/.julia/environments/v1.4/Manifest.toml`
[no changes]
3.576830 seconds (2.55 M allocations: 168.654 MiB, 5.42% gc time)
julia> @time using DataFrames
0.000309 seconds (236 allocations: 12.641 KiB)
julia> @time Pkg.status()
Status `~/.julia/environments/v1.4/Project.toml`
[c9ce4bd3] ArchGDAL v0.3.2
[6e4b80f9] BenchmarkTools v0.5.0
[336ed68f] CSV v0.6.1
[5ae59095] Colors v0.12.1
[a93c6f00] DataFrames v0.20.2
[add2ef01] GDAL v1.1.2
[28b8d3ca] GR v0.49.1
[dcc97b0b] GeoStats v0.11.6
[7073ff75] IJulia v1.21.2
[86fae568] ImageView v0.10.8
[98b081ad] Literate v2.5.0
[961ee093] ModelingToolkit v3.6.4
[9b87118b] PackageCompiler v1.1.1
[b98c9c47] Pipe v1.2.0
[91a5bcdd] Plots v1.3.3
[612083be] Queryverse v0.5.0
[295af30f] Revise v2.6.7
[123dc426] SymEngine v0.8.2
[24249f21] SymPy v1.0.20
[44d3d7a6] Weave v0.10.2
[fdbf4ff8] XLSX v0.7.0
0.200055 seconds (137.18 k allocations: 8.654 MiB)
julia> @time versioninfo()
Julia Version 1.4.2
Commit 44fa15b150* (2020-05-23 18:35 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Pentium(R) 4 CPU 3.00GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-9.0.1 (ORCJIT, nocona)
4.183625 seconds (2.06 M allocations: 93.365 MiB, 3.33% gc time)
Oh. It turns out that I had a dirty registry. I removed ~/.julia/registries/General
and was able to update packages normally. Iโm going to try @pdeffebachโs MWE again now.