Фильтр dplyr с условием на нескольких столбцах
Вот фиктивные данные:
father<- c(1, 1, 1, 1, 1)
mother<- c(1, 1, 1, NA, NA)
children <- c(NA, NA, 2, 5, 2)
cousins <- c(NA, 5, 1, 1, 4)
dataset <- data.frame(father, mother, children, cousins)
dataset
father mother children cousins
1 1 NA NA
1 1 NA 5
1 1 2 1
1 NA 5 1
1 NA 2 4
Я хочу отфильтровать эту строку:
father mother children cousins
1 1 NA NA
Я могу сделать это с помощью:
test <- dataset %>%
filter(father==1 & mother==1) %>%
filter (is.na(children)) %>%
filter (is.na(cousins))
test
Мой вопрос: у меня много столбцов, таких как великий отец, дядя1, дядя2, дядя3, и я хочу избежать чего-то подобного:
filter (is.na(children)) %>%
filter (is.na(cousins)) %>%
filter (is.na(uncle1)) %>%
filter (is.na(uncle2)) %>%
filter (is.na(uncle3))
and so on...
Как я могу использовать dplyr, чтобы сказать, фильтровать весь столбец с na (кроме отца == 1 и mother == 1)
Ответы
Ответ 1
Возможное решение dplyr
(версия> = 0.5.0.9004):
# > packageVersion('dplyr')
# [1] ‘0.5.0.9004
dataset %>%
filter(!is.na(father), !is.na(father)) %>%
filter_at(vars(-father, -mother), all_vars(is.na(.)))
Объяснение:
vars(-father, -mother)
: выберите все столбцы, кроме father
и mother
.
all_vars(is.na(.))
: хранить строки, где is.na
равно TRUE
для всех выбранных столбцов.
примечание: следует использовать any_vars
вместо all_vars
, если нужно сохранить строки, где is.na
равен TRUE
для любого столбца.
Ответ 2
Решение dplyr
:
test <- dataset %>%
filter(father==1 & mother==1 & rowSums(is.na(.[,3:4]))==2)
Где "2" - количество столбцов, которые должны быть NA
.
Это дает:
> test
father mother children cousins
1 1 1 NA NA
Вы можете применить эту логику и в базе R:
dataset[dataset$father==1 & dataset$mother==1 & rowSums(is.na(dataset[,3:4]))==2,]
Ответ 3
Ни один из ответов не является адаптивным решением. Я думаю, что намерение состоит не в перечислении всех переменных и значений для фильтрации данных.
Один простой способ добиться этого - слияние. Если у вас есть все условия в df_filter, вы можете сделать это:
df_results = df_filter %>% left_join(df_all)
Ответ 4
Вот базовый метод R, использующий две функции Reduce
и [
к подмножеству.
keepers <- Reduce(function(x, y) x == 1 & y == 1, dataset[, 1:2]) &
Reduce(function(x, y) is.na(x) & is.na(y), dataset[, 3:4])
keepers
[1] TRUE FALSE FALSE FALSE FALSE
Каждое Reduce
последовательно принимает предоставленные переменные и выполняет логическую проверку. Два результата связаны с &
. Второй аргумент функции " Reduce
можно настроить так, чтобы он включал любые переменные в формате data.frame, который вы хотите.
Затем используйте логический вектор для подмножества
dataset[keepers,]
father mother children cousins
1 1 1 NA NA