#r #subset #na
Вопрос:
Я хотел бы удалить все строки, которые содержат более 25% NAs в нескольких столбцах. В связи с тем, что это включает в себя около 120 соответствующих столбцов, было бы полезно не указывать их все. Предпочтительно, скорее, что-то вроде: все между columnA и columnZ.
Я пробовал работать с:
data[!is.na(data$ColumnA:data$ColumnZ), > 0.25]
Но это только показало эту ошибку:
Необходимо подмножество столбцов с допустимым вектором индексов.
Логические индексы должны соответствовать размеру индексированного ввода.
Вход x имеет размер 250, но индекс !is.na(данные$ColumnA:данные$ColumnZ) > 0.25 имеет размер 3.
(250-это фактическое количество столбцов в наборе данных)
Я также думал о том, чтобы попробовать drop_na, но это приводит к аналогичной проблеме.
У вас есть какие-нибудь предложения? Заранее спасибо
Комментарии:
1. Не могли бы вы поделиться воспроизводимым образцом ваших данных с помощью
dput(head(data))
?, чтобы другие могли использовать его, чтобы помочь вам.2.
df[rowMeans(is.na(df)) < 0.25, ]
3. @alistaire, я полагаю, вам все равно придется подмножествовать столбцы по имени или индексу, например
df[rowMeans(is.na(df[,paste0("Column", LETTERS[1:26])])) < 0.25, ]
Ответ №1:
Вы можете использовать rowMeans(is.na(.)
Данные:
set.seed(1)
df<-tibble(matrix(sample(c(1, NA), 64, replace=TRUE, prob = c(0.75, 0.25)), nrow=8))
# A tibble: 8 x 1
`matrix(...)`[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 1 1 1 1 1 NA
2 1 1 1 1 NA 1 1 1
3 1 NA 1 1 1 1 1 NA
4 1 1 1 1 NA NA NA 1
5 1 1 1 1 NA NA 1 NA
6 1 1 NA 1 1 1 1 1
7 NA 1 1 1 1 1 NA 1
8 1 1 1 1 1 NA 1 1
Фильтр:
df%>%filter(rowMeans(is.na(.))<0.25)
# A tibble: 4 x 1
`matrix(...)`[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 1 1 1 1 1 NA
2 1 1 1 1 NA 1 1 1
3 1 1 NA 1 1 1 1 1
4 1 1 1 1 1 NA 1 1
Или с помощью rowwise():
df%>%
rowwise()%>%
filter(mean(is.na(c_across(everything())))<0.25)
Ответ №2:
Обычно я решаю задачи такого типа с помощью пакетов tidyverse и naniar.
Вот пример использования встроенного набора данных «airquality» для идентификации строк с более чем 25% NAs (отсутствующие значения):
library(tidyverse)
library(naniar)
data(airquality)
dat1 <- airquality
miss_case_summary(dat1) %>%
filter(pct_miss >= 25)
# A tibble: 2 x 3
# case n_miss pct_miss
# <int> <int> <dbl>
#1 5 2 33.3
#2 27 2 33.3
И исключить эти два случая (строки):
dat2 <- dat1 %>%
slice(-c(5, 27))
Если у вас в наборе данных большое количество NAs, вы можете использовать:
list_of_gt25_NAs <- miss_case_summary(dat1) %>%
filter(pct_miss >= 25)
dat2 <- dat1 %>%
slice(-c(list_of_gt25_NAs$case))