Подстановка фрейма данных с помощью dplyr по первой категориальной переменной и классовой частоте заданного диапазона значений во второй переменной

#r #class #dplyr

Вопрос:

В моем проекте я хочу подмножество фрейма данных с использованием dplyr, сохраняя только строки, скажем, класса variable1, в котором больше всего записей в заданном диапазоне значений в variable2.
Поскольку это может показаться здесь довольно двусмысленным, но мой фрейм данных довольно большой, я приведу вам пример фрейма данных mtcars.

На изображении ниже вы видите фрейм данных, отсортированный по переменной carb. Теперь я хочу (если возможно с dplyr ),

  1. чтобы отфильтровать ДВА класса углеводов, которые имеют наибольшее количество значений в диапазоне от 4,0 до 4,3.
  2. Из двух классов-победителей следует сохранить не все строки, а только строки в пределах упомянутого диапазона от 4,0 до 4,3. И впоследствии:
  3. Если второе место должно быть разделено двумя или более классами углеводов (как в примере), или первое место должно быть разделено тремя или более классами углеводов, «выигрышные» классы должны быть определены случайным образом (если возможно, повторяемым случайным образом, аналогично set.seed )

В конце концов, подмножество должно состоять либо из 4 отмеченных красным цветом, либо из 4 отмеченных синим строк (три строки из класса углеводов 1 «как победитель» и одна строка из одного из классов 2 или 4, соответственно, в соответствии со случайностью).

У меня есть базовое понимание подмножества с использованием dplyr. Но моя проблема в этом случае состоит в том, чтобы проверить/сравнить значения, которые должны быть получены из целых «суб-сущностей» по классам, — в качестве условия фильтрации.

Может ли кто-нибудь помочь здесь?

введите описание изображения здесь

Ответ №1:

Одна из идей состоит в том, чтобы использовать rank() функцию, которая имеет возможность устанавливать связи случайным образом.

 library(dplyr, warn.conflicts = FALSE)
set.seed(415)

# subset drat
mt_drat <- mtcars %>%
  filter(between(drat, 4, 4.3)) 

# rank by number of rows, randomly decide ties
mt_rank <- mt_drat %>%
  group_by(carb) %>%
  summarize(n = n()) %>%
  mutate(rank = rank(-n, ties.method = 'random')) %>%
  filter(rank %in% 1:2)
  
# filter to winners
mt_drat %>%
  filter(carb %in% mt_rank$carb)
#>                 mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#> Fiat 128       32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#> Toyota Corolla 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#> Fiat X1-9      27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
#> Ford Pantera L 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
 

Создано 2021-09-23 пакетом reprex (v2.0.0)