Reputation:
I'd like to pass argument to a function which use dplyr
.
The idea is to transform the data of a specific column (my argument) of a data frame.
Here is an illustrative example:
example = function(x){
df %>%
mutate( paste0(x, '_with_noise') = x + rnorm(n(), 0, 0.01))
}
The problem is I obtain this error message:
> Error: unexpected '=' in: " df %>%
> mutate( paste(x, '_with_noise', sep = '') ="
> > } Error: unexpected '}' in "}"
I also tried to use these but I have the exact same error.
mutate_
instead of mutate
quote()
Upvotes: 0
Views: 1160
Reputation: 206167
Here's how you would use mutate_
.
example = function(x){
tx <- lazyeval::interp(~z+rnorm(n(), 0, 0.01), z=as.name(x))
tn <- paste0(x, '_with_noise')
df %>%
mutate_( .dots=setNames(list(tx), tn))
}
example("a")
example("b")
There are examples of this in the NSE vignette from dplyr (vignette("nse","dplyr")
). This method is safer than pasting arbitrary strings and evaluating the results.
Upvotes: 4
Reputation: 2989
The paste
command doesn't work here within the mutate
, so it is better to assign the name of the variable to an additional variable y
example = function(x){
y <- paste(x, '_with_noise', sep = '')
df %>%
mutate(y = x + rnorm(n(), 0, 0.01))
}
So if your data is
a <- c("A","B","C")
b <- c(2,3,4)
df <- data.frame(a,b)
> df
a b
1 A 2
2 B 3
3 C 4
calling
> example(df$b)
leads to the result
a b y
1 A 2 2.013845
2 B 3 2.998154
3 C 4 3.987750
Upvotes: 0
Reputation: 2584
To make this trick you have to put your entire command into paste
function.
BTW, it's better to use paste0
instead of paste(..., sep = '')
This is a working example.
example = function(x){
y <- as.character(substitute(x))
eval(parse(text = paste0(
"df %>% mutate(", y, "_with_noise =", y, " + rnorm(n(), 0, 0.01) )"
)))
}
set.seed(99)
df <- as.data.frame(matrix(sample(10, 25, T), ncol = 5,
dimnames = list(NULL, letters[1:5]) ))
example(b)
# a b c d e b_with_noise
# 1 6 10 6 7 3 9.996149
# 2 2 7 6 4 1 7.008946
# 3 7 3 2 2 9 2.991608
# 4 10 4 7 1 6 3.995421
# 5 6 2 7 2 8 2.001143
Upvotes: -1