2015-07-28 2 views
1

Я хочу, чтобы удалить строки из кадра данных, когда столбец имеет NA только тогда, когда остальные строки, где значение НС найдено совпадения других, значение в кадре данныхУдаление определенных строк с некоторыми значениями NA в кадре данных

Например,

df <- data.frame(ID = c(1,1,2,2),DAY=c(1,1,2,3), VAL=c(1,NA,NA,5)) 

Я хочу удалить вторую строку, потому что есть отсутствующее значение в VAL и уже есть значение VAL с ID = 1 и DAY = 1, чтобы получить

ID  DAY  VAL 
1  1  1 
2  2  NA 
2  3  5 

Есть идеи как это сделать? Я мог бы попробовать написать цикл, но это не кажется эффективным.

+0

возможно дубликат [Как удалить "строк" со значением NA?] (Http://stackoverflow.com/questions/6138776/how-to-remove-rows-with-a-na-value) – MichaelChirico

+0

@MichaelChirico Я не нашел его в качестве дубликата, потому что 'na.omit' является более общим и он пропускает все строки с значениями NA. Но здесь OP хочет выборочно удалить значения NA по группе. – akrun

ответ

4

Это можно сделать, создав логическое условие внутри каждой переменной группировки. Здесь я угадываю «ID» и «DAY» как переменную группировки.

Один вариант используется data.table. Мы преобразуем 'data.frame' в 'data.table' (setDT(df)). Сгруппированный по 'ID', 'DAY', мы получаем индекс строки (.I) из VAL, который удовлетворяет условию (sum(is.na(VAL))!= .N & is.na(VAL)) и удаляет индекс этой строки из набора данных df. sum(is.na(VAL))!= .N дает логический вектор, который проверяет, не является ли количество значений NA в группе не равным количеству строк в этой группе (.N). Если «VAL» также является «NA» вместе с предыдущим условием, то это удаляется.

library(data.table) 
i1 <- setDT(df)[, .I[sum(is.na(VAL))!=.N & is.na(VAL)] , by = .(ID, DAY)]$V1 
df[-i1] 
# ID DAY VAL 
#1: 1 1 1 
#2: 2 2 NA 
#3: 2 3 5 

Или аналогичный вариант с dplyr. Мы группируем «ID», «День», а затем используем filter с указанным выше условием.

library(dplyr) 
df %>% 
    group_by(ID, DAY) %>% 
    filter(!(sum(is.na(VAL))!=n() & is.na(VAL))) 
# ID DAY VAL 
#1 1 1 1 
#2 2 2 NA 
#3 2 3 5 
+2

Возможно, я недостаточно читаю, но почему два решения возвращают разные результаты? – mpalanco

+2

@mplanco Из-за небольшой ошибки в коде 'dplyr'. Он должен читать: 'df%>% group_by (ID, DAY)%>% filter (! (Sum (is.na (VAL))! = N() & is.na (VAL)))' –

+1

@ StevenBeaupré Спасибо , Я пытался что-то другое и получил другой результат. – akrun

Смежные вопросы