Reputation: 889
I am wondering why I cannot use the Cols
column selector in transform
to change a dataframe column. For instance:
df = DataFrame(x = 1:5, y = 6:10)
transform(df, [:x, :y] .=> v -> v .+ 100) # OK
df[!, Cols(1:2)] .= df[!, Cols(1:2)] .+ 100 # OK
transform(df, Cols(1:2) .=> v -> v .+ 100) # MethodError: no method matching length(::Cols{Tuple{UnitRange{Int64}}})
I've read in the DataFrames
documentation that says column selectors such as Cols
, Between
, Not
, and All
can be used in transform
, among others, but yet I get this error.
Thanks for any pointers.
Upvotes: 3
Views: 166
Reputation: 69819
These selectors can be used when they are passed to transform
directly. Here you are using broadcasting with .=>
(note the dot), so you are not passing them directly to transform
, but instead try pass the following:
julia> Cols(1:2) .=> v -> v .+ 100
ERROR: MethodError: no method matching length(::Cols{Tuple{UnitRange{Int64}}})
The error you observe is not emitted by DataFrames.jl but by Julia base.
What you need to do is to use names
to make things work:
julia> names(df, Cols(1:2)) .=> v -> v .+ 100
2-element Vector{Pair{String, var"#7#8"}}:
"x" => var"#7#8"()
"y" => var"#7#8"()
and in consequence the following works:
transform(df, names(df, Cols(1:2)) .=> v -> v .+ 100)
In the future the functionality you request might be added but it requires changes in DataAPI.jl, see here.
EDIT
As signaled in the original answer in DataFrames.jl 1.3 the functionality has been added and now you can do transform(df, Cols(1:2) .=> v -> v .+ 100)
without error. See https://bkamins.github.io/julialang/2021/12/17/selectors.html for an explanation how it works now.
Upvotes: 3