From 1e9a1552eb392fc9cc3491a542226f41ee17af5f Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Thu, 26 May 2022 13:07:40 +0200 Subject: [PATCH 1/9] Import R data frame attributes as metadata Use the `metadata` function recently added to DataAPI and DataFrames to import R `data.frame` attributes and set them as `DataFrame` metadata. R stores per-column attributes in vector objects, while DataFrames.jl stores them in the `DataFrame` object, as there is no generic mechanism to attach metadata to an `AbstractVector` object. The `row.names` attribute is skipped as it is not appropriate to store it as global metadata given that it will get out of sync after subsetting rows. We could provide a way to turn row names into a column instead. Also add methods to check equality between two `DictoVec` objects as these are useful for tests (haven commonly sets named numeric vectors to store value labels so this case deserves testing). --- Project.toml | 2 ++ src/DictoVec.jl | 9 +++++++ src/RData.jl | 2 +- src/convert.jl | 21 +++++++++++++--- test/DictoVec.jl | 46 ++++++++++++++++++++++++++++++++++ test/RDA.jl | 16 ++++++++++++ test/data_v3/dfattributes.rda | Bin 0 -> 313 bytes 7 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 test/data_v3/dfattributes.rda diff --git a/Project.toml b/Project.toml index 38551fa..bc0b108 100644 --- a/Project.toml +++ b/Project.toml @@ -5,6 +5,7 @@ version = "0.8.3" [deps] CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597" CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193" +DataAPI = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" @@ -15,6 +16,7 @@ Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" [compat] CategoricalArrays = "0.8, 0.9, 0.10" CodecZlib = "0.4, 0.5, 0.6, 0.7" +DataAPI = "1.11" DataFrames = "0.21, 0.22, 1.0" FileIO = "1.6.5" Requires = "1.0.0" diff --git a/src/DictoVec.jl b/src/DictoVec.jl index 0fc275c..a87c429 100644 --- a/src/DictoVec.jl +++ b/src/DictoVec.jl @@ -26,6 +26,15 @@ struct DictoVec{T} end end +Base.:(==)(dict1::DictoVec, dict2::DictoVec) = + dict1.index2name == dict2.index2name && dict1.data == dict2.data +Base.isequal(dict1::DictoVec, dict2::DictoVec) = + isequal(dict1.index2name, dict2.index2name) && isequal(dict1.data, dict2.data) + +const hash_dictovec_seed = UInt === UInt64 ? 0xe00ac4bbcfc2fa07 : 0x57f3f900 +Base.hash(dict::DictoVec, h::UInt) = + hash(dict.index2name, hash(dict.data, h + hash_dictovec_seed)) + Base.eltype(::Type{DictoVec{T}}) where T = T Base.eltype(dict::DictoVec) = eltype(typeof(dict)) Base.length(dict::DictoVec) = length(dict.data) diff --git a/src/RData.jl b/src/RData.jl index 814ae3f..87b985d 100644 --- a/src/RData.jl +++ b/src/RData.jl @@ -1,6 +1,6 @@ module RData -using DataFrames, CategoricalArrays, FileIO, TimeZones, Unicode +using DataAPI, DataFrames, CategoricalArrays, FileIO, TimeZones, Unicode export sexp2julia, diff --git a/src/convert.jl b/src/convert.jl index a26685f..a364ee3 100644 --- a/src/convert.jl +++ b/src/convert.jl @@ -225,14 +225,27 @@ end function sexp2julia(rl::RList) if isdataframe(rl) # FIXME add force_missing option to control whether always convert to Union{T, Missing} - DataFrame(Any[isa(col, RAltRep) ? sexp2julia(col) : jlvec(col, false) for col in rl.data], - identifier.(names(rl)), makeunique=true) + cols = Any[isa(col, RAltRep) ? sexp2julia(col) : jlvec(col, false) for col in rl.data] + nms = identifier.(names(rl)) + obj = DataFrame(cols, nms, makeunique=true) + meta = DataAPI.metadata(obj) + for (key, val) in pairs(rl.attr) + key in ("names", "class", "row.names") && continue + meta[key] = sexp2julia(val) + end + for (col, name) in zip(rl.data, nms) + colmeta = DataAPI.metadata(obj, name) + for (key, val) in pairs(col.attr) + colmeta[key] = sexp2julia(val) + end + end elseif hasnames(rl) - DictoVec(jlvec(Any, rl), names(rl)) + obj = DictoVec(jlvec(Any, rl), names(rl)) else # FIXME return DictoVec if forceDictoVec is on - jlvec(Any, rl) + obj = jlvec(Any, rl) end + return obj end function sexp2julia(ar::RAltRep) diff --git a/test/DictoVec.jl b/test/DictoVec.jl index 87b820b..f7f0272 100644 --- a/test/DictoVec.jl +++ b/test/DictoVec.jl @@ -28,6 +28,13 @@ end @test_throws KeyError dv["a"] @test_throws KeyError dv[:a] + @test dv == DictoVec(Symbol[]) == DictoVec(Int[]) + @test isequal(dv, DictoVec(Symbol[])) + @test isequal(dv, DictoVec(Int[])) + @test dv != DictoVec([:a], ["a"]) + @test !isequal(dv, DictoVec([:a], ["a"])) + @test hash(dv) == hash(DictoVec(Symbol[])) == hash(DictoVec(Int[])) + @test get(dv, 1, :x) == :x @test get(() -> :y, dv, 1) == :y @test get(dv, "a", :x) == :x @@ -88,6 +95,17 @@ end @test collect(keys(dv)) == RData.RString[] @test values(dv) == [2.0, 5.0, 4.0] + @test dv == DictoVec([2.0, 5.0, 4.0]) + @test dv == DictoVec([2, 5, 4]) + @test isequal(dv, DictoVec([2.0, 5.0, 4.0])) + @test dv != DictoVec([3.0, 5.0, 4.0]) + @test !isequal(dv, DictoVec([3.0, 5.0, 4.0])) + @test dv != DictoVec([2.0, 5.0, 4.0], ["b", "c", "a"]) + @test !isequal(dv, DictoVec([2.0, 5.0, 4.0], ["b", "c", "a"])) + @test hash(dv) == + hash(DictoVec([2.0, 5.0, 4.0])) == + hash(DictoVec([2, 5, 4])) + @test_throws BoundsError dv[0] @test_throws BoundsError dv[4] @test dv[1] == 2.0 @@ -121,6 +139,17 @@ end @test values(dv) == [2.0, 5.0, 4.0] @test show2string(dv) == "DictoVec{Float64}(\"a\"=>2.0,\"b\"=>5.0,\"c\"=>4.0)" + @test dv == DictoVec([2.0, 5.0, 4.0], ["a", "b", "c"]) + @test dv == DictoVec([2, 5, 4], ["a", "b", "c"]) + @test isequal(dv, DictoVec([2.0, 5.0, 4.0], ["a", "b", "c"])) + @test dv != DictoVec([3.0, 5.0, 4.0], ["a", "b", "c"]) + @test !isequal(dv, DictoVec([3.0, 5.0, 4.0], ["a", "b", "c"])) + @test dv != DictoVec([2.0, 5.0, 4.0], ["b", "c", "a"]) + @test !isequal(dv, DictoVec([2.0, 5.0, 4.0], ["b", "c", "a"])) + @test hash(dv) == + hash(DictoVec([2.0, 5.0, 4.0], ["a", "b", "c"])) == + hash(DictoVec([2, 5, 4], ["a", "b", "c"])) + @test dv[1] === 2.0 @test dv["a"] === 2.0 @test dv[[1, 3]] == [2.0, 4.0] @@ -142,6 +171,23 @@ end @test show2string(dv) == "DictoVec{Float64}(\"a\"=>6.0,\"c\"=>4.0)" end +@testset "== and isequal with -0.0, NaN and missing" begin + @test DictoVec([0.0, 5.0, 4.0], ["b", "c", "a"]) == + DictoVec([-0.0, 5.0, 4.0], ["b", "c", "a"]) + @test !isequal(DictoVec([0.0, 5.0, 4.0], ["b", "c", "a"]), + DictoVec([-0.0, 5.0, 4.0], ["b", "c", "a"])) + + @test DictoVec([NaN, 5.0, 4.0], ["b", "c", "a"]) != + DictoVec([NaN, 5.0, 4.0], ["b", "c", "a"]) + @test isequal(DictoVec([NaN, 5.0, 4.0], ["b", "c", "a"]), + DictoVec([NaN, 5.0, 4.0], ["b", "c", "a"])) + + @test ismissing(DictoVec([missing, 5.0, 4.0], ["b", "c", "a"]) != + DictoVec([missing, 5.0, 4.0], ["b", "c", "a"])) + @test isequal(DictoVec([missing, 5.0, 4.0], ["b", "c", "a"]), + DictoVec([missing, 5.0, 4.0], ["b", "c", "a"])) +end + end end # TestDictoVec diff --git a/test/RDA.jl b/test/RDA.jl index 58d6176..bcfc89c 100644 --- a/test/RDA.jl +++ b/test/RDA.jl @@ -3,6 +3,7 @@ using Test using DataFrames using CategoricalArrays using RData +using TimeZones @testset "Loading RData files (version=$ver)" for ver in (2, 3) rdata_path = joinpath(dirname(@__FILE__), "data_v$ver") @@ -195,4 +196,19 @@ end ["Inferior", "Anterior", "LBBB", "Missing", "NoSTUp", "OtherSTUp", "Paced"] end +@testset "Data frames attributes (version=3)" begin + df = load(joinpath("data_v3", "dfattributes.rda"))["df"] + + @test metadata(df) == + Dict("collectiondates" => [ZonedDateTime(2022, 05, 25, 22, 5, tz"UTC"), + ZonedDateTime(2022, 05, 26, 22, 5, tz"UTC")], + "comment" => "This is a data frame") + @test metadata(df, :x) == + Dict("label" => "X") + @test isequal(metadata(df, :y), + Dict("labels" => DictoVec([1.0, 2.0, 3.0, missing], + ["a", "b", "c", "missing"]), + "unit" => "s")) +end + end # module TestRDA diff --git a/test/data_v3/dfattributes.rda b/test/data_v3/dfattributes.rda new file mode 100644 index 0000000000000000000000000000000000000000..240b0ab72342321395a44c27df8bd006c999f455 GIT binary patch literal 313 zcmV-90ml9xiwFP!000001AS3TPQ)+_^`tGOm4K1p0KEXSVZ#oP5E3g83{tn5Ob05p zsWb`Vvw^d~juUYVF2EE!X$0d1RT{rIwx9iSby^Dm4vKrHYu zf*3NiV!ptrT|&6FTngQ~GvT%9q>;0#K`{Q~9F@4OFk$Qoy;BA-3qY}A@x87suVq-! zhGRsp*rt@DFL2*640hAo7w1pkc)wb Date: Thu, 26 May 2022 16:54:50 +0200 Subject: [PATCH 2/9] Set size hint --- src/convert.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/convert.jl b/src/convert.jl index a364ee3..fe3cc2f 100644 --- a/src/convert.jl +++ b/src/convert.jl @@ -229,12 +229,14 @@ function sexp2julia(rl::RList) nms = identifier.(names(rl)) obj = DataFrame(cols, nms, makeunique=true) meta = DataAPI.metadata(obj) + sizehint!(meta, length(rl.attr)) for (key, val) in pairs(rl.attr) key in ("names", "class", "row.names") && continue meta[key] = sexp2julia(val) end for (col, name) in zip(rl.data, nms) colmeta = DataAPI.metadata(obj, name) + sizehint!(colmeta, length(col.attr)) for (key, val) in pairs(col.attr) colmeta[key] = sexp2julia(val) end From a6f7d19fadd978452e0564d8476699e1027fbfd3 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Sat, 1 Oct 2022 23:32:38 +0200 Subject: [PATCH 3/9] Fixes --- src/DictoVec.jl | 6 ++--- src/RData.jl | 8 ++++-- src/convert.jl | 43 ++++++++++++++++++----------- test/RDA.jl | 49 +++++++++++++++++++++++----------- test/data_v2/dfattributes.rda | Bin 0 -> 406 bytes test/data_v3/dfattributes.rda | Bin 313 -> 406 bytes test/generate_rda.R | 37 +++++++++++++++++++++++++ 7 files changed, 107 insertions(+), 36 deletions(-) create mode 100644 test/data_v2/dfattributes.rda diff --git a/src/DictoVec.jl b/src/DictoVec.jl index a87c429..4d6eec6 100644 --- a/src/DictoVec.jl +++ b/src/DictoVec.jl @@ -27,13 +27,13 @@ struct DictoVec{T} end Base.:(==)(dict1::DictoVec, dict2::DictoVec) = - dict1.index2name == dict2.index2name && dict1.data == dict2.data + dict1.name2index == dict2.name2index && dict1.data == dict2.data Base.isequal(dict1::DictoVec, dict2::DictoVec) = - isequal(dict1.index2name, dict2.index2name) && isequal(dict1.data, dict2.data) + isequal(dict1.name2index, dict2.name2index) && isequal(dict1.data, dict2.data) const hash_dictovec_seed = UInt === UInt64 ? 0xe00ac4bbcfc2fa07 : 0x57f3f900 Base.hash(dict::DictoVec, h::UInt) = - hash(dict.index2name, hash(dict.data, h + hash_dictovec_seed)) + hash(dict.name2index, hash(dict.data, h + hash_dictovec_seed)) Base.eltype(::Type{DictoVec{T}}) where T = T Base.eltype(dict::DictoVec) = eltype(typeof(dict)) diff --git a/src/RData.jl b/src/RData.jl index 87b985d..67358b8 100644 --- a/src/RData.jl +++ b/src/RData.jl @@ -44,6 +44,8 @@ end ## supported `kwoptions`: ## convert::Bool (true by default) for converting R objects into Julia equivalents, ## otherwise load() returns R internal representation (ROBJ-derived objects) +## metadata::Bool (true by default) for importing R attributes into metadata +## (only has an effect for data frames currently) ## TODO option for disabling names checking (e.g. column names) ## ############################################################################## @@ -57,6 +59,7 @@ function fileio_load(s::Stream{format"RData"}; kwoptions...) @debug "minimal R version: $(ctx.Rmin)" convert2julia = get(ctx.kwdict, :convert, true) + metadata = get(ctx.kwdict, :metadata, true) # top level read -- must be a paired list of objects # we read it here to be able to convert to julia objects inplace @@ -70,7 +73,7 @@ function fileio_load(s::Stream{format"RData"}; kwoptions...) tag = readitem(ctx) obj_name = convert(RString, isa(tag, RSymbol) ? tag.displayname : "\0") obj = readitem(ctx) - setindex!(res, (convert2julia ? sexp2julia(obj) : obj), obj_name) + setindex!(res, (convert2julia ? sexp2julia(obj, metadata=metadata) : obj), obj_name) fl = readuint32(ctx.io) readattrs(ctx, fl) end @@ -84,7 +87,8 @@ function fileio_load(s::Stream{format"RDataSingle"}; kwoptions...) ctx = RDAContext(rdaio(io, chomp(readline(io))); kwoptions...) @assert ctx.fmtver == 2 || ctx.fmtver == 3 # supported format versions convert2julia = get(ctx.kwdict, :convert, true) - return convert2julia ? sexp2julia(readitem(ctx)) : readitem(ctx) + metadata = get(ctx.kwdict, :metadata, true) + return convert2julia ? sexp2julia(readitem(ctx), metadata=metadata) : readitem(ctx) end function fileio_load(f::Union{File{format"RData"}, File{format"RDataSingle"}}; diff --git a/src/convert.jl b/src/convert.jl index fe3cc2f..9dfb71b 100644 --- a/src/convert.jl +++ b/src/convert.jl @@ -194,12 +194,12 @@ function jlvec(::Type{T}, rv::RVEC, force_missing::Bool=true) where T end end -function sexp2julia(rex::RSEXPREC) +function sexp2julia(rex::RSEXPREC; metadata::Bool=true) @warn "Conversion of $(typeof(rex)) to Julia is not implemented" maxlog=1 return nothing end -function sexp2julia(rv::RVEC) +function sexp2julia(rv::RVEC; metadata::Bool=true) # TODO dimnames? # FIXME add force_missing option to control whether always convert to Union{T, Missing} jv = jlvec(rv, false) @@ -222,23 +222,34 @@ function sexp2julia(rv::RVEC) end end -function sexp2julia(rl::RList) +function sexp2julia(rl::RList; metadata::Bool=true) if isdataframe(rl) # FIXME add force_missing option to control whether always convert to Union{T, Missing} cols = Any[isa(col, RAltRep) ? sexp2julia(col) : jlvec(col, false) for col in rl.data] nms = identifier.(names(rl)) obj = DataFrame(cols, nms, makeunique=true) - meta = DataAPI.metadata(obj) - sizehint!(meta, length(rl.attr)) - for (key, val) in pairs(rl.attr) - key in ("names", "class", "row.names") && continue - meta[key] = sexp2julia(val) - end - for (col, name) in zip(rl.data, nms) - colmeta = DataAPI.metadata(obj, name) - sizehint!(colmeta, length(col.attr)) - for (key, val) in pairs(col.attr) - colmeta[key] = sexp2julia(val) + if metadata + for (key, val) in pairs(rl.attr) + # skip already processed system attributes + if key in ("names", "class") + continue + elseif key in ("comment", "label") + metadata!(obj, key, sexp2julia(val), style=:note) + else + metadata!(obj, key, sexp2julia(val), style=:default) + end + end + for (col, name) in zip(rl.data, nms) + for (key, val) in pairs(col.attr) + # skip already processed system attributes + if key in ("names", "class", "levels") + continue + elseif key in ("comment", "label", "units") + colmetadata!(obj, name, key, sexp2julia(val), style=:note) + else + colmetadata!(obj, name, key, sexp2julia(val), style=:default) + end + end end end elseif hasnames(rl) @@ -250,9 +261,9 @@ function sexp2julia(rl::RList) return obj end -function sexp2julia(ar::RAltRep) +function sexp2julia(ar::RAltRep; metadata::Bool=true) if iswrapped(ar) - return sexp2julia(unwrap(ar)) + return sexp2julia(unwrap(ar), metadata=metadata) elseif iscompactseq(ar) return jlrange(ar) else diff --git a/test/RDA.jl b/test/RDA.jl index bcfc89c..ace1193 100644 --- a/test/RDA.jl +++ b/test/RDA.jl @@ -143,6 +143,40 @@ using TimeZones @test testdf[!, "listascol2"] isa Vector{Any} @test isequal(testdf[!, "listascol2"], [[1., 2.], [3, 4], [5., 6., 7.]]) end # list of vectors + + @testset "Data frames attributes to metadata (version=3)" begin + df = load(joinpath("data_v3", "dfattributes.rda"))["df"] + + @test isequal(Dict(k => metadata(df, k, style=true) for k in metadatakeys(df)), + Dict("collectiontimes" => ([ZonedDateTime(2022, 05, 25, 22, 5, tz"UTC"), + ZonedDateTime(2022, 05, 26, 22, 5, tz"UTC")], + :default), + "comment" => ("This is a data frame", :note), + "row.names" => ([missing, -6], :default))) + @test Dict(k => colmetadata(df, :v1, k, style=true) for k in colmetadatakeys(df, :v1)) == + Dict("label" => ("V1", :note), + "labels" => (DictoVec([1.0, 2.0, 3.0], ["a", "b", "c"]), :default)) + @test Dict(k => colmetadata(df, :v2, k, style=true) for k in colmetadatakeys(df, :v2)) == + Dict("label" => ("V2", :note), + "labels" => (DictoVec([1.0, 2.0, 3.0], ["a", "b", "c"]), :default), + "na_values" => (3.0, :default)) + @test Dict(k => colmetadata(df, :v3, k, style=true) for k in colmetadatakeys(df, :v3)) == + Dict("label" => ("V3", :note), + "labels" => (DictoVec([1.0, 2.0, 3.0], ["a", "b", "c"]), :default), + "na_range" => ([3.0, Inf], :default)) + @test Dict(k => colmetadata(df, :v4, k, style=true) for k in colmetadatakeys(df, :v4)) == + Dict("label" => ("V4", :note), + "comment" => ("A comment", :note), + "units" => ("m/s^2", :note), + "custom" => (1, :default)) + + df = load(joinpath("data_v3", "dfattributes.rda"), metadata=false)["df"] + @test isempty(metadatakeys(df)) + @test isempty(colmetadatakeys(df, :v1)) + @test isempty(colmetadatakeys(df, :v2)) + @test isempty(colmetadatakeys(df, :v3)) + @test isempty(colmetadatakeys(df, :v4)) + end end # for ver in ... @testset "Loading AltRep-containing RData files (version=3)" begin @@ -196,19 +230,4 @@ end ["Inferior", "Anterior", "LBBB", "Missing", "NoSTUp", "OtherSTUp", "Paced"] end -@testset "Data frames attributes (version=3)" begin - df = load(joinpath("data_v3", "dfattributes.rda"))["df"] - - @test metadata(df) == - Dict("collectiondates" => [ZonedDateTime(2022, 05, 25, 22, 5, tz"UTC"), - ZonedDateTime(2022, 05, 26, 22, 5, tz"UTC")], - "comment" => "This is a data frame") - @test metadata(df, :x) == - Dict("label" => "X") - @test isequal(metadata(df, :y), - Dict("labels" => DictoVec([1.0, 2.0, 3.0, missing], - ["a", "b", "c", "missing"]), - "unit" => "s")) -end - end # module TestRDA diff --git a/test/data_v2/dfattributes.rda b/test/data_v2/dfattributes.rda new file mode 100644 index 0000000000000000000000000000000000000000..6813e16d92fa1f79690d46801ea76625aa06ea5c GIT binary patch literal 406 zcmV;H0crjpiwFP!000001JzUAO2aS|PSbYl2L6CPKwrSgHZQ!>p$J|ny2-ATEX%ae zrqHGnyqV9UcRrDi;k6g5r)ksCY@#9vmNw_4Ip@pyzMNbf54+7_6Cq?G%fQIA!A16< zf3mZWkcDAlAPY6X;_(Ecw!pK%u7j-|ydn7d>$!5rBDW-V)z-tPPvTe$tMepakypU}MgW|CkFuHm zh^3{%7sNUmu?8nMQ{pF5zpMhIx}&W_{72GVjkE)#Bf@W4!5LQz{R8eRiro8h(+Y<= z4TFGjp+z@(Zn;qH;DmcZ?_fLFjj#2VsL>=AVNhseEDBc&mj`00;-~G>>y%!%^gg53 z91}rWlL)S_-j-2#-%{6lEdzOkAx+cwJkZghw)=Np?7~aj4Afl(x{Os~{NQII~PM2gB4p$J|ny2-ATEX%ae zrqHGnyqV9UcRrDi;k6g5r)ksCY@#9vmNw_4Ip@pyzMNbf54+7_6Cq?G%fQIA!A16< zf3mZWkcDAlAPY6X;_(Ecw!pK%u7j-|ydn7d>$!5rBDW-V)z-tPPvTe$tMepakypU}MgW|CkFuHm zh^3{%7sNUmu?8nMQ{pF5zpMhIx}&W_{72GVjkE)#Bf@W4!5LQz{R8eRiro8h(+Y<= z4TFGjp+z@(Zn;qH;DmcZ?_fLFjj#2VsL>=AVNhseEDBc&mj`00;-~G>>y%!%^gg53 z91}rWlL)S_-j-2#-%{6lEdzOkAx+cwJkZghw)=Np?7~aj4Afl(x{Os~{NQII~PM2gB4Dm4vKrHYu zf*3NiV!ptrT|&6FTngQ~GvT%9q>;0#K`{Q~9F@4OFk$Qoy;BA-3qY}A@x87suVq-! zhGRsp*rt@DFL2*640hAo7w1pkc)wb Date: Sun, 2 Oct 2022 12:23:11 +0200 Subject: [PATCH 4/9] Require DataFrames 1.4 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index bc0b108..d060069 100644 --- a/Project.toml +++ b/Project.toml @@ -17,7 +17,7 @@ Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" CategoricalArrays = "0.8, 0.9, 0.10" CodecZlib = "0.4, 0.5, 0.6, 0.7" DataAPI = "1.11" -DataFrames = "0.21, 0.22, 1.0" +DataFrames = "1.4" FileIO = "1.6.5" Requires = "1.0.0" TimeZones = "0.7, 0.8, 0.9, 0.10, 1.0" From 424fcd48dc83d6add84438409c12d51b90f38d18 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Sun, 9 Oct 2022 22:20:29 +0200 Subject: [PATCH 5/9] Update src/convert.jl Co-authored-by: Alexey Stukalov --- src/convert.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/convert.jl b/src/convert.jl index 9dfb71b..a12a946 100644 --- a/src/convert.jl +++ b/src/convert.jl @@ -234,7 +234,7 @@ function sexp2julia(rl::RList; metadata::Bool=true) if key in ("names", "class") continue elseif key in ("comment", "label") - metadata!(obj, key, sexp2julia(val), style=:note) + metadata!(obj, key, sexp2julia(val; metadata=metadata), style=:note) else metadata!(obj, key, sexp2julia(val), style=:default) end From 47f30dbd55132292161d982e2fec1029e7756e33 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Sun, 9 Oct 2022 22:22:22 +0200 Subject: [PATCH 6/9] Update Project.toml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bogumił Kamiński --- Project.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index d060069..b8bc3bc 100644 --- a/Project.toml +++ b/Project.toml @@ -16,8 +16,8 @@ Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" [compat] CategoricalArrays = "0.8, 0.9, 0.10" CodecZlib = "0.4, 0.5, 0.6, 0.7" -DataAPI = "1.11" -DataFrames = "1.4" +DataAPI = "1.12.0" +DataFrames = "1.4.0" FileIO = "1.6.5" Requires = "1.0.0" TimeZones = "0.7, 0.8, 0.9, 0.10, 1.0" From d0333a452fbde531908856e7040af15762676ef0 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Sun, 9 Oct 2022 22:49:18 +0200 Subject: [PATCH 7/9] Bump version to 1.0 --- Project.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index b8bc3bc..d4ef0e7 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "RData" uuid = "df47a6cb-8c03-5eed-afd8-b6050d6c41da" -version = "0.8.3" +version = "1.0.0" [deps] CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597" @@ -21,7 +21,7 @@ DataFrames = "1.4.0" FileIO = "1.6.5" Requires = "1.0.0" TimeZones = "0.7, 0.8, 0.9, 0.10, 1.0" -julia = "1" +julia = "1.6" [extras] CodecBzip2 = "523fee87-0ab8-5b00-afb7-3ecf72e48cfd" From 09d0f1c7a00317317bace81aa0ae4a91bdab515d Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Sun, 9 Oct 2022 22:49:59 +0200 Subject: [PATCH 8/9] Update ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a40f49c..ba2f6fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: fail-fast: false matrix: version: - - '1.0' + - '1.6' - '1' # automatically expands to the latest stable 1.x release of Julia - 'nightly' os: From 2724f62e2a958decf33413924c4c1e4d732e4e42 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Mon, 10 Oct 2022 08:26:46 +0200 Subject: [PATCH 9/9] Also drop Julia 1.0 on macOS --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba2f6fe..5937610 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: - x86 include: # macos doesn't support x86 - os: macos-latest - version: '1.0' + version: '1.6' arch: x64 - os: macos-latest version: '1'