user3904098
user3904098

Reputation:

Pass argument to dplyr

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.

Upvotes: 0

Views: 1160

Answers (3)

MrFlick
MrFlick

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

rmuc8
rmuc8

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

inscaven
inscaven

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

Related Questions