Search code examples
rtidyr

How to include an argument from another function into a new function


I am trying to wrap a function from tidyr into my new function but one argument is being ignored. See example below:

library(tidyr)

one2many2 <- function(data, var) {
  data <- data %>%
    mutate(rows = row_number()) %>%
    uncount(data[, var])
  return(data)
}

a <- data.frame(name = c("Maria", "Tina"), age = c(5, 3))

The variable "age" should be removed automatically because .remove = TRUE is the default. However, "age" is still shown on the final output. How can I include the option to remove or not to remove in my function?

one2many2(a, "age", .remove = TRUE) # remove = TRUE is ignored

Solution

  • .remove works only if weights is the name of a column in data. What you set weights = data[, var] is actually evaluated as a vector of weights (weights = c(5, 3)), instead of the name of a column (weights = age). You should use Embrace operator {{ to transport a data-masked argument.

    library(tidyr)
    
    one2many2 <- function(data, var, ...){
      data %>%
        mutate(rows = row_number()) %>%
        uncount({{ var }}, ...)
    }
    
    one2many2(a, age) # no need to quote "age"
    #    name rows
    # 1 Maria    1
    # 2 Maria    1
    # 3 Maria    1
    # 4 Maria    1
    # 5 Maria    1
    # 6  Tina    2
    # 7  Tina    2
    # 8  Tina    2
    
    one2many2(a, age, .remove = FALSE)
    #    name age rows
    # 1 Maria   5    1
    # 2 Maria   5    1
    # 3 Maria   5    1
    # 4 Maria   5    1
    # 5 Maria   5    1
    # 6  Tina   3    2
    # 7  Tina   3    2
    # 8  Tina   3    2