cbsteh
cbsteh

Reputation: 889

Transform dataframe columns using column selector (Cols) fails

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

Answers (1)

Bogumił Kamiński
Bogumił Kamiński

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

Related Questions