Подмножество строк, содержащих значения NA (отсутствующие) в выбранном столбце фрейма данных


96

У нас есть фрейм данных из файла CSV. Во фрейме данных DFесть столбцы, содержащие наблюдаемые значения, и столбец ( VaR2), содержащий дату, когда было выполнено измерение. Если дата не была записана, CSV-файл содержит значение NAдля отсутствующих данных.

Var1  Var2 
10   2010/01/01
20   NA
30   2010/03/01

Мы хотели бы использовать команду subset для определения нового фрейма данных new_DF, чтобы он содержал только строки, которые имеют NA'значение из столбца ( VaR2). В приведенном примере в новом будет содержаться только строка 2 DF.

Команда

new_DF<-subset(DF,DF$Var2=="NA") 

не работает, итоговый фрейм данных не содержит записей строк.

Если в исходном файле CSV ценен NAобмениваются с NULL, та же команда производит желаемый результат: new_DF<-subset(DF,DF$Var2=="NULL").

Как я могу заставить этот метод работать, если для символьной строки значение NAуказано в исходном CSV-файле?

Ответы:


149

Никогда не используйте == 'NA' для проверки отсутствующих значений. is.na()Вместо этого используйте . Это должно сделать это:

new_DF <- DF[rowSums(is.na(DF)) > 0,]

или если вы хотите проверить конкретный столбец, вы также можете использовать

new_DF <- DF[is.na(DF$Var),]

Если у вас есть значения символов NA, сначала запустите

Df[Df=='NA'] <- NA

чтобы заменить их пропущенными значениями.


2
Спасибо за быстрый ответ (это было быстро)! В самом деле, из-за доставки данных csv «NA» являются символьными значениями, и ваш второй оператор может быть очень полезен. Не могли бы вы также пояснить ваше первое утверждение? Использование rowSums () для меня непонятно, поскольку я буду проверять только конкретный столбец (их много). Если в этом конкретном столбце (в примере это столбец Var2) есть строка символов 'NA' (я заменю ее вторым оператором), тогда я хотел бы выбрать всю строку как часть нового фрейма данных .
Джон

@John: обновлено. Смысл в том, чтобы использовать is.na, я неправильно истолковал, что вы хотите проверить все переменные.
Joris Meys

3
должно быть так new_DF <- DF[is.na(DF$Var),], т.е. после него должна быть дополнительная (скобка DF[?
PatrickT

39

NA - это специальное значение в R, не путайте значение NA со строкой «NA». В зависимости от того, как данные были импортированы, ваши ячейки «NA» и «NULL» могут иметь различный тип (поведение по умолчанию - преобразовать строки «NA» в значения NA и оставить строки «NULL» как есть).

При использовании read.table () или read.csv () вам следует рассмотреть аргумент «na.strings», чтобы выполнить чистый импорт данных и всегда работать с реальными значениями R NA.

Пример, работающий в обоих случаях "NULL" и "NA" ячейки:

DF <- read.csv("file.csv", na.strings=c("NA", "NULL"))
new_DF <- subset(DF, is.na(DF$Var2))

1
Спасибо за Ваш ответ. Если я правильно понимаю, первый оператор будет делать то же самое, что и Df [Df == 'NA'] <- NA в примере с Джорисом? Тогда (небольшая) разница будет заключаться в том, что это делается в вашем статусе непосредственно в начале, когда создается фрейм данных (это очень чистый метод программирования, и поэтому мне он нравится).
Джон

В яблочко. Джорис предложил заменить строки "NA" значениями NA вручную, здесь я предлагаю только использовать функцию "na.strings" read.table () для достижения той же цели.
maressyl 02

Ответ Джориса на самом деле является «предпочтительным» способом выполнить этот подвиг (если вы пишете это в скрипте). См .: stackoverflow.com/questions/9860090/…
Джонатан,

@Jonathan: Здесь две разные идеи, в теме, которую вы цитируете, говорится, что «[» следует отдавать предпочтение для «subset», но мы говорили об аргументе «na.strings» в read.table (), мое подмножество было здесь только для визуализации эффекты.
maressyl

34

complete.casesдает, TRUEкогда все значения в строке неNA

DF[!complete.cases(DF), ]

13
new_data <- data %>% filter_all(any_vars(is.na(.))) 

Это должно создать новый фрейм данных (new_data ) только с недостающими значениями в нем.

Лучше всего работает для отслеживания значений, которые вы могли бы впоследствии потерять, потому что в них были столбцы с отсутствующими наблюдениями (NA).


3

Попробуйте изменить это:

new_DF<-dplyr::filter(DF,is.na(Var2)) 

Не могли бы вы объяснить, почему это работает, что это делает и т. Д.?
csilk

new_DF <-dplyr :: filter (DF, is.na (Var2)) он в основном использует функцию фильтрации пакета dplyr и отфильтровывает любое наблюдение в столбце Var2, которое удовлетворяет условию is.na, т.е. они выбирают все наблюдения с NA
drhnis

1
Более красиво выражается как DF %>% filter(is.na(Var2))после library(dplyr).
Joe

-1

Печатает все строки с данными NA:

tmp <- data.frame(c(1,2,3),c(4,NA,5));
tmp[round(which(is.na(tmp))/ncol(tmp)),]

@ZheyuanLi Если вам не нравится ответ, просто проголосуйте против. Редактирование ответа для рекомендации пометки НЕ является подходящим действием. Оставьте комментарий, если почувствуете в этом необходимость.
Манфред Рэдлвиммер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.