Home > front end >  Calling/passing variables from a function to function
Calling/passing variables from a function to function

Time:10-01

I'm trying to call some variable names using rlang and tidyselect from f1() to f2(). But it doesn't print.

library(rlang)
library(dplyr)
library(R.utils)
library(tidyselect)

db <- tibble(
  D = as.factor(rbinom(10, size=1, p=0.7)),
  X1 = 10*rnorm(10),
  CRT1 = 15*rnorm(10),
  CRT2 = 12*rnorm(10))


f1 <- function(data, varname){
  #Can I use in this function `tidyselect` syntax Like f2()? 
  
  varname = enquo(varname)
  sdf <- data %>%
    group_by(D) %>%  ### ---- D variable called in f2()
    summarise(a = mean(!!varname), 
              b = sd(!!varname), .groups = "drop")

  list(evl = (sum(sdf$b) > 0), df = data)
}

f2 <- function(data, controls){
  
  controls = enexpr(controls)
  cols <- tidyselect::eval_select(controls, data)
  col_nms <- names(cols)
  
  res = f1(data, X1) ### ---- X1 variable called in f2()
  if (res$evl) {
    data = res$df
    printf("The variable calculated is %s
and the variable grouped %s \n\n", names(data$X1), names(data$D))
  }
  
  for (i in col_nms) {
    printf("The control variable is %s,grouped by %s, and calulated by %s \n", i, names(data$D), names(data$X1))
  }
  
  
}


f2(db, controls = c("CRT1", "CRT2"))
#> 

Other question: Can I use in f1 function tidyselect syntax like f2()?

Edit

I need print variable names/values using the output from f1().

f2 <- function(data, controls){
  
  controls = enexpr(controls)
  cols <- tidyselect::eval_select(controls, data)
  col_nms <- names(cols)
  
  res = f1(data, X1) ### ---- X1 variable called on f2()
  if (res$evl) {
    data = res$df
    printf("The variable calculated is %s
and the variable grouped %s \n\n", names(data$X1), names(data$D))
  }
  
  for (i in col_nms) {
    printf("The control variable is %s,grouped by %s, and calulated by %s.
The first value of %s is %f \n", 
           i, names(data$D), names(data$X1), names(data$D), data[1,2])
  }
  
}

What I need (output)

#The variable calculated is X1
#and the variable grouped D
#
#The control variable is CRT1, grouped by D and calulated by X1. The first value of D is 21.6.
#The control variable is CRT2 grouped by D and calulated by X1 The first value of D is 21.6

CodePudding user response:

Since both X1 and D are hardcoded into your function, there's no reason to do something more elaborate than using those strings. I changed a couple things here and there too:

f1 <- function(data, varname){
  #Can I use in this function `tidyselect` syntax Like f2()? 
  

  sdf <- data %>%
    group_by(D) %>%  ### ---- D variable called in f2()
    summarise(a = mean({{varname}}), 
              b = sd({{varname}}), .groups = "drop")
  
  list(evl = (sum(sdf$b) > 0), df = data)
}

f2 <- function(data, controls){
  
  
  cols <- data %>% select({{controls}})
  col_nms <- names(cols)
  print(col_nms)
  
  res = f1(data, X1) ### ---- X1 variable called in f2()

  if (res$evl) {
    data = res$df
    data
    printf("The variable calculated is %s
and the variable grouped %s \n\n", 'X1', 'D')
  }
  
  for (i in col_nms) {
    printf("The control variable is %s,grouped by %s, and calulated by %s \n", i, 'D', 'X1')
  }
  
  
}

If you need something more abstract, please edit your example accordingly

Output:

The variable calculated is X1
and the variable grouped D 

The control variable is CRT1,grouped by D, and calulated by X1 
The control variable is CRT2,grouped by D, and calulated by X1 
  • Related