Sous-ensemble de lignes contenant des valeurs NA (manquantes) dans une colonne choisie d'un bloc de données

96

Nous avons une trame de données à partir d'un fichier CSV. Le bloc de données DFcomporte des colonnes contenant des valeurs observées et une colonne ( VaR2) contenant la date à laquelle une mesure a été prise. Si la date n'a pas été enregistrée, le fichier CSV contient la valeur NA, pour les données manquantes.

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

Nous aimerions utiliser la commande subset pour définir un nouveau bloc de données de new_DFsorte qu'il ne contienne que des lignes qui ont une NA'valeur de la colonne ( VaR2). Dans l'exemple donné, seule la ligne 2 sera contenue dans le nouveau DF.

La commande

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

ne fonctionne pas, le bloc de données résultant n'a pas d'entrées de ligne.

Si dans le fichier CSV d' origine de la valeur NAsont échangées avec NULLla même commande produit le résultat souhaité: new_DF<-subset(DF,DF$Var2=="NULL").

Comment puis-je faire fonctionner cette méthode si, pour la chaîne de caractères, la valeur NAest fournie dans le fichier CSV d'origine?

John
la source

Réponses:

146

N'utilisez jamais == 'NA' pour tester les valeurs manquantes. Utilisez is.na()plutôt. Cela devrait le faire:

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

ou si vous souhaitez vérifier une colonne particulière, vous pouvez également utiliser

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

Si vous avez des valeurs de caractères NA, lancez d'abord

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

pour les remplacer par des valeurs manquantes.

Joris Meys
la source
2
Merci pour votre réponse rapide (c'était rapide)! En effet, en raison de la livraison csv des données, les «NA» sont des valeurs de caractères et votre deuxième instruction pourrait être très utile. Pouvez-vous également clarifier votre première déclaration? L'utilisation de rowSums () n'est pas claire pour moi, car je ne vérifierai qu'une colonne particulière (il y a beaucoup de colonnes). Si cette colonne particulière (dans l'exemple, ce serait la colonne Var2) a une chaîne de caractères `` NA '' (je la remplacerai par votre deuxième déclaration), alors je voudrais choisir la ligne entière pour faire partie du nouveau cadre de données .
John
@John: mis à jour. Le point est d'utiliser is.na, j'ai mal interprété que vous vouliez vérifier toutes les variables.
Joris Meys
3
devrait-il être new_DF <- DF[is.na(DF$Var),], c'est-à-dire qu'il semble y avoir une (parenthèse supplémentaire après DF[?
PatrickT
39

NA est une valeur spéciale dans R, ne mélangez pas la valeur NA avec la chaîne "NA". Selon la façon dont les données ont été importées, vos cellules "NA" et "NULL" peuvent être de différents types (le comportement par défaut est de convertir les chaînes "NA" en valeurs NA et de laisser les chaînes "NULL" telles quelles).

Si vous utilisez read.table () ou read.csv (), vous devriez considérer l'argument "na.strings" pour effectuer une importation de données propres et toujours travailler avec des valeurs R NA réelles.

Un exemple, fonctionnant dans les deux cas des cellules "NULL" et "NA":

DF <- read.csv("file.csv", na.strings=c("NA", "NULL"))
new_DF <- subset(DF, is.na(DF$Var2))
maressyl
la source
1
Merci pour votre réponse. Si je comprends bien, la première déclaration ferait la même chose que Df [Df == 'NA'] <- NA dans l'exemple de Joris? La (petite) différence serait alors que cela se fait directement dans votre déclaration au début, lorsque la trame de données est créée (c'est une méthode de programmation très propre et je l'aime donc).
John
Exactement. Joris a suggéré de remplacer manuellement les chaînes "NA" par des valeurs NA, ici je suggère seulement d'utiliser la fonction "na.strings" de read.table () pour atteindre le même but.
maressyl
La réponse de Joris est en fait la manière "préférée" d'accomplir cet exploit (si vous écrivez ceci dans un script). Voir: stackoverflow.com/questions/9860090/…
Jonathan
@Jonathan: Deux idées distinctes ici, le sujet que vous citez dit que "[" devrait être préféré sur "subset", mais nous parlions de l'argument "na.strings" dans read.table (), mon sous-ensemble n'était là que pour visualiser les effets.
maressyl
33

complete.casesdonne TRUEquand toutes les valeurs d'une ligne ne sont pasNA

DF[!complete.cases(DF), ]
user3226167
la source
11
new_data <- data %>% filter_all(any_vars(is.na(.))) 

Cela devrait créer une nouvelle trame de données (new_data ) avec uniquement les valeurs manquantes.

Fonctionne mieux pour garder une trace des valeurs que vous pourriez supprimer par la suite car elles contenaient des colonnes avec des observations manquantes (NA).

Ronak Pol
la source
3

Essayez de changer ceci:

new_DF<-dplyr::filter(DF,is.na(Var2)) 
drhnis
la source
Pouvez-vous expliquer pourquoi cela fonctionne, ce que cela fait, etc.?
csilk
new_DF <
drhnis
1
Plus joliment exprimé comme DF %>% filter(is.na(Var2))après library(dplyr).
Joe
-1

Imprime toutes les lignes avec des données NA:

tmp <- data.frame(c(1,2,3),c(4,NA,5));
tmp[round(which(is.na(tmp))/ncol(tmp)),]
jstar
la source
@ZheyuanLi Si vous n'aimez pas la réponse, votez simplement contre. La modification de la réponse pour recommander le marquage n'est PAS l'action appropriée. Laissez un commentaire si vous en ressentez le besoin.
Manfred Radlwimmer