Skip to content

Commit

Permalink
Improve rename API
Browse files Browse the repository at this point in the history
Using pairs is more convenient, more flexible and more consistent.
  • Loading branch information
nalimilan committed Oct 27, 2017
1 parent 902e131 commit 8e1dcb6
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 24 deletions.
4 changes: 2 additions & 2 deletions docs/src/man/joins.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ In order to join data tables on keys which have different names, you must first
```julia
a = DataFrame(ID = [20, 40], Name = ["John Doe", "Jane Doe"])
b = DataFrame(IDNew = [20, 40], Job = ["Lawyer", "Doctor"])
rename!(b, :IDNew, :ID)
rename!(b, :IDNew => :ID)
join(a, b, on = :ID, kind = :inner)
```

Expand All @@ -69,6 +69,6 @@ a = DataFrame(City = ["Amsterdam", "London", "London", "New York", "New York"],
b = DataFrame(Location = ["Amsterdam", "London", "London", "New York", "New York"],
Work = ["Lawyer", "Lawyer", "Lawyer", "Doctor", "Doctor"],
Name = ["a", "b", "c", "d", "e"])
rename!(b, [:Location => :City, :Work => :Job])
rename!(b, :Location => :City, :Work => :Job)
join(a, b, on = [:City, :Job])
```
30 changes: 19 additions & 11 deletions src/abstractdataframe/abstractdataframe.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,28 +138,35 @@ function rename!(df::AbstractDataFrame, args...)
rename!(index(df), args...)
return df
end
rename!(f::Function, df::AbstractDataFrame) = rename!(df, f)
function rename!(f::Function, df::AbstractDataFrame)
rename!(f, index(df))
return df
end

rename(df::AbstractDataFrame, args...) = rename!(copy(df), args...)
rename(f::Function, df::AbstractDataFrame) = rename(df, f)
rename(f::Function, df::AbstractDataFrame) = rename!(f, copy(df))

"""
Rename columns
```julia
rename!(df::AbstractDataFrame, from::Symbol, to::Symbol)
rename!(df::AbstractDataFrame, d::Associative)
rename!(df::AbstractDataFrame, (from => to)::Pair{Symbol, Symbol}...)
rename!(df::AbstractDataFrame, d::Associative{Symbol,Symbol})
rename!(df::AbstractDataFrame, d::AbstractArray{Pair{Symbol,Symbol}})
rename!(f::Function, df::AbstractDataFrame)
rename(df::AbstractDataFrame, from::Symbol, to::Symbol)
rename(df::AbstractDataFrame, (from => to)::Pair{Symbol, Symbol}...)
rename(df::AbstractDataFrame, d::Associative{Symbol,Symbol})
rename(df::AbstractDataFrame, d::AbstractArray{Pair{Symbol,Symbol}})
rename(f::Function, df::AbstractDataFrame)
```
**Arguments**
* `df` : the AbstractDataFrame
* `d` : an Associative type that maps the original name to a new name
* `f` : a function that has the old column name (a symbol) as input
and new column name (a symbol) as output
* `d` : an Associative type or an AbstractArray of pairs that maps
the original names to new names
* `f` : a function which for each column takes the old name (a Symbol)
and returns the new name (a Symbol)
**Result**
Expand All @@ -169,10 +176,11 @@ rename(f::Function, df::AbstractDataFrame)
```julia
df = DataFrame(i = 1:10, x = rand(10), y = rand(["a", "b", "c"], 10))
rename(df, :i => :A, :x => :X)
rename(df, [:i => :A, :x => :X])
rename(df, Dict(:i => :A, :x => :X))
rename(x -> Symbol(uppercase(string(x))), df)
rename(df, Dict(:i=>:A, :x=>:X))
rename(df, :y, :Y)
rename!(df, Dict(:i=>:A, :x=>:X))
rename!(df, Dict(:i =>: A, :x => :X))
```
"""
Expand Down
7 changes: 7 additions & 0 deletions src/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1267,3 +1267,10 @@ macro tsv_str(s, flags...)
:tsv_str)
inlinetable(s, flags...; separator='\t')
end

@deprecate rename!(x::AbstractDataFrame, from::AbstractArray, to::AbstractArray) rename!(x, [f=>t for (f, t) in zip(from, to)])
@deprecate rename!(x::AbstractDataFrame, from::Symbol, to::Symbol) rename!(x, from => to)
@deprecate rename!(x::Index, f::Function) rename!(f, x)
@deprecate rename(x::AbstractDataFrame, from::AbstractArray, to::AbstractArray) rename(x, [f=>t for (f, t) in zip(from, to)])
@deprecate rename(x::AbstractDataFrame, from::Symbol, to::Symbol) rename(x, from => to)
@deprecate rename(x::Index, f::Function) rename(f, x)
8 changes: 3 additions & 5 deletions src/other/index.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,11 @@ function rename!(x::Index, nms)
return x
end

rename!(x::Index, from, to) = rename!(x, zip(from, to))
rename!(x::Index, from::Symbol, to::Symbol) = rename!(x, ((from, to),))
rename!(x::Index, f::Function) = rename!(x, [(x,f(x)) for x in x.names])
rename!(f::Function, x::Index) = rename!(x, f)
rename!(x::Index, nms::Pair{Symbol,Symbol}...) = rename!(x::Index, collect(nms))
rename!(f::Function, x::Index) = rename!(x, [(x=>f(x)) for x in x.names])

rename(x::Index, args...) = rename!(copy(x), args...)
rename(f::Function, x::Index) = rename(x, f)
rename(f::Function, x::Index) = rename!(f, copy(x))

Base.haskey(x::Index, key::Symbol) = haskey(x.lookup, key)
Base.haskey(x::Index, key::Real) = 1 <= key <= length(x.names)
Expand Down
21 changes: 19 additions & 2 deletions test/dataframe.jl
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,27 @@ module TestDataFrame

@testset "rename" begin
df = DataFrame(A = 1:3, B = 'A':'C')
@test names(rename(df, :A, :A_1)) == [:A_1, :B]
@test names(rename(df, :A => :A_1)) == [:A_1, :B]
@test names(df) == [:A, :B]
@test names(rename!(df, :A, :A_1)) == [:A_1, :B]
@test names(rename(df, :A => :A_1, :B => :B_1)) == [:A_1, :B_1]
@test names(df) == [:A, :B]
@test names(rename(df, [:A => :A_1, :B => :B_1])) == [:A_1, :B_1]
@test names(df) == [:A, :B]
@test names(rename(df, Dict(:A => :A_1, :B => :B_1))) == [:A_1, :B_1]
@test names(df) == [:A, :B]
@test names(rename(x->Symbol(lowercase(string(x))), df)) == [:a, :b]
@test names(df) == [:A, :B]

@test rename!(df, :A => :A_1) === df
@test names(df) == [:A_1, :B]
@test rename!(df, :A_1 => :A_2, :B => :B_2) === df
@test names(df) == [:A_2, :B_2]
@test rename!(df, [:A_2 => :A_3, :B_2 => :B_3]) === df
@test names(df) == [:A_3, :B_3]
@test rename!(df, Dict(:A_3 => :A_4, :B_3 => :B_4)) === df
@test names(df) == [:A_4, :B_4]
@test rename!(x->Symbol(lowercase(string(x))), df) === df
@test names(df) == [:a_4, :b_4]
end

@testset "size" begin
Expand Down
8 changes: 4 additions & 4 deletions test/index.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ end
@test_throws ArgumentError names!(i, [:a,:a])
@test names!(i, [:a,:b]) == Index([:a,:b])
@test rename(i, Dict(:a=>:A, :b=>:B)) == Index([:A,:B])
@test rename(i, :a, :A) == Index([:A,:b])
@test rename(i, :a, :a) == Index([:a,:b])
@test rename(i, [:a], [:A]) == Index([:A,:b])
@test rename(i, [:a], [:a]) == Index([:a,:b])
@test rename(i, :a => :A) == Index([:A,:b])
@test rename(i, :a => :a) == Index([:a,:b])
@test rename(i, [:a => :A]) == Index([:A,:b])
@test rename(i, [:a => :a]) == Index([:a,:b])
@test rename(x->Symbol(uppercase(string(x))), i) == Index([:A,:B])
@test rename(x->Symbol(lowercase(string(x))), i) == Index([:a,:b])

Expand Down

0 comments on commit 8e1dcb6

Please sign in to comment.