简体   繁体   中英

Generalizable function to select and filter dataframe r - using shiny input

I am building a shiny app. The user will need to be able to reduce the data by selecting variables and filtering on specific values for those variables. I am stuck trying to get a generalizable function that can work based on all possible selections.

Here is an example - I skip the shiny code because I think the problem is with the function:

#sample dataframe
df <- data.frame('date' = c(1, 2, 3, 2, 2, 3, 1), 
                 'time' = c('a', 'b', 'c', 'e', 'b', 'a', 'e'), 
                 'place' = c('A', 'A', 'A', 'H', 'A', 'H', 'H'), 
                 'result' = c('W', 'W', 'L', 'W', 'W', 'L', 'L'))

If the user selected date and result for the date values 1, 2 ; and the result values W , I would do the following:

out <- df %>%
    select(date, result) %>%
    filter(date %in% c(1,2)) %>%
    filter(result %in% c('W'))

The challenge I am having is that the user can select any unique combinations of variables and values. Using the input$ values from my shiny app, I can get the selected variables into a vector and I can get the selected values into a list of values, positionaly matching the selected variables. For example:

selected_variables <- c('date', 'result')
selected_values <- list(c(1,2), c('W'))

What i think i then need is a generalizable function that will match up the filter calls with the correct variables. Something like:

#function that takes data frame, vector of selected variables, list of vectors of chosen values for each variable
#Returns a reduced table of selected variables, filtered values
table_reducer <- function(df, select_var, filter_values) { 
    #select the variables        
    out <- df %>%
    #now filter each variable by the values contained in the list
    select(vect_of_var)
    out <- [for loop that iterates over vect_of_var, list_of_vec, filtering accordingly]
    out #return out
}

My thinking would be to use a zip equivalent from python, but all my searching on that just points me to mapply and i can't see how to use that within the for loop (which i also know is not always approved in R - but i am talking about a relatively small number of iterations). If there is a better solution to this i would welcome it.

Here's a 1-liner table_reducer function in base R -

table_reducer <- function(df, select_var, filter_values) {
  subset(df, Reduce(`&`, Map(`%in%`, df[select_var], filter_values)))  
}

selected_variables <- c('date', 'result')
selected_values <- list(c(1,2), c('W'))
table_reducer(df, selected_variables, selected_values)

#  date time place result
#1    1    a     A      W
#2    2    b     A      W
#4    2    e     H      W
#5    2    b     A      W

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM