Skip to content
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

Using mutate(across()) on vector with named elements uses names rather than element values, WAD? #6754

Closed
ammar-gla opened this issue Feb 23, 2023 · 3 comments · Fixed by #6757
Milestone

Comments

@ammar-gla
Copy link

I have a vector where each value corresponds to a column name, which I pass onto mutate(across()) hoping to transform the existing columns. When the vector elements do not have names, this work correctly, but when I assign names to the elements, the output contains new columns with the intended transformation using the vector names instead.

Is this working as designed? I could not find any documentation explaining this behaviour, but I am also relatively new to R in general.

I found this issue when trying to pass a named vector to unite() which seemed to have problems with the named elements. Not sure whether these issues are connected.

library(dplyr)

# Create vector with named elements
named_vector <- iris[1:2] %>% colnames() %>% setNames(c("length","width"))
not_named_vector <- iris[1:2] %>% colnames()

# Intent: change columns to character
bug_output <- iris %>% mutate(across(all_of(named_vector),as.character)) 
correct_output <- iris %>% mutate(across(all_of(not_named_vector),as.character))

str(bug_output) # Outcome: new character columns are created using element names
str(correct_output) # Correct outcome
@ammar-gla ammar-gla changed the title Using mutate(across()) on vector with named elements uses names rather than element values, WAD? Using mutate(across()) on vector with named elements uses names rather than element values, WAD? Feb 23, 2023
@DavisVaughan
Copy link
Member

It is intentional, it is part of how tidyselection works, like with select():

library(dplyr, warn.conflicts = FALSE)

df <- tibble(a = 1, b = 2, c = 3)

cols <- c("a", "c")
names(cols) <- toupper(cols)

select(df, all_of(cols))
#> # A tibble: 1 × 2
#>       A     C
#>   <dbl> <dbl>
#> 1     1     3

I've added an example of this to the across() docs #6757

We are also going to add examples to the docs of all_of() r-lib/tidyselect#333

@DavisVaughan DavisVaughan added this to the 1.1.1 milestone Feb 23, 2023
@ammar-gla
Copy link
Author

ammar-gla commented Feb 24, 2023

That is good to know, thank you.

To avoid this behaviour, do I need to drop the element names from the vector beforehand, or is there a way to ignore the names when using all_of()?

@DavisVaughan
Copy link
Member

You need to drop the names

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants