Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow to pass a reference to where to add a column by its name #2365

Merged
merged 8 commits into from
Aug 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
25 changes: 14 additions & 11 deletions src/dataframe/dataframe.jl
Original file line number Diff line number Diff line change
Expand Up @@ -603,18 +603,20 @@ end
##############################################################################

"""
insertcols!(df::DataFrame, [ind::Int], (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 `ind` 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
- `ind` : a position at which we want to insert a column
- `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.
Expand All @@ -623,7 +625,7 @@ If `ind` 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
Expand Down Expand Up @@ -655,8 +657,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, col::ColumnIndex, name_cols::Pair{Symbol,<:Any}...;
makeunique::Bool=false, copycols::Bool=true)
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"))
Expand Down Expand Up @@ -744,9 +747,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, col::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, col, (Symbol(n) => v for (n,v) in name_cols)...,
makeunique=makeunique, copycols=copycols)

insertcols!(df::DataFrame, name_cols::Pair{Symbol,<:Any}...;
Expand All @@ -758,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, col_ind::Int=ncol(df)+1; makeunique::Bool=false, name_cols...)
if !(0 < col_ind <= 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 $col_ind"))
"$(ncol(df)) columns at index $col"))
end
if !isempty(name_cols)
# an explicit error is thrown as keyword argument was supported in the past
Expand Down
8 changes: 8 additions & 0 deletions test/dataframe.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down