Mutate: Programmatically naming a new column, and then using the result in a subsequent mutate

Hi all,

Within a dplyr::mutate() call, I am trying to create a new column that will be programmatically named according to an argument to the custom function below. I want to use the results in this programmatically-named column to make a calculation for a subsequent column. However, I can't figure out how to properly call the new variable after it's been created.

impute_missing_values <- function(dataframe, vars_to_impute){
  vars_to_impute <- enquo(vars_to_impute)
  length_imputed_columns <- dataframe %>%
    select(!!vars_to_impute) %>%
    length()
  new_col_name <- quo_name(vars_to_impute)
  
  dataframe %<>%
    mutate_at(vars(!!vars_to_impute), ~case_when(. >= 0 ~ .)) %>%
    mutate(row_Avg = select(.,!!vars_to_impute) %>% rowMeans(.,na.rm=TRUE),
           !!new_col_name := select(.,!!vars_to_impute) %>% is.na() %>% rowSums(),
# This is the line where I'm struggling.
           prop_missing_Q = !!new_col_name/length_imputed_columns) %>%             
    mutate_at(vars(!!vars_to_impute), ~case_when(prop_missing_Q <= 0.2 & is.na(.) ~ row_Avg,
                                                 TRUE ~ .))
  
  return(dataframe)
  
}

impute_missing_values(BISBAS, BB8:BB20)


# Output. BB8:BB20 is the name of the programmatically created column, but I don't know how to properly unquote in this situation.
 Error in "BB8:BB20"/length_imputed_columns : 
  non-numeric argument to binary operator 
1 Like

Hi @pcall. Because the new_col_name is character, change it to symbol by sym as the follow will do.

impute_missing_values <- function(dataframe, vars_to_impute){
  vars_to_impute <- enquo(vars_to_impute)
  length_imputed_columns <- dataframe %>%
    select(!!vars_to_impute) %>%
    length()
  new_col_name <- quo_name(vars_to_impute)
  
  dataframe %<>%
    mutate_at(vars(!!vars_to_impute), ~case_when(. >= 0 ~ .)) %>%
    mutate(row_Avg = select(.,!!vars_to_impute) %>% rowMeans(.,na.rm=TRUE),
           !!new_col_name := select(.,!!vars_to_impute) %>% is.na() %>% rowSums(),
           # This is the line where I'm struggling.
           prop_missing_Q = !!sym(new_col_name)/length_imputed_columns) %>%             
    mutate_at(vars(!!vars_to_impute), ~case_when(prop_missing_Q <= 0.2 & is.na(.) ~ row_Avg,
                                                 TRUE ~ .))
  
  return(dataframe)
  
}```
5 Likes

Wonderful, this is precisely what I was looking for! Thank you @raytong!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.