I'm struggling to use {tidyselect} for (what I think is) a simple pattern: I'd like to apply a transformation to any column who's name ends with "_id" or is named "id" itself. The input dataframes may or may not have columns meeting this requirement.
When only concerned with the "_id" requirement, it's easy:
df %>% mutate(
across(ends_with("_id"), myfun)
)
And if the table does include an "id" column, then this works, too:
But the "id" column is sometimes-present-sometimes-missing. I can pretty easily solve for this with some basic conditionals and inspecting the colnames directly, but I was naïvely hoping this (any_of()) would work (it does not):
you can use logical operators to combine conditions & and | or .
Use any_of just for vectors you want some of , the ends_with requirement can be separate
example:
library(tidyverse)
#works
head(iris) %>% mutate(
across(any_of(c("Species")) | ends_with("Length") , ~"x")
)
# species x is not there but because its conditional it doesnt matter
head(iris) %>% mutate(
across(any_of(c("Speciesx")) | ends_with("Length") , ~"x")
)
@nirgrahamuk aaaahh, I'd messed up my testing with the | operator by placing it withinany_of() (and thus it was instead evaluated as the logical operator) .
In looking at that solution I do think it'd be nice (read: intuitive) to wrap all acceptable patterns by a single any_of() -- as that's what we want: "any of these to match". But I also now see the nuance in the docs on any_of() and all_of() taking character args only.