tidyr icon indicating copy to clipboard operation
tidyr copied to clipboard

Names attribute in cols for pivot_longer results in "Can't rename variables in this context."

Open JamesHWade opened this issue 2 years ago • 2 comments

After upgrading to v1.3 I noticed, pivot_longer fails when I pass a vector with names attributes to the cols argument. Relevant issues: #1104 and #1160. Looks like #1405 is the breaking change?

I discovered this when trying to create custom tidymodels::recipes steps. Would it be best practice to use as.character(cols) for anything passed to pivot_longer? This may not be enough context, but here is what I was working on if more context might help.

Here is a reprex:

library(tidyr)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(modeldata)
data(meats)

meats_small <- meats |> select(x_001, x_002, x_003, water, protein)

measures <- c("x_001", "x_002", "x_003")
measures_with_names <- measures
names(measures_with_names) <- measures

meats_small |> 
  pivot_longer(
    cols = all_of(measures),
    names_to = "measure",
    values_to = "response"
  )
#> # A tibble: 645 × 4
#>    water protein measure response
#>    <dbl>   <dbl> <chr>      <dbl>
#>  1  60.5    16.7 x_001       2.62
#>  2  60.5    16.7 x_002       2.62
#>  3  60.5    16.7 x_003       2.62
#>  4  46      13.5 x_001       2.83
#>  5  46      13.5 x_002       2.84
#>  6  46      13.5 x_003       2.84
#>  7  71      20.5 x_001       2.58
#>  8  71      20.5 x_002       2.58
#>  9  71      20.5 x_003       2.59
#> 10  72.8    20.7 x_001       2.82
#> # … with 635 more rows

meats_small |> 
  pivot_longer(
    cols = all_of(measures_with_names),
    names_to = "measure",
    values_to = "response"
  )
#> Error in `pivot_longer()`:
#> ! Can't rename variables in this context.

#> Backtrace:
#>      ▆
#>   1. ├─tidyr::pivot_longer(...)
#>   2. └─tidyr:::pivot_longer.data.frame(...)
#>   3.   └─tidyr::build_longer_spec(...)
#>   4.     └─tidyselect::eval_select(...)
#>   5.       └─tidyselect:::eval_select_impl(...)
#>   6.         ├─tidyselect:::with_subscript_errors(...)
#>   7.         │ └─rlang::try_fetch(...)
#>   8.         │   └─base::withCallingHandlers(...)
#>   9.         └─tidyselect:::vars_select_eval(...)
#>  10.           └─tidyselect:::ensure_named(...)
#>  11.             └─cli::cli_abort(...)
#>  12.               └─rlang::abort(...)

Created on 2023-02-02 with reprex v2.0.2

JamesHWade avatar Feb 02 '23 23:02 JamesHWade

was there any fix to this? I'm teaching a stat learning course. I have tidyr v1.2.1 and code is working fine, some new students have 1.3.0 and are getting the can't rename variables in this context error.

jimmyrisk avatar May 09 '23 01:05 jimmyrisk

Just unname the vector you supplied to all_of() using unname()

DavisVaughan avatar May 09 '23 12:05 DavisVaughan

I think this is a case where the error message should be improved in tidyselect https://github.com/r-lib/tidyselect/issues/336

DavisVaughan avatar Jul 27 '24 13:07 DavisVaughan