Reputation: 411
I have an example df:
df <- data.frame(
Date1 = as.Date(c("2010-09-10", "2015-12-03")),
Date2 = as.Date(c("2012-09-10", "2016-12-03")),
Selected = c("Date1", "Date1, Date2"),
Value = c("2010-09-10", "2015-12-03, 2016-12-03"))
Date1 Date2 Selected Value
1 2010-09-10 2012-09-10 Date1 2010-09-10
2 2015-12-03 2016-12-03 Date1, Date2 2015-12-03, 2016-12-03
and I want to be able to create/mutate the new column 'Value' that evaluates whatever column names are in the 'Selected' column. I could use get() if the string in 'Selected' was just a single column name but it could be a concatenation of variable names separated by a comma which is where I'm stuck on how to evaluate.
Upvotes: 1
Views: 96
Reputation: 25313
A possible solution, based on tidyverse
:
library(tidyverse)
df %>%
separate_rows(Selected, sep = ",\\s*") %>%
rowwise %>%
mutate(Value = cur_data()[[Selected]]) %>%
group_by(Date1, Date2) %>%
summarise(Selected = str_c(Selected, collapse = ", "),
Value = str_c(Value, collapse = ", "), .groups = "drop")
#> # A tibble: 2 × 4
#> Date1 Date2 Selected Value
#> <date> <date> <chr> <chr>
#> 1 2010-09-10 2012-09-10 Date1 2010-09-10
#> 2 2015-12-03 2016-12-03 Date1, Date2 2015-12-03, 2016-12-03
A more succinct one:
library(tidyverse)
df %>%
rowwise %>%
mutate(Value = map(str_split(Selected, ", "), ~ cur_data()[.x]),
Value = reduce(Value, c) %>% str_c(collapse=", ")) %>%
ungroup
#> # A tibble: 2 × 4
#> Date1 Date2 Selected Value
#> <date> <date> <chr> <chr>
#> 1 2010-09-10 2012-09-10 Date1 2010-09-10
#> 2 2015-12-03 2016-12-03 Date1, Date2 2015-12-03, 2016-12-03
Upvotes: 1
Reputation: 269371
1) For each word in Selected get that column name and replace the name in the string with the value of that column in the same row using gsubfn. gsubfn is like gsub except the replacement string can be a replacement function to which the match to the capture group in the regex (the part in parentheses) in the pattern is input and replaced with the output of the function. The function can be specified using formula notation as we do here.
library(dplyr)
library(gsubfn)
df %>%
rowwise %>%
mutate(Value=gsubfn("(\\w+)", ~ format(get(x)), Selected)) %>%
ungroup
## # A tibble: 2 x 4
## Date1 Date2 Selected Value
## <date> <date> <chr> <chr>
## 1 2010-09-10 2012-09-10 Date1 2010-09-10
## 2 2015-12-03 2016-12-03 Date1, Date2 2015-12-03, 2016-12-03
2) This can also be done using just gsubfn.
library(gsubfn)
nr <- nrow(df)
df |>
by(1:nr, transform, Value = gsubfn("(\\w+)", ~ format(get(x)), Selected)) |>
do.call(what = "rbind")
## Date1 Date2 Selected Value
## 1 2010-09-10 2012-09-10 Date1 2010-09-10
## 2 2015-12-03 2016-12-03 Date1, Date2 2015-12-03, 2016-12-03
Upvotes: 2
Reputation: 5481
You can do in base
R:
columns <- strsplit(df$Selected, ", ")
df$Value <- sapply(1:nrow(df), function(n) paste(format(df[n, columns[[n]]]), collapse = ", "))
Upvotes: 4