Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 390
cbsteh Avatar asked Aug 12 '26 14:08

cbsteh


1 Answers

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.

like image 148
Bogumił Kamiński Avatar answered Aug 14 '26 12:08

Bogumił Kamiński



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!