Skip to content

Commit

Permalink
wip: implement Rename transform (#15)
Browse files Browse the repository at this point in the history
* wip: implement Rename transform

* wip: implement Rename transform

* fix

* Actually address brought up issues

* refactor and add a pairs of strings constructor

* add tests

* confirm to Tables.jl spec

* assert that all requested renames exist

* update

* make it work with a single Pair, and add test

* Update src/transforms/rename.jl

* Update src/transforms/rename.jl

* Update src/transforms/rename.jl

* Update src/transforms/rename.jl

* Update src/transforms/rename.jl

Co-authored-by: Júlio Hoffimann <[email protected]>
  • Loading branch information
Omar-Elrefaei and juliohm authored Nov 23, 2021
1 parent a6d67c9 commit 97e2d77
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/TableTransforms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export
# built-in
Select,
Reject,
Rename,
Identity,
Center,
Scale,
Expand Down
1 change: 1 addition & 0 deletions src/transforms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ end

include("transforms/identity.jl")
include("transforms/select.jl")
include("transforms/rename.jl")
include("transforms/center.jl")
include("transforms/scale.jl")
include("transforms/zscore.jl")
Expand Down
46 changes: 46 additions & 0 deletions src/transforms/rename.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# ------------------------------------------------------------------
# Licensed under the MIT License. See LICENSE in the project root.
# ------------------------------------------------------------------

"""
Rename(:col₁ => :newcol₁, :col₂ => :newcol₂, ..., :col₁ => :newcolₙ)
The transform that renames `col₁` to `newcol₁`, `col₂` to `newcol₂`, ...
"""
struct Rename <: Stateless
names::Dict{Symbol,Symbol}
end

pairsyms(x::Pair) = Symbol(first(x)) => Symbol(last(x))

Rename(names::Pair) = pairsyms(names) |> Dict |> Rename
Rename(names...) = pairsyms.(names) |> Dict |> Rename

function apply(transform::Rename, table)
_rename(transform.names, table)
end

function revert(transform::Rename, table, cache)
# reversing the key-value pairs of the Dict
newnames = Dict(new => old for (old, new) in transform.names)
_rename(newnames, table) |> first
end


function _rename(names, table)
oldnames = Tables.columnnames(table)

# check if requested renames exist in the table
@assert keys(names) oldnames "invalid column names"

# use new names if necessary
newnames = map(oldnames) do oldname
oldname in keys(names) ? names[oldname] : oldname
end

cols = Tables.columns(table)
vals = [Tables.getcolumn(cols, name) for name in oldnames]
𝒯 = (; zip(newnames, vals)...) |> Tables.materializer(table)

𝒯, nothing
end
53 changes: 53 additions & 0 deletions test/transforms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,59 @@
@test n1 == n2
end

@testset "Rename" begin
a = rand(4000)
b = rand(4000)
c = rand(4000)
d = rand(4000)
t = Table(; a, b, c, d)

T = Rename(Dict(:a => :x))
n, c = apply(T, t)
@test Tables.columnnames(n) == (:x, :b, :c, :d)
tₒ = revert(T, n, c)
@test t == tₒ

T = Rename(Dict(:a => :x, :c => :y))
n, c = apply(T, t)
@test Tables.columnnames(n) == (:x, :b, :y, :d)
tₒ = revert(T, n, c)
@test t == tₒ

# rename with string pairs
T = Rename("a" => "x", "c" => "y")
n, c = apply(T, t)
@test Tables.columnnames(n) == (:x, :b, :y, :d)
tₒ = revert(T, n, c)
@test t == tₒ

# rename with symbol pairs
T = Rename(:a => :x, :c => :y)
n, c = apply(T, t)
@test Tables.columnnames(n) == (:x, :b, :y, :d)
tₒ = revert(T, n, c)
@test t == tₒ

# rename with mixed pairs
T = Rename("a" => :x)
n, c = apply(T, t)
@test Tables.columnnames(n) == (:x, :b, :c, :d)
tₒ = revert(T, n, c)
@test t == tₒ

T = Rename("a" => :x, :c => "y")
n, c = apply(T, t)
@test Tables.columnnames(n) == (:x, :b, :y, :d)
tₒ = revert(T, n, c)
@test t == tₒ

# reapply test
T = Rename(:b => :x, :d => :y)
n1, c1 = apply(T, t)
n2 = reapply(T, t, c1)
@test n1 == n2
end

@testset "Identity" begin
x = rand(4000)
y = rand(4000)
Expand Down

0 comments on commit 97e2d77

Please sign in to comment.