Home > database >  pass string as the argument in function to be used in other function in R
pass string as the argument in function to be used in other function in R

Time:06-11

I have this dataset:

toy <- cbind(ID = c(1:10),
                 group1 = sample(1:3, 10, replace = TRUE), 
                 group2 = sample(1:3, 10, replace = TRUE), 
                 value = rnorm(1:10))


      ID group1 group2       value
 [1,]  1      1      2 -0.32903883
 [2,]  2      3      3  0.06923648
 [3,]  3      1      1  0.09690423
 [4,]  4      1      3  0.29003439
 [5,]  5      3      2 -0.74667894
 [6,]  6      1      2 -0.84689639
 [7,]  7      3      3  1.19707766
 [8,]  8      1      3 -0.54862736
 [9,]  9      2      2  0.30304570
[10,] 10      1      3 -0.05697053

I want to write a function with two arguments: dataframe, focal.var.

the function takes a dataframe, groups it by a group1 and takes the mean of focal.var . I do not know how to pass the column names to mean() function below. I tried this:

focal <- function(dataset, focal.var){
  df <- dataset %>%
    group_by(group1) %>%
    mutate(FV_ft = mean(focal.var))
  return(df)

after calling my function:

focal(dataset = toy, focal.var = "value")

produces this error:

argument is not numeric or logical: returning NA

CodePudding user response:

@rawr is correct. The linked answer shows passing a string containing a column name into group_by. The process is no different when passing the string into summarise:

This is the approach I typically use:

library(dplyr)
focal <- function(dataset, focal.var){
  df <- dataset %>%
    group_by(group1) %>%
    mutate(FV_ft = mean(!!sym(focal.var)))
  return(df)
}

This is an approach recommended by the programming with dplyr vignette:

library(dplyr)
focal <- function(dataset, focal.var){
  df <- dataset %>%
    group_by(group1) %>%
    mutate(FV_ft = mean(.data[[focal.var]]))
  return(df)
}

CodePudding user response:

We could use curly-curly {{}}: And I have added one more argument for the group:

library(dplyr)
library(tibble)
focal <- function(dataset, group, focal.var){
  df <- dataset %>%
    as_tibble() %>% 
    group_by({{group}}) %>%
    mutate(FV_ft = mean({{focal.var}}, na.rm=TRUE))
  return(df)
}

focal(toy, group1, value)  
      ID group1 group2  value  FV_ft
   <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
 1     1      2      1 -0.653  0.160
 2     2      2      3  0.820  0.160
 3     3      2      2  1.48   0.160
 4     4      3      3 -0.929 -0.929
 5     5      2      1 -0.182  0.160
 6     6      2      1  1.00   0.160
 7     7      2      1 -0.852  0.160
 8     8      1      3 -1.72  -0.326
 9     9      2      2 -0.495  0.160
10    10      1      3  1.07  -0.326

CodePudding user response:

Seems like the answer is a one liner:

FV_ft = mean(eval(as.name(focal.var)))
  • Related