Удалить строки с неполными уровнями, которые не являются NA

Некоторое время я рассматривал возможные решения в Stackru, но мне нужно обратиться за помощью по этому вопросу.

У меня есть датафрейм со следующей структурой:

df <- data.frame(A = c("A", "A", "A", "A", "B", "B", "C", "C", "C", "C", "D"),
             B = c("F1", "F2", "F3", "F4", "F2", "F3", "F1", "F2", "F3", "F4", 
             "F4"))

Я хотел бы отфильтровать его, чтобы сохранить только те строки с полными уровнями, как показано ниже:

df_new <- data.frame(A = c("A", "A", "A", "A", "C", "C", "C", "C"),
                 B = c("F1", "F2", "F3", "F4", "F1", "F2", "F3", "F4"))

Пожалуйста, обратите внимание, что фильтрация Col1 подлежит условию, что Col2 должен иметь все уровни lvls <- c("F1", "F2", "F3", "F4")так что используя dplyr::filter или же subset это сложно. Это длинный (и динамический) набор данных, поэтому я не хотел бы делать это вручную. Заранее спасибо за ваше внимание.

2 ответа

Решение

Как насчет любого из них:

library(tidyverse)

df %>% group_by(A) %>% 
  filter(length(unique(B)) == length(levels(B)))

df %>% group_by(A) %>% 
  filter(n_distinct(B) == length(levels(B)))
       A      B
  <fctr> <fctr>
1      A     F1
2      A     F2
3      A     F3
4      A     F4
5      C     F1
6      C     F2
7      C     F3
8      C     F4

Или, если вам нужно беспокоиться о пропущенных значениях:

df %>% group_by(A) %>% 
  filter(length(unique(B[!is.na(B)])) == length(levels(B)))

df %>% group_by(A) %>% 
  filter(n_distinct(B, na.rm=TRUE) == length(levels(B)))

Вот вариант с data.table

library(data.table)
setDT(df)[, .SD[nlevels(droplevels(B))==max(nlevels(B))], A]
#   A  B
#1: A F1
#2: A F2
#3: A F3
#4: A F4
#5: C F1
#6: C F2
#7: C F3
#8: C F4
Другие вопросы по тегам