-
Notifications
You must be signed in to change notification settings - Fork 370
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
Feature Request: Allow naming function in rename
operation pairs.
#3361
Comments
The question is if this functionality is needed. Currently instead of:
you should write:
Do you think it is that much less convenient? And for a common case of:
It is easier to just write:
@nalimilan - what do you think? |
That syntax makes sense to me now that you've written it, but I probably wouldn't have come up with it on my own. I see now I could also write Also The reason for this issue is that I assumed the below would work based on syntax similarity between julia> df = DataFrame(a=1:3, b=4:6, c=7:9)
3×3 DataFrame
Row │ a b c
│ Int64 Int64 Int64
─────┼─────────────────────
1 │ 1 4 7
2 │ 2 5 8
3 │ 3 6 9
julia> function f(s::Union{String, Symbol})
s = lpad(s, 3, '_')
s = rpad(s, 5, '_')
if contains(s, 'b')
return uppercase(s)
else
return s
end
end
f (generic function with 2 methods)
julia> f(:a)
"__a__"
julia> f(:b)
"__B__"
julia> f(:c)
"__c__"
julia> select(df, :a => :d)
3×1 DataFrame
Row │ d
│ Int64
─────┼───────
1 │ 1
2 │ 2
3 │ 3
julia> rename(df, :a => :d)
3×3 DataFrame
Row │ d b c
│ Int64 Int64 Int64
─────┼─────────────────────
1 │ 1 4 7
2 │ 2 5 8
3 │ 3 6 9
julia> select(df, :a => identity => f)
3×1 DataFrame
Row │ __a__
│ Int64
─────┼───────
1 │ 1
2 │ 2
3 │ 3
julia> rename(df, :a => identity => f)
ERROR: MethodError: no method matching rename!(::DataFrame, ::Vector{Pair{Symbol, Pair{typeof(identity), typeof(f)}}})
julia> rename(df, :a => f) # this method makes more sense than the previous one for `rename`
ERROR: MethodError: no method matching rename!(::DataFrame, ::Vector{Pair{Symbol, typeof(f)}}) This feature would make in-place column name changes with functions easier. |
|
I was thinking about it. What @nathanrboyer wants is Now, apart from a comprehension another way to express what @nathanrboyer wants is:
or equivalently:
I know they are longer. But I am just asking myself if we add these examples to a manual, along with the comprehension This boils down to a question if the pattern @nalimilan - indeed
|
Right, |
Yes, but this is exactly why I am hesitating to add it. Since user (@nathanrboyer as an example) might have a different intuition, and Simply put |
Broadcasting when multiple columns are selected makes sense to me. My intuition is that the This is an excerpt of what I have written in the documentation PR:
I do also have this example later in my documentation PR, but I don't think it needs to be supported by
I do want df = DataFrame(Time = 0.0:0.1:0.3, Temp1 = rand(4), Temp2 = rand(4), Temp3 = rand(4))
function longname(x)
x = string(x)
n = last(x)
if chop(x) == "Temp"
return "Temperature " * n * " (°F)"
else
throw(ArgumentError("unsupported input string"))
end
end
rename!(df, Not(:Time) .=> longname) |
the syntax does kinda make sense to me but I think it should definitely have to be broadcasted (and maybe set a custom error message for when people inevitably attempt to chain a second |
There is potential ambiguity between callable and julia> struct StrFunc <: AbstractString
s
end
julia> ((;s)::StrFunc)(x) = string(s,x)
julia> StrFunc("hello ")("world")
"hello world"
julia> rename(df, :a => StrFunc("hello ")) |
Not realizing that there already is a rename(uppercase, df, :col)
rename(ab->uppercase.(ab), df, [:a, :b])
rename(df, [:a, :b]) do ab
uppercase.(ab)
end |
I like the proposal of @david-macmahon (if it is OK with the other discutants). Then the signature would be:
so the example call would be:
Note that I would make the last argument a keyword. There are two reasons for this:
What do you think? |
I like the consistency with |
I like the keyword argument method; it is probably more functional (by enabling These should all work the same (except which columns are kept): add_prefix(x) = "new_" * x
df = DataFrame(col = 1:3)
transform(df, :col => identity => :new_col)
transform(df, :col => identity => add_prefix)
rename(df, :col => :new_col)
rename(df, :col => add_prefix) # Error That's my whole argument. If the top three methods work, then, to be consistent, the bottom method should work too. I'll leave it now to others to determine what is best to implement. |
In #3380 I have added the I have thought a lot about the other proposal, and I do not think we should add it. I think it is better to keep
should work and how would they work (such things work in |
Okay, thanks for considering. |
The current options for renaming column(s) with a function are below, but these all require care in dealing with the other columns.
I would like the method below added to the
rename
andrename!
functions, so columns can be renamed in-place with a function just like they can with explicit new name(s).It would also work for multiple columns.
There is already a method for applying a function to the entire data frame
rename((s -> s * "_new"), df)
, but I don't think there is currently a way to apply it to only some columns.The text was updated successfully, but these errors were encountered: