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

Add the @rename macro #204

Closed
metanoid opened this issue Nov 12, 2020 · 9 comments · Fixed by #343
Closed

Add the @rename macro #204

metanoid opened this issue Nov 12, 2020 · 9 comments · Fixed by #343
Milestone

Comments

@metanoid
Copy link

It's not strictly necessary, because DataFrames.rename exists, but it is nice to have the keyword argument form.

@pdeffebach
Copy link
Collaborator

Thanks!

This will be good to add pre 1.0.

@pdeffebach
Copy link
Collaborator

Bumping this. Current struggling to rename something programmatically in dplyr. Would be great to have this in DataFramesMeta.jl

@MatthewRGonzalez
Copy link
Contributor

MatthewRGonzalez commented Oct 2, 2022

@pdeffebach would something silly like this be acceptable?

using DataFrames
using Chain

macro testrename(x, arg)
    esc(testrename_helper(x, (arg)))
end

function testrename_helper(x, arg)
    t = arg
    quote
        $DataFrames.rename($x, $t)
    end
end

df = DataFrame(x=rand(10), y=rand(10))
df[!, Symbol("Y 2")] = randn(10)


@chain df begin
    @testrename [:x, :y] .=> [:apple, :banana]
    @testrename Symbol("Y 2") => :pineapple
end

@MatthewRGonzalez
Copy link
Contributor

Hi, @pdeffebach. I want to bump this to discuss the design. Should the final version of @rename be something like

df(old_col1 = 1:10, old_col2 = 1:10)

@rename(df :new_col = :old_col)

@rename df begin  
     :new_col1 = :old_col1
     :new_col2 = :old_col2
end

Please let me know what you think!

@pdeffebach
Copy link
Collaborator

Yes. I guess rename should allow arbitrary expressions in the RHS so that you can do

@rename df :newcol = begin
    "old_col" * "1"
end

and of course `@rename df $(:x => :y)

@MatthewRGonzalez
Copy link
Contributor

Yes. I guess rename should allow arbitrary expressions in the RHS so that you can do

To make sure I'm understanding this correctly, would the DataFrames version of achieving this be something like

df = DataFrame(a_col = rand(10))
rename(x->x * "1", df)

@pdeffebach
Copy link
Collaborator

No. see the :newcol = ... at the top, it would be equivalent to

rename(df, ("old_col" * "1") => :new_col)

@rename should only ever create a rename(df, a => b, c => d) type-of expression. No need to bother with the function stuff.

@MatthewRGonzalez
Copy link
Contributor

Got it, thanks. I currently have the following:

@rename df :new1 = begin 
    $("old_col" * "1")
end

however, arbitrary RHS expressions need to be escaped. Further, arbitrary RHS expressions can not be mixed with other standard expressions. For example

@rename(df, :new1 = $("old_col" * "1"), :new2 = :old_col2)

errors in the same manner as

rename(df, ("old_col" * "1") => :new1, :old_col2 => :new2)
ERROR: MethodError: no method matching rename!(::DataFrame, ::Vector{Pair{A, Symbol} where A})

Which I think makes sense if this implementation is to rely on rename. Is this sufficient?

@pdeffebach
Copy link
Collaborator

The error above is because all the old names need to be the same type and all the new names need to be the same type. Just cast everything to string in the final expression. i.e., produce

rename(df, string(("old_col" * "1")) => string(:new1), string(:old_col2) => string(:new2))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants