rtidyversesummarize

Using value inside a column to call out which other column should be used in a function call


I am working on a R script visual that feeds from data in PBI. I have a slicer that is populating a column in a dataframe from a choice of other column headers. This slicer is populating the "letters" column with the column names a through k. I would like to use the value of letters to call a column in a summarize function call. This is because letters will change dynamically as the user changes the slicer. I put a comment where I would like to call this value of letters instead of manually calling a column name of dataset.

library(tidyverse)

filtered <-filter(dataset,ScrapRecipeID==SelectedRecipe)
filteredSort<-filtered[order(filtered$YearMonthIndex),]
summarizedRecipe<-filteredSort %>%
    dplyr::group_by(MonthYear,YearMonthIndex)  %>%
    dplyr::summarize(letterMean=mean(a)) %>%  # want to call the value of letters here
    ungroup()
summarizedAll<-dataset %>%
    dplyr::group_by(MonthYear,YearMonthIndex)  %>%
    dplyr::summarize(letterMean2=mean(a)) %>%   # want to call the value of letters here
    ungroup()

dput of dataset:

dput(head(dataset))
structure(list(a = c(0.00266666666666667, 0.00266666666666667, 
0.00266666666666667, 0.00266666666666667, 0.00266666666666667, 
0.00266666666666667), b = c(2e-04, 2e-04, 2e-04, 2e-04, 2e-04, 
2e-04), c = c(0, 0, 0, 0, 0, 0), d = c(0.00916666666666667, 0.00916666666666667, 
0.00916666666666667, 0.00916666666666667, 0.00916666666666667, 
0.00916666666666667), e = c(0.148333333333333, 0.148333333333333, 
0.148333333333333, 0.148333333333333, 0.148333333333333, 0.148333333333333
), f = c(0.316666666666667, 0.316666666666667, 0.316666666666667, 
0.316666666666667, 0.316666666666667, 0.316666666666667), g = c(0.0333333333333333, 
0.0333333333333333, 0.0333333333333333, 0.0333333333333333, 0.0333333333333333, 
0.0333333333333333), h = c(0.135, 0.135, 0.135, 0.135, 0.135, 
0.135), SelectedRecipe = c("Recipe 85D", "Recipe 85D", "Recipe 85D", 
"Recipe 85D", "Recipe 85D", "Recipe 85D"), YearMonthIndex = c(24257L, 
24257L, 24257L, 24257L, 24257L, 24257L), MonthYear = c("05-2021", 
"05-2021", "05-2021", "05-2021", "05-2021", "05-2021"), Year = c(12126L, 
12126L, 12126L, 12126L, 12126L, 12126L), ScrapRecipeID = c("", 
"", "", "", "", ""), i = c(0.00193333333333333, 0.00193333333333333, 
0.00193333333333333, 0.00193333333333333, 0.00193333333333333, 
0.00193333333333333), J = c(0.00933333333333333, 0.00933333333333333, 
0.00933333333333333, 0.00933333333333333, 0.00933333333333333, 
0.00933333333333333), k = c(0.0396666666666667, 0.0396666666666667, 
0.0396666666666667, 0.0396666666666667, 0.0396666666666667, 0.0396666666666667
), letters = c("a", "a", "a", "a", "a", "a")), row.names = c(NA, 
6L), class = "data.frame")

Solution

  • You can find the unique values in your letters column and then get the intersection of the values a-k. You can then pass that vector to across() in a summarize() to get the mean of those columns that appear in the letter columns.

    library(dplyr)
    library(rlang)
    lets <- tolower(unique(df$letters))
    
    coloverlap <- intersect(letters[1:11], lets)
    summarizedAll<-df %>%
      dplyr::group_by(MonthYear,YearMonthIndex)  %>%
      dplyr::summarize(across(coloverlap,~mean(.x, na.rm = TRUE), .names =  "letterMean2_{coloverlap}"  )) %>%   
      ungroup()
    

    edit if the letter will always be one letter you can use find the unique value and then pass it to mean with the help of rlang:

    summarizedAll<-df %>%
      dplyr::group_by(MonthYear,YearMonthIndex)  %>%
      dplyr::summarize( lettermean2 = mean(!!rlang::sym(unique(df$letters))) ) %>%   # want to call the value of letters here
      ungroup()