Reputation: 1040
I have created a user function in R to multiply two columns to create a third (within a series), so this function creates 4 new columns.
create_mult_var <- function(.data){
.data <-.data%>%
mutate(Q4_1_4 = Q4_1_2_TEXT*Q4_1_3_TEXT) %>%
mutate(Q4_2_4 = Q4_2_2_TEXT*Q4_2_3_TEXT) %>%
mutate(Q4_3_4 = Q4_3_2_TEXT*Q4_3_3_TEXT) %>%
mutate(Q4_4_4 = Q4_4_2_TEXT*Q4_4_3_TEXT)
.data
I am trying to modify this function so that I can apply it to a different set of columns that match the same type. For instance, if I want to repeat this on the series of columns that start with "Q8", I know I can do the following:
create_mult_var_2 <- function(.data){
.data <-.data%>%
mutate(Q8_1_4 = Q8_1_2_TEXT*Q8_1_3_TEXT) %>%
mutate(Q8_2_4 = Q8_2_2_TEXT*Q8_2_3_TEXT) %>%
mutate(Q8_3_4 = Q8_3_2_TEXT*Q8_3_3_TEXT) %>%
mutate(Q8_4_4 = Q8_4_2_TEXT*Q8_4_3_TEXT)
.data
}
Instead of creating a different function for each of the Q4 and Q8 series, I would like to add the "Q4" or "Q8" as an argument. I tried this below, but R would not accept this as an argument this way. Is there a way to achieve my desired outcome?
This does not work:
create_mult_var <- function(.data,question){
.data <-.data%>%
mutate(question_1_4 = question_1_2_TEXT*question_1_3_TEXT) %>%
mutate(question_2_4 = question_2_2_TEXT*question_2_3_TEXT) %>%
mutate(question_3_4 = question_3_2_TEXT*question_3_3_TEXT) %>%
mutate(question_4_4 = question_4_2_TEXT*question_4_3_TEXT)
.data
}
I would like to modify the function, such as that I can use the following:
data_in %>% create_mult_var("Q4") %>% create_mult_var("Q8")
Or something similar to create these new columns? Any suggestions are appreciated! Thank you! If this is a bad idea, any suggestions for how I should approach this?
Upvotes: 1
Views: 66
Reputation: 886938
We could use paste
and evaluate with !!
create_mult_var_2 <- function(.data, pat){
.data <-.data%>%
mutate(!! str_c(pat, '_1_4') :=
!! rlang::sym(str_c(pat, '_1_2_TEXT')) *
!! rlang::sym(str_c(pat, '_1_3_TEXT')))
.data
}
create_mult_var_2(data_in, "Q4")
# Q4_1_2_TEXT Q4_1_3_TEXT Q4_1_4
#1 1 5 5
#2 2 6 12
#3 3 7 21
#4 4 8 32
Also, based on the pattern showed, this can be automated as well
library(dplyr)
library(stringr)
create_mult_var_3 <- function(.data, pat) {
.data %>%
mutate(across(matches(str_c("^", pat, "_\\d+_2")), ~
.* get(str_replace(cur_column(), '_2_TEXT', '_3_TEXT')),
.names = '{.col}_new')) %>%
rename_at(vars(ends_with('_new')),
~ str_replace(., '\\d+_TEXT_new', '4'))
}
-testing
create_mult_var_3(data_in, "Q4")
# Q4_1_2_TEXT Q4_1_3_TEXT Q4_1_4
#1 1 5 5
#2 2 6 12
#3 3 7 21
#4 4 8 32
data_in <- data.frame(Q4_1_2_TEXT = 1:4, Q4_1_3_TEXT = 5:8)
Upvotes: 2