Edwin
Edwin

Reputation: 3242

dplyr v.0.6.0 standard evaluation mutate

I am trying to figure out the new implementation of standard evaluation in dplyr v.0.6.0. I have worked my way through the vignette, but I am still struggling when building an expression to be evaluated in mutate.

Say I want to make a function that adds a dummy to a x for each row where var is equal to some value. It should work at both NA values and regular values.

library(dplyr)
make_dummy_at_value <- function(x, var, value) {
  var_e <- enquo(var)
  value_e <- enquo(value)
  if (is.na(value)) {
    x <- x %>% mutate(dum = as.numeric(is.na(!!var_e)))
  } else {
    x <- x %>% mutate(dum = as.numeric(!!var_e == !!value_e))
  }
  return(x)
}

Now the following works fine

x <- data.frame(some_var = c(NA, 2))
make_dummy_at_value(x, some_var, NA)

However, this does not

make_dummy_at_value(x, some_var, 2)

I guess we can only put one unquoted expression in the mutate statement, but how to implement it then?

Cheers

Upvotes: 1

Views: 79

Answers (1)

akrun
akrun

Reputation: 887138

The value doesn't need any enquo as it is a numeric element and not a quoted string. Also, it is not a column. It can be directly used within the mutate/summarise

 make_dummy_at_value <- function(x, var, value) {
  var_e <- enquo(var)

  if (is.na(value)) {
    x %>% 
       mutate(dum = as.numeric(is.na(!!var_e)))
  } else {
     x %>% 
        mutate(dum = as.numeric((!!var_e) == value & !is.na(!!var_e) ))
  }

}



make_dummy_at_value(x, some_var, 2)
#  some_var dum
#1       NA   0
#2        2   1
make_dummy_at_value(x, some_var, NA)
#  some_var dum
#1       NA   1
#2        2   0

make_dummy_at_value(x, some_var, 3)
#  some_var dum
#1       NA   0
#2        2   0

If the intention is to pass numeric as well as string for 'value', then

make_dummy_at_value <- function(x, var, value) {
  var_e <- enquo(var)
   value <- enquo(value)
   value_e <- quo_name(value)

  if (is.na(value_e)) {
    x %>% 
       mutate(dum = as.numeric(is.na(!!var_e)))
  } else {
     x %>% 
        mutate(dum = as.numeric((!!var_e) == value_e & !is.na(!!var_e) ))
  }

}

make_dummy_at_value(x, some_var, 2)
#  some_var dum
#1       NA   0
#2        2   1
make_dummy_at_value(x, some_var, NA)
#  some_var dum
#1       NA   1
#2        2   0
make_dummy_at_value(x, some_var, v1)
#  some_var dum
#1       NA   0
#2        2   0

Using another example

x1 <- data.frame(col1 = c(NA, 4, 5), col2 = c('A', NA, 'B'), stringsAsFactors= FALSE)
make_dummy_at_value(x1, col1, NA)
#  col1 col2 dum
#1   NA    A   1
#2    4 <NA>   0
#3    5    B   0
make_dummy_at_value(x1, col2, NA)
#  col1 col2 dum
#1   NA    A   0
#2    4 <NA>   1
#3    5    B   0
make_dummy_at_value(x1, col2, A)
#  col1 col2 dum
#1   NA    A   1
#2    4 <NA>   0
#3    5    B   0

Upvotes: 1

Related Questions