R Динамически фильтровать строки во фрейме данных на основе уникальной комбинации перечисленных столбцов

У меня есть большой набор данных (49 столбцов с 16000 строками) в длинном формате. В конечном итоге мне нужно отфильтровать набор данных по уникальным комбинациям определенных пользователем определенных столбцов, чтобы построить другие динамически выбранные столбцы. Построение будет выполнено с использованием ggplots2 и фасетов (x, y, facet_column, facet_row, colorbin).

Вместо того, чтобы показывать свой большой набор данных, я собрал гораздо меньший пример, используя набор данных mtcars, чтобы проиллюстрировать свою проблему. У меня столбцы выводятся правильно, но без серии циклов for я не могу понять, как изменить подмножество.

Настроить данные:

#Load needed libraries
library("dplyr", "tidyr", "ggplot2")

#Convert row.names into a column that can be called
data <- tibble::rownames_to_column(mtcars, "Names")

#Declare groups:
#group_rows are the columns that I need to filter my data based on the unique combinations
#  Ultimately, I want to create a new plot of group_cols based on these rows
group_rows <- list(list('cyl', 'gear'), list('vs', 'carb'))
#group_cols are the columns I want included in the plot
group_cols <- list(list('Names', 'mpg','cyl', 'gear'), list('Names', 'wt','vs', 'carb'))

Это работает и дает нужный мне результат, но СУПЕР неудобно

Поскольку я НЕ динамически фильтрую переменную group_rows, мне приходится повторять цикл для каждого варианта списка в group_rows. В моем примере у меня есть только две переменные в каждом списке моих group_rows, но в моем фактическом наборе данных я мог иметь значительно больше.

# Do group_rows 1
for (c in group_cols){
  for (var_cyl in unique(data$cyl)){
    for (var_gear in unique(data$gear)){
     df <- data %>%
        filter(cyl==var_cyl &gear==var_gear) %>%
        select_(.dots = c)
      # enter my plotting function
    }
  }
}
# Do group_rows 2
for (c in group_cols){
  for (var_vs in unique(data$vs)){
    for (var_carb in unique(data$carb)){
      df <- data %>%
        filter(vs==var_vs &carb==var_carb) %>%
        select_(.dots = c)

      # enter my plotting function
    }
  }
}

person melmo    schedule 18.05.2020    source источник
comment
Можете ли вы предоставить созданный вручную график, который показывает ожидаемый результат?   -  person Ian Campbell    schedule 18.05.2020
comment
Я не могу использовать этот пример данных (потому что я пытался получить больше о фильтрующих строках), но если вы думаете, что это было бы полезно, я мог бы добавить вывод с моим большим набором данных.   -  person melmo    schedule 18.05.2020
comment
Очень сложно помочь без репрезентативных данных и ожидаемых результатов.   -  person Ian Campbell    schedule 18.05.2020
comment
Я добавил свой фактический набор данных и цифры в качестве фрагмента. Дайте мне знать, если я могу еще что-нибудь сделать, чтобы прояснить ситуацию.   -  person melmo    schedule 18.05.2020
comment
Я думаю, что есть хороший шанс помочь вам делать то, что вы хотите, но, к сожалению, ваш вопрос не в той форме, которую я могу понять. Предоставьте рабочий набор данных, который мы можем запустить, а также параметры, которые вы ожидаете передать, и ожидаемый результат. Ваша последняя редакция делает вопрос слишком широким. Пожалуйста, сделайте свой вопрос настолько минимальным, насколько это необходимо, чтобы помочь вам преодолеть препятствие.   -  person Ian Campbell    schedule 18.05.2020
comment
Спасибо, Йен, твой ответ меня близко, так что держу пари, ты тоже сможешь это понять. Я обновил свой вопрос, чтобы, надеюсь, быть более ясным. Часть, с которой у меня возникла проблема, - это фильтрация строк для включения в подмножество data.frame. Я надеюсь, что из очень грубого кода, который я добавил, ясно, в чем моя проблема. Мое подмножество столбцов и построение графика в порядке.   -  person melmo    schedule 18.05.2020
comment
См. github.com/alan-y/blogdown-website/issues. / за подход.   -  person Lionel Henry    schedule 19.05.2020


Ответы (1)


Вот подход с использованием parse_expr из rlang, а также purrr

Я немного изменил ваш group_rows, чтобы включить фильтрацию:

group_rows <- list(list("cyl==4", "&", "gear==4"), list("vs==1", "&", "carb==4"))

library(dplyr)
library(purrr)
library(rlang)
map2(group_cols,group_rows,
     ~ data %>%
          dplyr::select(unlist(.x)) %>%
          dplyr::filter(!!parse_expr(paste(.y,collapse = "")))
     )
[[1]]
           Names  mpg cyl gear
1     Datsun 710 22.8   4    4
2      Merc 240D 24.4   4    4
3       Merc 230 22.8   4    4
4       Fiat 128 32.4   4    4
5    Honda Civic 30.4   4    4
6 Toyota Corolla 33.9   4    4
7      Fiat X1-9 27.3   4    4
8     Volvo 142E 21.4   4    4

[[2]]
      Names   wt vs carb
1  Merc 280 3.44  1    4
2 Merc 280C 3.44  1    4

Мне не ясно, как вы собираетесь построить 4 столбца. Но вы можете использовать walk2 вместо map2 и просто строить график своей функции, как хотите.

person Ian Campbell    schedule 18.05.2020
comment
Мне нужно использовать ggplot в фасетной оболочке, чтобы построить столбцы_группы как что-то вроде (x, y, facet_column, facet_row, color). Проблема с этим кодом у меня до сих пор заключается в том, что строки все еще явно объявлены (cyl == 4), а не перечислены динамически. Мне нужен набор графиков для каждой уникальной комбинации цилиндров и шестерен. - person melmo; 18.05.2020