From 155266a4b26e7b3413ec45a7f17ffbf5fce102d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Sat, 5 Nov 2022 01:10:32 +0100 Subject: [PATCH 1/4] add default style to metadata! and colmetadata! --- Project.toml | 2 +- src/other/metadata.jl | 36 ++++++++++++++++++++---------------- test/metadata.jl | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/Project.toml b/Project.toml index dae0749812..153d1f19c2 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DataFrames" uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.4.2" +version = "1.4.3" [deps] Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" diff --git a/src/other/metadata.jl b/src/other/metadata.jl index a1cd49f511..60a283d5a0 100644 --- a/src/other/metadata.jl +++ b/src/other/metadata.jl @@ -168,13 +168,13 @@ function metadatakeys(x::Union{DataFrameRow, SubDataFrame}) end """ - metadata!(df::AbstractDataFrame, key::AbstractString, value; style) - metadata!(dfr::DataFrameRow, key::AbstractString, value; style) - metadata!(dfc::DataFrameColumns, key::AbstractString, value; style) - metadata!(dfr::DataFrameRows, key::AbstractString, value; style) + metadata!(df::AbstractDataFrame, key::AbstractString, value; style::Symbol=:default) + metadata!(dfr::DataFrameRow, key::AbstractString, value; style::Symbol=:default) + metadata!(dfc::DataFrameColumns, key::AbstractString, value; style::Symbol=:default) + metadata!(dfr::DataFrameRows, key::AbstractString, value; style::Symbol=:default) Set table-level metadata for object `df` for key `key` to have value `value` -and style `style` and return `df`. +and style `style` (`:default` by default) and return `df`. For `SubDataFrame` and `DataFrameRow` only `:note`-style is allowed. Trying to set a key-value pair for which the key already exists in the parent @@ -188,7 +188,8 @@ See also: [`metadata`](@ref), [`metadatakeys`](@ref), $TABLEMETA_EXAMPLE ``` """ -function metadata!(df::DataFrame, key::AbstractString, value::Any; style) +function metadata!(df::DataFrame, key::AbstractString, value::Any; + style::Symbol=:default) premeta = getfield(df, :metadata) if premeta === nothing meta = Dict{String, Tuple{Any, Any}}() @@ -204,13 +205,13 @@ function metadata!(df::DataFrame, key::AbstractString, value::Any; style) end function metadata!(x::Union{DataFrameRows, DataFrameColumns}, - key::AbstractString, value::Any; style) + key::AbstractString, value::Any; style::Symbol=:default) metadata!(parent(x), key, value, style=style) return x end function metadata!(x::Union{DataFrameRow, SubDataFrame}, - key::AbstractString, value::Any; style) + key::AbstractString, value::Any; style::Symbol=:default) if style !== :note throw(ArgumentError("only :note-style metadata is supported for " * "DataFrameRow and SubDataFrame")) @@ -464,13 +465,13 @@ function colmetadatakeys(x::Union{DataFrameRow, SubDataFrame}) end """ - colmetadata!(df::AbstractDataFrame, col::ColumnIndex, key::AbstractString, value; style) - colmetadata!(dfr::DataFrameRow, col::ColumnIndex, key::AbstractString, value; style) - colmetadata!(dfc::DataFrameColumns, col::ColumnIndex, key::AbstractString, value; style) - colmetadata!(dfr::DataFrameRows, col::ColumnIndex, key::AbstractString, value; style) + colmetadata!(df::AbstractDataFrame, col::ColumnIndex, key::AbstractString, value; style::Symbol=:default) + colmetadata!(dfr::DataFrameRow, col::ColumnIndex, key::AbstractString, value; style::Symbol=:default) + colmetadata!(dfc::DataFrameColumns, col::ColumnIndex, key::AbstractString, value; style::Symbol=:default) + colmetadata!(dfr::DataFrameRows, col::ColumnIndex, key::AbstractString, value; style::Symbol=:default) Set column-level metadata in `df` for column `col` and key `key` to have value `value` -and style `style` and return `df`. +and style `style` (`:default` by default) and return `df`. For `SubDataFrame` and `DataFrameRow` only `:note` style is allowed. Trying to set a key-value pair for which the key already exists in the parent @@ -484,7 +485,8 @@ See also: [`metadata`](@ref), [`metadatakeys`](@ref), $COLMETADATA_EXAMPLE ``` """ -function colmetadata!(df::DataFrame, col::ColumnIndex, key::AbstractString, value::Any; style) +function colmetadata!(df::DataFrame, col::ColumnIndex, key::AbstractString, value::Any; + style::Symbol=:default) idx = index(df)[col] # check if column exists and get its integer index pre_cols_meta = getfield(df, :colmetadata) if pre_cols_meta === nothing @@ -502,13 +504,15 @@ function colmetadata!(df::DataFrame, col::ColumnIndex, key::AbstractString, valu end function colmetadata!(x::Union{DataFrameRows, DataFrameColumns}, - col::ColumnIndex, key::AbstractString, value::Any; style) + col::ColumnIndex, key::AbstractString, value::Any; + style::Symbol=:default) colmetadata!(parent(x), col, key, value; style=style) return x end function colmetadata!(x::Union{DataFrameRow, SubDataFrame}, - col::ColumnIndex, key::AbstractString, value::Any; style) + col::ColumnIndex, key::AbstractString, value::Any; + style::Symbol=:default) col_name = _names(x)[index(x)[col]] if style !== :note throw(ArgumentError("only :note-style metadata is supported for " * diff --git a/test/metadata.jl b/test/metadata.jl index fbf770a51c..aa5d8d738b 100644 --- a/test/metadata.jl +++ b/test/metadata.jl @@ -470,6 +470,22 @@ end @test check_allnotemetadata(df) end +@testset "metadata default" begin + df = DataFrame(a=1) + metadata!(df, "x", "y") + colmetadata!(df, :a, "p", "q") + @test metadata(df, "x", style=true) == ("y", :default) + @test colmetadata(df, :a, "p", style=true) == ("q", :default) + df = eachcol(DataFrame(a=1)) + metadata!(df, "x", "y") + colmetadata!(df, :a, "p", "q") + @test metadata(df, "x", style=true) == ("y", :default) + @test colmetadata(df, :a, "p", style=true) == ("q", :default) + df = view(DataFrame(a=1), :, :) + @test_throws ArgumentError metadata!(df, "x", "y") + @test_throws ArgumentError colmetadata!(df, :a, "p", "q") +end + @testset "rename & rename!" begin df = DataFrame() df2 = rename(df) From f3b3f04b956ebf72ecf191bf5e04eb975125bfa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Sat, 5 Nov 2022 01:12:52 +0100 Subject: [PATCH 2/4] require DataAPI.jl 1.13 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 153d1f19c2..e08d6eda97 100644 --- a/Project.toml +++ b/Project.toml @@ -27,7 +27,7 @@ Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" [compat] CategoricalArrays = "0.10.0" Compat = "4.2" -DataAPI = "1.12.0" +DataAPI = "1.13.0" InvertedIndices = "1" IteratorInterfaceExtensions = "0.1.1, 1" Missings = "0.4.2, 1" From 0d6a1a6dc67fc15745438ac3bbf52a1bed58c4aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Sat, 5 Nov 2022 11:01:02 +0100 Subject: [PATCH 3/4] improve tests --- test/metadata.jl | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/metadata.jl b/test/metadata.jl index aa5d8d738b..3b27c7ee20 100644 --- a/test/metadata.jl +++ b/test/metadata.jl @@ -486,6 +486,43 @@ end @test_throws ArgumentError colmetadata!(df, :a, "p", "q") end +@testset "fallback definitions of metadata and colmetadata" begin + df = DataFrame() + @test metadata(df) == Dict() + @test metadata(df, style=true) == Dict() + @test colmetadata(df) == Dict() + @test colmetadata(df, style=true) == Dict() + df.a = 1:2 + df.b = 2:3 + df.c = 3:4 + @test metadata(df) == Dict() + @test metadata(df, style=true) == Dict() + @test colmetadata(df) == Dict() + @test colmetadata(df, style=true) == Dict() + metadata!(df, "a1", "b1", style=:default) + metadata!(df, "a2", "b2", style=:note) + colmetadata!(df, :a, "x1", "y1", style=:default) + colmetadata!(df, :a, "x2", "y2", style=:note) + colmetadata!(df, :c, "x3", "y3", style=:note) + @test metadata(df) == Dict("a1" => "b1", "a2" => "b2") + @test metadata(df, style=true) == Dict("a1" => ("b1", :default), + "a2" => ("b2", :note)) + @test colmetadata(df) == Dict(:a => Dict("x1" => "y1", + "x2" => "y2"), + :c => Dict("x3" => "y3")) + @test colmetadata(df, style=true) == Dict(:a => Dict("x1" => ("y1", :default), + "x2" => ("y2", :note)), + :c => Dict("x3" => ("y3", :note))) + @test colmetadata(df, :a) == Dict("x1" => "y1", + "x2" => "y2") + @test colmetadata(df, :a, style=true) == Dict("x1" => ("y1", :default), + "x2" => ("y2", :note)) + @test colmetadata(df, :b) == Dict() + @test colmetadata(df, :b, style=true) == Dict() + @test colmetadata(df, :c) == Dict("x3" => "y3") + @test colmetadata(df, :c, style=true) == Dict("x3" => ("y3", :note)) +end + @testset "rename & rename!" begin df = DataFrame() df2 = rename(df) From abad0a2a98be691e4c2cd82fd27a9743891891fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Sat, 5 Nov 2022 11:11:39 +0100 Subject: [PATCH 4/4] add NEWS.md entry --- NEWS.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS.md b/NEWS.md index 8a4b24f703..9086da2535 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,11 @@ * Improve printing of grouping keys when displaying `GroupedDataFrame` ([#3213](https://github.com/JuliaData/DataFrames.jl/pull/3213)) +## Integration changes + +* Support updates of metadata API introduced in DataAPI.jl 1.13.0 + ([3216](https://github.com/JuliaData/DataFrames.jl/pull/3216)) + # DataFrames.jl v1.4.2 Patch Release Notes ## Bug fixes