Jemc36
Jemc36

Reputation: 11

User-defined function with dplyr - mutate column is a argument

I would like to create a defined function with dplyr in R. But I stuck in passing argument in mutate function. I have two datasets.

data1:

GROUP AGEGRP COUNT
1 0 15
2 1 20

data2:

GROUP COUNT
3 15

My function is

freqcnt <- function(var) {
  var <- enquo(var)
  
  data2 <- data2 %>%
    mutate(!!var = 99)
  
  data1 <- data1 %>%
    rbind(data2) %>%
    return()
} 

When I run the following code,

df <- freqcnt(AGEGRP)

the error message is popped up.

Error: unexpected '=' in:
"    
    mutate(!!var ="

However, if I remove !!, then var will become the name of variable instead of AGEGRP. Please show me some lights. Thanks,

Upvotes: 1

Views: 2146

Answers (2)

www
www

Reputation: 39154

Here is a fix to your function.

library(dplyr)

freqcnt <- function(var){
  
  data2 <- data2 %>%
    mutate({{var}} := 99)

  data1 <- data1 %>%
    rbind(data2)
    
    return(data1)
  
}

freqcnt("AGEGRP")
#   GROUP AGEGRP COUNT
# 1     1      0    15
# 2     2      1    20
# 3     3     99    15

By the way, since you are using dplyr. I suggest you can use the bind_rows function instead of rbind. It can combine data frames with different column names, leaving those unmatched column NA. Below is a function I proposed. You don't need to specify the column names anymore. Furthermore, I design it to be able to take an argument fill as the value to fill in the unmatched columns.

freqcnt2 <- function(fill){
  data1 <- data1 %>%
    bind_rows(data2) %>%
    mutate(across(.fns = function(x) ifelse(is.na(x), fill, x)))
  return(data1)
}

freqcnt2(99)
#   GROUP AGEGRP COUNT
# 1     1      0    15
# 2     2      1    20
# 3     3     99    15

DATA

data1 <- data.frame(GROUP = 1:2,
                    AGEGRP = 0:1,
                    COUNT = c(15,20))

data2 <- data.frame(GROUP = 3, COUNT = 15)

Upvotes: 3

Sirius
Sirius

Reputation: 5429

Isn't this really all you need:

    freqcnt <- function(var) {
        var <- as.character(substitute(var))
        data2[,var] <- 99
        return( rbind( data1, data2 ) )
    }

People have this obsession with tidyversyficationism at times.

Upvotes: 0

Related Questions