Skip to content

Commit 97e2d77

Browse files
wip: implement Rename transform (#15)
* 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 <julio.hoffimann@gmail.com>
1 parent a6d67c9 commit 97e2d77

File tree

4 files changed

+101
-0
lines changed

4 files changed

+101
-0
lines changed

src/TableTransforms.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export
3131
# built-in
3232
Select,
3333
Reject,
34+
Rename,
3435
Identity,
3536
Center,
3637
Scale,

src/transforms.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ end
213213

214214
include("transforms/identity.jl")
215215
include("transforms/select.jl")
216+
include("transforms/rename.jl")
216217
include("transforms/center.jl")
217218
include("transforms/scale.jl")
218219
include("transforms/zscore.jl")

src/transforms/rename.jl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# ------------------------------------------------------------------
2+
# Licensed under the MIT License. See LICENSE in the project root.
3+
# ------------------------------------------------------------------
4+
5+
"""
6+
Rename(:col₁ => :newcol₁, :col₂ => :newcol₂, ..., :col₁ => :newcolₙ)
7+
8+
The transform that renames `col₁` to `newcol₁`, `col₂` to `newcol₂`, ...
9+
"""
10+
struct Rename <: Stateless
11+
names::Dict{Symbol,Symbol}
12+
end
13+
14+
pairsyms(x::Pair) = Symbol(first(x)) => Symbol(last(x))
15+
16+
Rename(names::Pair) = pairsyms(names) |> Dict |> Rename
17+
Rename(names...) = pairsyms.(names) |> Dict |> Rename
18+
19+
function apply(transform::Rename, table)
20+
_rename(transform.names, table)
21+
end
22+
23+
function revert(transform::Rename, table, cache)
24+
# reversing the key-value pairs of the Dict
25+
newnames = Dict(new => old for (old, new) in transform.names)
26+
_rename(newnames, table) |> first
27+
end
28+
29+
30+
function _rename(names, table)
31+
oldnames = Tables.columnnames(table)
32+
33+
# check if requested renames exist in the table
34+
@assert keys(names) oldnames "invalid column names"
35+
36+
# use new names if necessary
37+
newnames = map(oldnames) do oldname
38+
oldname in keys(names) ? names[oldname] : oldname
39+
end
40+
41+
cols = Tables.columns(table)
42+
vals = [Tables.getcolumn(cols, name) for name in oldnames]
43+
𝒯 = (; zip(newnames, vals)...) |> Tables.materializer(table)
44+
45+
𝒯, nothing
46+
end

test/transforms.jl

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,59 @@
131131
@test n1 == n2
132132
end
133133

134+
@testset "Rename" begin
135+
a = rand(4000)
136+
b = rand(4000)
137+
c = rand(4000)
138+
d = rand(4000)
139+
t = Table(; a, b, c, d)
140+
141+
T = Rename(Dict(:a => :x))
142+
n, c = apply(T, t)
143+
@test Tables.columnnames(n) == (:x, :b, :c, :d)
144+
tₒ = revert(T, n, c)
145+
@test t == tₒ
146+
147+
T = Rename(Dict(:a => :x, :c => :y))
148+
n, c = apply(T, t)
149+
@test Tables.columnnames(n) == (:x, :b, :y, :d)
150+
tₒ = revert(T, n, c)
151+
@test t == tₒ
152+
153+
# rename with string pairs
154+
T = Rename("a" => "x", "c" => "y")
155+
n, c = apply(T, t)
156+
@test Tables.columnnames(n) == (:x, :b, :y, :d)
157+
tₒ = revert(T, n, c)
158+
@test t == tₒ
159+
160+
# rename with symbol pairs
161+
T = Rename(:a => :x, :c => :y)
162+
n, c = apply(T, t)
163+
@test Tables.columnnames(n) == (:x, :b, :y, :d)
164+
tₒ = revert(T, n, c)
165+
@test t == tₒ
166+
167+
# rename with mixed pairs
168+
T = Rename("a" => :x)
169+
n, c = apply(T, t)
170+
@test Tables.columnnames(n) == (:x, :b, :c, :d)
171+
tₒ = revert(T, n, c)
172+
@test t == tₒ
173+
174+
T = Rename("a" => :x, :c => "y")
175+
n, c = apply(T, t)
176+
@test Tables.columnnames(n) == (:x, :b, :y, :d)
177+
tₒ = revert(T, n, c)
178+
@test t == tₒ
179+
180+
# reapply test
181+
T = Rename(:b => :x, :d => :y)
182+
n1, c1 = apply(T, t)
183+
n2 = reapply(T, t, c1)
184+
@test n1 == n2
185+
end
186+
134187
@testset "Identity" begin
135188
x = rand(4000)
136189
y = rand(4000)

0 commit comments

Comments
 (0)