James
James

Reputation: 589

Defining optional arguments in R when more complex function

I've looked through various postings on this, but haven't found them to be practical for more complex situations when not adding two numbers ("Correct" way to specifiy optional arguments in R functions).

If I wanted to define an optional argument (in my function to select a variable from the dataset), most responses point to doing something like below. However, when you have a longer function, it just seems impractical, and then you're essentially repeating things twice, which is the whole point of using a function in the first place.

select_fun_cars = function(df, var){
  if(missing(var)){
  df%>%
  select(hp, cyl)
  }
  df%>%
  select({{var}}, hp, cyl)
}

select_fun_cars(mtcars, mpg)

For instance, in my select statement, I am wanting to rename a variable and then select other variables. I would have to do this (as far as I know). It seems like there should be an easier way in this instance.

tab_output_fun_sd <- function(df, df_ov, df_74, df_75, Domains){
  if(missing(Domains)){
  return(df%>%
      select(
        !!paste("Intake", "(", "N=", max(df_ov$`new_timing_of_assessment = First.N.Valid`), ")","† Mean (Std. Deviation)") := initial_overall, 
           !!paste("Intake", "(", "N=", max(df_ov$`new_timing_of_assessment = Last.N.Valid`), ")","† Mean (Std. Deviation)") := last_overall, 
           !!paste("Intake", "(", "N=", max(df_74$`new_timing_of_assessment = First.N.Valid`), ")","† Mean (Std. Deviation)") := `initial_4274`, 
           !!paste("Intake", "(", "N=", max(df_74$`new_timing_of_assessment = Last.N.Valid`), ")","† Mean (Std. Deviation)") := `last_4274`,
           !!paste("Intake", "(", "N=", max(df_75$`new_timing_of_assessment = First.N.Valid`), ")","† Mean (Std. Deviation)") := `initial_4275`,
           !!paste("Intake", "(", "N=", max(df_75$`new_timing_of_assessment = Last.N.Valid`), ")","† Mean (Std. Deviation)") := `last_4275`)%>%
        gt() %>%
  opt_stylize(style= 2, color = "blue")%>%
  as_raw_html())
  }
  
 return(df%>%
    select(Domains = label,
           !!paste("Intake", "(", "N=", max(df_ov$`new_timing_of_assessment = First.N.Valid`), ")","† Mean (Std. Deviation)") := initial_overall, 
           !!paste("Intake", "(", "N=", max(df_ov$`new_timing_of_assessment = Last.N.Valid`), ")","† Mean (Std. Deviation)") := last_overall, 
           !!paste("Intake", "(", "N=", max(df_74$`new_timing_of_assessment = First.N.Valid`), ")","† Mean (Std. Deviation)") := `initial_4274`, 
           !!paste("Intake", "(", "N=", max(df_74$`new_timing_of_assessment = Last.N.Valid`), ")","† Mean (Std. Deviation)") := `last_4274`,
           !!paste("Intake", "(", "N=", max(df_75$`new_timing_of_assessment = First.N.Valid`), ")","† Mean (Std. Deviation)") := `initial_4275`,
           !!paste("Intake", "(", "N=", max(df_75$`new_timing_of_assessment = Last.N.Valid`), ")","† Mean (Std. Deviation)") := `last_4275`)%>%
  gt() %>%
  opt_stylize(style= 2, color = "blue")%>%
  as_raw_html())
}

Upvotes: 1

Views: 76

Answers (3)

G. Grothendieck
G. Grothendieck

Reputation: 270045

This will pass the var argument column to select and rename it using the string in the label variable.

library(dplyr)

select_fun_cars <- function(df, var, label = "X") {
  df %>% select("{label}" := {{var}}, hp, cyl) %>% head(2)
}

select_fun_cars(mtcars, mpg)
           X  hp cyl
## Mazda RX4     21 110   6
## Mazda RX4 Wag 21 110   6

select_fun_cars(mtcars)
##                hp cyl
## Mazda RX4     110   6
## Mazda RX4 Wag 110   6

Upvotes: 1

Edward
Edward

Reputation: 19339

Since you didn't add a dplyr tag, this is a base R approach:

select_fun_cars = function(df, var=NULL){
  if(!missing(var)) var <- deparse(substitute(var))

  df <- df[, c(var, 'hp', 'cyl')]
  
  # Rename var if it is supplied
  if(!missing(var)) names(df)[1] <- 'label'
  
  return(df)
}

select_fun_cars(mtcars, mpg) |> head()
                  label  hp cyl
Mazda RX4          21.0 110   6
Mazda RX4 Wag      21.0 110   6
Datsun 710         22.8  93   4
Hornet 4 Drive     21.4 110   6
Hornet Sportabout  18.7 175   8
Valiant            18.1 105   6

select_fun_cars(mtcars) |> head()
                   hp cyl
Mazda RX4         110   6
Mazda RX4 Wag     110   6
Datsun 710         93   4
Hornet 4 Drive    110   6
Hornet Sportabout 175   8
Valiant           105   6

This also works for the dplyr select:

df <- select(df, var, hp, cyl)

Upvotes: 2

Gero
Gero

Reputation: 177

For the first case I would suggest just setting to NULL the default argument/s. This should work pretty well with dplyr::select()

select_fun_cars = function(df, var = NULL){
  df%>%
  select(var, hp, cyl)
}

For the second case, if you want to rename a column label using the character value stored in Domains (e.g, Domains = "new_label") I suggest using the function dplyr::rename(setNames("label", Domains)). Notice that if you set the default value as Domains = "label" it won't rename anything

Upvotes: 2

Related Questions