Reputation: 517
Tidy eval now supports glue strings
So this works great:
my_summarise5 <- function(data, mean_var ) {
data %>%
mutate(
"mean_{{mean_var}}" := mean({{ mean_var }}),
)
}
mtcars %>% my_summarise5(cyl)
But then
my_summarise5 <- function(data, mean_var ) {
data %>%
mutate(
"mean_{{mean_var}}" := mean({{ mean_var }}),
"mean_{{mean_var}}_plusone" := "mean_{{mean_var}}"+1
)
}
mtcars %>% my_summarise5(cyl)
Throws
Error: Problem with `mutate()` input `mean_cyl_plusone`.
x non-numeric argument to binary
Would some 'paste' or 'glue' thing in the "mean_{{mean_var}}_plusone" := "mean_{{mean_var}}"+1
part fix this?
Note this is obviously not a useful case, its a MWE for the syntax. I actually want to define two new columns with different names, one which uses the other ... otherwise I have to repeat and it also gets messy.
Upvotes: 4
Views: 308
Reputation: 269301
Use across:
my_summarise5 <- function(data, mean_var ) {
data %>%
mutate(
"mean_{{mean_var}}" := mean({{ mean_var }}),
across(last_col(), ~.+1, .names = "{col}_plusone")
)
}
mtcars %>% my_summarise5(cyl) %>% head
giving:
mpg cyl disp hp drat wt qsec vs am gear carb mean_cyl mean_cyl_plusone
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 6.1875 7.1875
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 6.1875 7.1875
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 6.1875 7.1875
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 6.1875 7.1875
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 6.1875 7.1875
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 6.1875 7.1875
Upvotes: 4
Reputation: 2262
I love the tidyverse, but using base R can have a big payoff, by making your code readable and maintainable.
my_summarise5 <- function (data, mean_var) {
mean_name <- paste0("mean_", mean_var)
plus_one_name <- paste0(mean_name, "_plus_one")
data[[mean_name]] <- mean(data[[mean_var]])
data[[plus_one_name]] <- data[[mean_name]] + 1
data
}
Anybody who knows R can understand the above.
tmp <- data.frame(a = 1:5)
my_summarise5(tmp, "a")
## a mean_a mean_a_plus_one
## 1 1 3 4
## 2 2 3 4
## 3 3 3 4
## 4 4 3 4
## 5 5 3 4
If you want to pass a bare symbol as mean_var
, then just add this line to the start of the function:
mean_var <- as.character(substitute(mean_var))
This isn't perfect, because it'll break with deeply nested functions. So you could mix a little tidyverse in by doing (something like) mean_var <- enquo(mean_var)
. But I still would prefer the simple data manipulation to stuff with mutate
and across
.
Upvotes: 1