From 3ef44c04f869b8778af282872056f5e8560895e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Wed, 18 Oct 2023 21:02:31 +0200 Subject: [PATCH 1/4] initial implementation --- src/dataframerow/dataframerow.jl | 40 +++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/dataframerow/dataframerow.jl b/src/dataframerow/dataframerow.jl index 4b9cf4930..f8a035262 100644 --- a/src/dataframerow/dataframerow.jl +++ b/src/dataframerow/dataframerow.jl @@ -259,11 +259,45 @@ for T in MULTICOLUMNINDEX_TUPLE end end -Base.@propagate_inbounds Base.setindex!(r::DataFrameRow, value, idx) = - setindex!(parent(r), value, row(r), parentcols(index(r), idx)) - index(r::DataFrameRow) = getfield(r, :colindex) +is_column_insertion_allowed(dfr::DataFrameRow) = index(dfr) isa Index + +Base.@propagate_inbounds function Base.setindex!(dfr::DataFrameRow, value, idx) + if colinds isa SymbolOrString && columnindex(dfr, colinds) == 0 + if !is_column_insertion_allowed(dfr) + throw(ArgumentError("creating new columns in a DataFrameRow that subsets " * + "columns of its parent data frame is disallowed")) + end + T = typeof(val) + newcol = similar(val, Union{T,Missing}, nrow(parent(dfr))) + fill!(newcol, missing) + newcol[row(dfr)] = val + parent(dfr)[!, colinds] = newcol + else + setindex!(parent(dfr), value, row(dfr), parentcols(index(dfr), idx)) + end + return dfr +end + +insertcols(dfr::DataFrameRow, args...; + after::Bool=false, makeunique::Bool=false, copycols::Bool=true) = + throw(ArgumentError("insertcols is not supported for DataFrameRow. " * + "Maybe you wanted to use insertcols!?")) + +function insertcols!(dfr::DataFrameRow, col::ColumnIndex, name_cols::Pair{Symbol}...; + after::Bool=false, makeunique::Bool=false, copycols::Bool=false) + if !is_column_insertion_allowed(dfr) + throw(ArgumentError("creating new columns in a DataFrameRow that subsets " * + "columns of its parent data frame is disallowed")) + end + r = row(dfr) + insertcols!(view(parent(dfr), r:r, :), + col, (k => [v] for (k,v) in name_cols)..., + after=after, makeunique=makeunique, copycols=copycols) + return dfr +end + Base.names(r::DataFrameRow, cols::Colon=:) = names(index(r)) function Base.names(r::DataFrameRow, cols) From 68906818a58723cbafc1fa4eaef17256d7e51fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Wed, 18 Oct 2023 23:39:08 +0200 Subject: [PATCH 2/4] fix typo --- src/dataframerow/dataframerow.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dataframerow/dataframerow.jl b/src/dataframerow/dataframerow.jl index f8a035262..5107c8b6a 100644 --- a/src/dataframerow/dataframerow.jl +++ b/src/dataframerow/dataframerow.jl @@ -264,7 +264,7 @@ index(r::DataFrameRow) = getfield(r, :colindex) is_column_insertion_allowed(dfr::DataFrameRow) = index(dfr) isa Index Base.@propagate_inbounds function Base.setindex!(dfr::DataFrameRow, value, idx) - if colinds isa SymbolOrString && columnindex(dfr, colinds) == 0 + if idx isa SymbolOrString && columnindex(dfr, idx) == 0 if !is_column_insertion_allowed(dfr) throw(ArgumentError("creating new columns in a DataFrameRow that subsets " * "columns of its parent data frame is disallowed")) @@ -273,7 +273,7 @@ Base.@propagate_inbounds function Base.setindex!(dfr::DataFrameRow, value, idx) newcol = similar(val, Union{T,Missing}, nrow(parent(dfr))) fill!(newcol, missing) newcol[row(dfr)] = val - parent(dfr)[!, colinds] = newcol + parent(dfr)[!, idx] = newcol else setindex!(parent(dfr), value, row(dfr), parentcols(index(dfr), idx)) end From eccd0b453a1daa721b63e671507828959f029bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Sun, 22 Oct 2023 22:29:27 +0200 Subject: [PATCH 3/4] Update src/dataframerow/dataframerow.jl Co-authored-by: Milan Bouchet-Valat --- src/dataframerow/dataframerow.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dataframerow/dataframerow.jl b/src/dataframerow/dataframerow.jl index 5107c8b6a..9741d4794 100644 --- a/src/dataframerow/dataframerow.jl +++ b/src/dataframerow/dataframerow.jl @@ -281,7 +281,7 @@ Base.@propagate_inbounds function Base.setindex!(dfr::DataFrameRow, value, idx) end insertcols(dfr::DataFrameRow, args...; - after::Bool=false, makeunique::Bool=false, copycols::Bool=true) = + after::Bool=false, makeunique::Bool=false, copycols::Bool=true) = throw(ArgumentError("insertcols is not supported for DataFrameRow. " * "Maybe you wanted to use insertcols!?")) From a141a7117dae2972eeebe098d0353074a67d0cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Sun, 22 Oct 2023 22:40:22 +0200 Subject: [PATCH 4/4] avoid repeated index call --- src/dataframerow/dataframerow.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dataframerow/dataframerow.jl b/src/dataframerow/dataframerow.jl index 5107c8b6a..125ae1007 100644 --- a/src/dataframerow/dataframerow.jl +++ b/src/dataframerow/dataframerow.jl @@ -264,7 +264,7 @@ index(r::DataFrameRow) = getfield(r, :colindex) is_column_insertion_allowed(dfr::DataFrameRow) = index(dfr) isa Index Base.@propagate_inbounds function Base.setindex!(dfr::DataFrameRow, value, idx) - if idx isa SymbolOrString && columnindex(dfr, idx) == 0 + if idx isa SymbolOrString && (int_idx = columnindex(dfr, idx)) == 0 if !is_column_insertion_allowed(dfr) throw(ArgumentError("creating new columns in a DataFrameRow that subsets " * "columns of its parent data frame is disallowed")) @@ -273,7 +273,7 @@ Base.@propagate_inbounds function Base.setindex!(dfr::DataFrameRow, value, idx) newcol = similar(val, Union{T,Missing}, nrow(parent(dfr))) fill!(newcol, missing) newcol[row(dfr)] = val - parent(dfr)[!, idx] = newcol + parent(dfr)[!, int_idx] = newcol else setindex!(parent(dfr), value, row(dfr), parentcols(index(dfr), idx)) end