Фильтрация строк внутри группы

У меня есть фрейм данных, подобный следующему:

ID <- c(1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5)
Type <- c('A','B','C','B', 'C','A','B', 'C','A','C', 'C')
Value <- c(10, 11, 12, 1, 2, 100, 101, 102, -1, -2, -10)

df <- data.frame(ID, Type, Value)

Моя цель - фрейм данных, в котором для каждого идентификатора есть только одна строка. Но я хотел бы выбрать строки на основе определенных критериев/принципа водопада.

Поэтому предпочтительнее тип A, затем тип B, затем тип C. Моя цель - следующий фрейм данных:

ID <- c(1, 2, 3, 4, 5)
Type <- c('A','B','A','A', 'C')
Value <- c(10, 1, 100, -1, -10)

df_goal <- data.frame(ID, Type, Value)

Я думал о том, чтобы перейти к широкому формату, а затем использовать dplyr::coalesce, но тогда я потерял бы колонку «Тип». Я почти уверен, что есть решение с использованием dplyr::group_by и dplyr::summarise. Изначально я также думал об использовании dplyr::if_else в выражении dplyr::filter, но я думаю, что это невозможно.

Любая помощь приветствуется!

Всегда ли отношение предпочтения выражается в алфавитном порядке, или у вас может быть случай, когда K предпочтительнее J?

sindri_baldur 17.05.2022 12:25

На самом деле это вовсе не A, B, C. Но решение с slice_min все равно работает, так как я могу создать фиктивную переменную.

KidLu 17.05.2022 13:22
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
2
2
31
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В dplyr используйте slice_min, который по умолчанию фильтрует минимальное значение по группе, упорядоченной по переменной (здесь Type, которая отсортирована в алфавитном порядке).

library(dplyr)
df %>% 
  group_by(ID) %>% 
  slice_min(Type)

# A tibble: 5 × 3
# Groups:   ID [5]
     ID Type  Value
  <dbl> <chr> <dbl>
1     1 A        10
2     2 B         1
3     3 A       100
4     4 A        -1
5     5 C       -10

В базе R:

df[with(df, Type == ave(Type, ID, FUN = min)), ]

решение data.table

library(data.table)

setDT(df) # make it a data.table if it is not yet

setkey(df, Type) # set the key on Type
df[, .SD[1L], by = ID] # subset the first value per ID

#    ID Type Value
# 1:  1    A    10
# 2:  3    A   100
# 3:  4    A    -1
# 4:  2    B     1
# 5:  5    C   -10

Или df[, .SD[which.min(Type)], by = ID]

sindri_baldur 17.05.2022 14:57

Конечно, это работает, но это становится ужасно медленным на больших наборах данных по сравнению с установкой ключа и прямым получением первого.

Merijn van Tilborg 17.05.2022 15:28

Другие вопросы по теме