I have the following dataframe:
df <- data.frame(ID=1:3, col1=1:3, col2=4:6, col3=7:9, col4=10:12, col5=13:15, col6=16:18, col7=19:21)
I need to create a function that essentially does the following:
df_new <- df %>% select(ID, c(col1:col5)) %>% mutate(col1=col1/col2, col3=col3/col2, col4=-col4, col5=-col5)
With the result:
> df_new
ID col1 col2 col3 col4 col5
1 1 0.25 4 1.75 -10 -13
2 2 0.40 5 1.60 -11 -14
3 3 0.50 6 1.50 -12 -15
I write a function to do this:
genUIR_test = function(df, arg1, arg2, arg3, arg4, arg5){
arg1 <- substitute(arg1)
arg2 <- substitute(arg2)
arg3 <- substitute(arg3)
arg4 <- substitute(arg4)
arg5 <- substitute(arg5)
df_new = df %>% select(ID, c(arg1:arg5)) %>%
mutate(arg1=arg1/arg2, arg3=arg3/arg2, arg4=-arg4, arg5=-arg5)
return(df_new)
}
And when I run the function, I get the following error:
> genUIR_test(df, col1, col2, col3, col4, col5)
Error in `mutate()`:
ℹ In argument: `arg1 = arg1/arg2`.
Caused by error in `arg1 / arg2`:
! non-numeric argument to binary operator
Run `rlang::last_trace()` to see where the error occurred.
Can you please tell me what I am doing wrong? Thanks.
substitute
is the base R way of non-standard evaluation, the tidyverse
way is with {{
.
And to assign to names passed as arguments to a mutate
statement, use :=
.
suppressPackageStartupMessages({
library(dplyr)
})
genUIR_test <- function(df, arg1, arg2, arg3, arg4, arg5){
df_new <- df %>%
select(ID, {{arg1}}:{{arg5}}) %>%
mutate(
{{arg1}} := {{arg1}} / {{arg2}},
{{arg3}} := {{arg3}} / {{arg2}},
{{arg4}} := -{{arg4}},
{{arg5}} := -{{arg5}}
)
df_new
}
df <- data.frame(
ID=1:3,
col1=1:3, col2=4:6, col3=7:9,
col4=10:12, col5=13:15, col6=16:18,
col7=19:21
)
genUIR_test(df, col1, col2, col3, col4, col5)
#> ID col1 col2 col3 col4 col5
#> 1 1 0.25 4 1.75 -10 -13
#> 2 2 0.40 5 1.60 -11 -14
#> 3 3 0.50 6 1.50 -12 -15
Created on 2025-07-12 with reprex v2.1.1