From a82b7b3660ba090a5c03adc5175de1298ea8d596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Thu, 13 Aug 2020 00:37:03 +0200 Subject: [PATCH 1/6] allow to pass a reference to where to add a column by its name --- src/dataframe/dataframe.jl | 18 ++++++++++-------- test/dataframe.jl | 8 ++++++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/dataframe/dataframe.jl b/src/dataframe/dataframe.jl index 6bd1b59343..c67fa2d97e 100644 --- a/src/dataframe/dataframe.jl +++ b/src/dataframe/dataframe.jl @@ -603,7 +603,7 @@ end ############################################################################## """ - insertcols!(df::DataFrame, [ind::Int], (name=>col)::Pair...; + insertcols!(df::DataFrame, [ref::Int], (name=>col)::Pair...; makeunique::Bool=false, copycols::Bool=true) Insert a column into a data frame in place. Return the updated `DataFrame`. @@ -612,7 +612,8 @@ If `ind` is omitted it is set to `ncol(df)+1` # Arguments - `df` : the DataFrame to which we want to add columns -- `ind` : a position at which we want to insert a column +- `ref` : a position at which we want to insert a column, passed as an integer + or a column name (a string or a `Symbol`) - `name` : the name of the new column - `col` : an `AbstractVector` giving the contents of the new column or a value of any type other than `AbstractArray` which will be repeated to fill a new vector; @@ -655,8 +656,9 @@ julia> insertcols!(d, 2, :c => 2:4, :c => 3:5, makeunique=true) │ 3 │ 'c' │ 4 │ 5 │ 3 │ ``` """ -function insertcols!(df::DataFrame, col_ind::Int, name_cols::Pair{Symbol,<:Any}...; +function insertcols!(df::DataFrame, ref::ColumnIndex, name_cols::Pair{Symbol,<:Any}...; makeunique::Bool=false, copycols::Bool=true) + col_ind = Int(ref isa SymbolOrString ? columnindex(df, ref) : ref) if !(0 < col_ind <= ncol(df) + 1) throw(ArgumentError("attempt to insert a column to a data frame with " * "$(ncol(df)) columns at index $col_ind")) @@ -744,9 +746,9 @@ function insertcols!(df::DataFrame, col_ind::Int, name_cols::Pair{Symbol,<:Any}. return df end -insertcols!(df::DataFrame, col_ind::Int, name_cols::Pair{<:AbstractString,<:Any}...; +insertcols!(df::DataFrame, ref::ColumnIndex, name_cols::Pair{<:AbstractString,<:Any}...; makeunique::Bool=false, copycols::Bool=true) = - insertcols!(df, col_ind, (Symbol(n) => v for (n,v) in name_cols)..., + insertcols!(df, ref, (Symbol(n) => v for (n,v) in name_cols)..., makeunique=makeunique, copycols=copycols) insertcols!(df::DataFrame, name_cols::Pair{Symbol,<:Any}...; @@ -758,10 +760,10 @@ insertcols!(df::DataFrame, name_cols::Pair{<:AbstractString,<:Any}...; insertcols!(df, (Symbol(n) => v for (n,v) in name_cols)..., makeunique=makeunique, copycols=copycols) -function insertcols!(df::DataFrame, col_ind::Int=ncol(df)+1; makeunique::Bool=false, name_cols...) - if !(0 < col_ind <= ncol(df) + 1) +function insertcols!(df::DataFrame, ref::Int=ncol(df)+1; makeunique::Bool=false, name_cols...) + if !(0 < ref <= ncol(df) + 1) throw(ArgumentError("attempt to insert a column to a data frame with " * - "$(ncol(df)) columns at index $col_ind")) + "$(ncol(df)) columns at index $ref")) end if !isempty(name_cols) # an explicit error is thrown as keyword argument was supported in the past diff --git a/test/dataframe.jl b/test/dataframe.jl index f8a6e737a3..82238c42f8 100644 --- a/test/dataframe.jl +++ b/test/dataframe.jl @@ -187,8 +187,16 @@ end df = DataFrame(a=Union{Int, Missing}[1, 2], b=Union{Float64, Missing}[3.0, 4.0]) @test_throws ArgumentError insertcols!(df, 5, :newcol => ["a", "b"]) @test_throws ArgumentError insertcols!(df, 0, :newcol => ["a", "b"]) + @test_throws ArgumentError insertcols!(df, :z, :newcol => ["a", "b"]) + @test_throws ArgumentError insertcols!(df, "z", :newcol => ["a", "b"]) + @test_throws MethodError insertcols!(df, true, :newcol => ["a", "b"]) @test_throws DimensionMismatch insertcols!(df, 1, :newcol => ["a"]) + @test_throws DimensionMismatch insertcols!(df, :a, :newcol => ["a"]) + @test_throws DimensionMismatch insertcols!(df, "a", :newcol => ["a"]) + ref1 = insertcols!(copy(df), :a, :newcol => ["a", "b"]) + ref2 = insertcols!(copy(df), "a", :newcol => ["a", "b"]) @test insertcols!(df, 1, :newcol => ["a", "b"]) == df + @test ref1 == ref2 == df @test names(df) == ["newcol", "a", "b"] @test df.a == [1, 2] @test df.b == [3.0, 4.0] From 8983b497a80460aec154b4280e6062cc4dc492b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Thu, 13 Aug 2020 00:39:10 +0200 Subject: [PATCH 2/6] Update src/dataframe/dataframe.jl --- src/dataframe/dataframe.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dataframe/dataframe.jl b/src/dataframe/dataframe.jl index c67fa2d97e..398e37287b 100644 --- a/src/dataframe/dataframe.jl +++ b/src/dataframe/dataframe.jl @@ -603,7 +603,7 @@ end ############################################################################## """ - insertcols!(df::DataFrame, [ref::Int], (name=>col)::Pair...; + insertcols!(df::DataFrame, [ref], (name=>col)::Pair...; makeunique::Bool=false, copycols::Bool=true) Insert a column into a data frame in place. Return the updated `DataFrame`. From 82a3135f6fa3d9aef47ad1b6140b2f51a6a0872a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Thu, 13 Aug 2020 11:08:37 +0200 Subject: [PATCH 3/6] improve docstring --- src/dataframe/dataframe.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dataframe/dataframe.jl b/src/dataframe/dataframe.jl index c67fa2d97e..bbd14aca23 100644 --- a/src/dataframe/dataframe.jl +++ b/src/dataframe/dataframe.jl @@ -613,7 +613,8 @@ If `ind` is omitted it is set to `ncol(df)+1` # Arguments - `df` : the DataFrame to which we want to add columns - `ref` : a position at which we want to insert a column, passed as an integer - or a column name (a string or a `Symbol`) + or a column name (a string or a `Symbol`); the column selected with `ref` + and columns following it are shifted to the right in `df` after the operation - `name` : the name of the new column - `col` : an `AbstractVector` giving the contents of the new column or a value of any type other than `AbstractArray` which will be repeated to fill a new vector; From 4aefee4a071f1444829fdc9b1cd897b367235c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Thu, 13 Aug 2020 11:11:18 +0200 Subject: [PATCH 4/6] fix ind --- src/dataframe/dataframe.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dataframe/dataframe.jl b/src/dataframe/dataframe.jl index a334379ba6..1f138eaf02 100644 --- a/src/dataframe/dataframe.jl +++ b/src/dataframe/dataframe.jl @@ -607,7 +607,7 @@ end makeunique::Bool=false, copycols::Bool=true) Insert a column into a data frame in place. Return the updated `DataFrame`. -If `ind` is omitted it is set to `ncol(df)+1` +If `ref` is omitted it is set to `ncol(df)+1` (the column is inserted as the last column). # Arguments From f308ba0f136ace5212d74ac39b47e633c599ec34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Wed, 19 Aug 2020 19:38:47 +0200 Subject: [PATCH 5/6] change ref to col and col to val --- src/dataframe/dataframe.jl | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/dataframe/dataframe.jl b/src/dataframe/dataframe.jl index 1f138eaf02..6a0f49266d 100644 --- a/src/dataframe/dataframe.jl +++ b/src/dataframe/dataframe.jl @@ -603,20 +603,20 @@ end ############################################################################## """ - insertcols!(df::DataFrame, [ref], (name=>col)::Pair...; + insertcols!(df::DataFrame, [col], (name=>val)::Pair...; makeunique::Bool=false, copycols::Bool=true) Insert a column into a data frame in place. Return the updated `DataFrame`. -If `ref` is omitted it is set to `ncol(df)+1` +If `col` is omitted it is set to `ncol(df)+1` (the column is inserted as the last column). # Arguments - `df` : the DataFrame to which we want to add columns -- `ref` : a position at which we want to insert a column, passed as an integer - or a column name (a string or a `Symbol`); the column selected with `ref` +- `col` : a position at which we want to insert a column, passed as an integer + or a column name (a string or a `Symbol`); the column selected with `col` and columns following it are shifted to the right in `df` after the operation - `name` : the name of the new column -- `col` : an `AbstractVector` giving the contents of the new column or a value of any +- `val` : an `AbstractVector` giving the contents of the new column or a value of any type other than `AbstractArray` which will be repeated to fill a new vector; As a particular rule a values stored in a `Ref` or a `0`-dimensional `AbstractArray` are unwrapped and treated in the same way. @@ -625,7 +625,7 @@ If `ref` is omitted it is set to `ncol(df)+1` be generated by adding a suffix - `copycols` : whether vectors passed as columns should be copied -If `col` is an `AbstractRange` then the result of `collect(col)` is inserted. +If `val` is an `AbstractRange` then the result of `collect(val)` is inserted. # Examples ```jldoctest @@ -657,9 +657,9 @@ julia> insertcols!(d, 2, :c => 2:4, :c => 3:5, makeunique=true) │ 3 │ 'c' │ 4 │ 5 │ 3 │ ``` """ -function insertcols!(df::DataFrame, ref::ColumnIndex, name_cols::Pair{Symbol,<:Any}...; +function insertcols!(df::DataFrame, col::ColumnIndex, name_cols::Pair{Symbol,<:Any}...; makeunique::Bool=false, copycols::Bool=true) - col_ind = Int(ref isa SymbolOrString ? columnindex(df, ref) : ref) + col_ind = Int(col isa SymbolOrString ? columnindex(df, col) : col) if !(0 < col_ind <= ncol(df) + 1) throw(ArgumentError("attempt to insert a column to a data frame with " * "$(ncol(df)) columns at index $col_ind")) @@ -747,9 +747,9 @@ function insertcols!(df::DataFrame, ref::ColumnIndex, name_cols::Pair{Symbol,<:A return df end -insertcols!(df::DataFrame, ref::ColumnIndex, name_cols::Pair{<:AbstractString,<:Any}...; +insertcols!(df::DataFrame, col::ColumnIndex, name_cols::Pair{<:AbstractString,<:Any}...; makeunique::Bool=false, copycols::Bool=true) = - insertcols!(df, ref, (Symbol(n) => v for (n,v) in name_cols)..., + insertcols!(df, col, (Symbol(n) => v for (n,v) in name_cols)..., makeunique=makeunique, copycols=copycols) insertcols!(df::DataFrame, name_cols::Pair{Symbol,<:Any}...; @@ -761,10 +761,10 @@ insertcols!(df::DataFrame, name_cols::Pair{<:AbstractString,<:Any}...; insertcols!(df, (Symbol(n) => v for (n,v) in name_cols)..., makeunique=makeunique, copycols=copycols) -function insertcols!(df::DataFrame, ref::Int=ncol(df)+1; makeunique::Bool=false, name_cols...) - if !(0 < ref <= ncol(df) + 1) +function insertcols!(df::DataFrame, col::Int=ncol(df)+1; makeunique::Bool=false, name_cols...) + if !(0 < col <= ncol(df) + 1) throw(ArgumentError("attempt to insert a column to a data frame with " * - "$(ncol(df)) columns at index $ref")) + "$(ncol(df)) columns at index $col")) end if !isempty(name_cols) # an explicit error is thrown as keyword argument was supported in the past From 9e5076afcf1bf9949cef83981fbd27c3f7976295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogumi=C5=82=20Kami=C5=84ski?= Date: Wed, 19 Aug 2020 19:40:42 +0200 Subject: [PATCH 6/6] update NEWS.md --- NEWS.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index d2b2211504..ead8651853 100644 --- a/NEWS.md +++ b/NEWS.md @@ -35,7 +35,9 @@ ([#2308](https://github.com/JuliaData/DataFrames.jl/pull/2308)) * allow column renaming in joins ([#2313](https://github.com/JuliaData/DataFrames.jl/pull/2313) - * add `rownumber` to `DataFrameRow` ([#2356](https://github.com/JuliaData/DataFrames.jl/pull/2356)) +* add `rownumber` to `DataFrameRow` ([#2356](https://github.com/JuliaData/DataFrames.jl/pull/2356)) +* allow passing column name to specify the position where a new columns should be + inserted in `insertcols!` ([#2365](https://github.com/JuliaData/DataFrames.jl/pull/2365)) ## Deprecated