2010-06-07 3 views
30

J'ai un vecteur de listes et j'utilise unlist sur eux. Certains des éléments dans les vecteurs sont NULL et unlist semble les laisser tomber.Empêcher la liste de supprimer des valeurs NULL

Comment puis-je empêcher cela?

est ici simple (non) exemple de travail montrant cette caractéristique indésirable de unlist

a = c(list("p1"=2, "p2"=5), 
     list("p1"=3, "p2"=4), 
     list("p1"=NULL, "p2"=NULL), 
     list("p1"=4, "p2"=5)) 
unlist(a) 
p1 p2 p1 p2 p1 p2 
2 5 3 4 4 5 

Répondre

15

Le problème ici est que vous ne pouvez pas avoir NULL au milieu d'un vecteur. Par exemple:

> c(1,NULL,3) 
[1] 1 3 

Vous pouvez cependant avoir NA dans le milieu. Vous pouvez pouvait le convertir en caractère et puis de nouveau à numérique, qui convertit automatiquement les valeurs NULL à NA (avec un avertissement):

> b <- as.numeric(as.character(a)) 
Warning message: 
NAs introduced by coercion 

puis mettre les noms revenir, parce qu'ils ont été abandonnées par le précédent opération:

> names(b) <- names(a) 
> b 
p1 p2 p1 p2 p1 p2 p1 p2 
2 5 3 4 NA NA 4 5 ` 
+2

Sur 3.2.2, il ressemble à as.numeric (as.character (NULL)) renvoie numérique (0). Une nouvelle approche pourrait être d'utiliser lapplication (b, fonction (x) ifelse (is.null (x), NA, x)) – cylondude

1

La méthode correcte pour indiquer une valeur manquante est NA (not NULL). Voici une autre version qui fonctionne:

a = c(list("p1"=2, "p2"=5), 
     list("p1"=3, "p2"=4), 
     list("p1"=NA, "p2"=NA), 
     list("p1"=4, "p2"=5)) 
    unlist(a) 

p1 p2 p1 p2 p1 p2 p1 p2 
2 5 3 4 NA NA 4 5 
+1

merci pour la réponse. Evidemment je ne définis pas la liste à la main, elle est renvoyée par une fonction. De toute façon, changer les valeurs NULL en NA avant 'unlist' semblait faire l'affaire. – nico

+0

@nico Si c'est votre fonction alors vous pourriez envisager de le réécrire pour renvoyer 'NA' au lieu de' NULL'. Jetez un oeil sur les pages d'aide 'NA' et' NULL' pour voir les différences entre ces deux objets. – Marek

+1

@Marek: Non, il s'agit en fait d'une liste renvoyée en appliquant 'coef' sur une liste d'objets retournés par' nls'. Certains de ces objets sont NULL et 'coef (NULL)' renvoie 'NULL' ... – nico

29

Dans ce cas (une liste de profondeur de niveau) cela devrait fonctionne aussi:

a[sapply(a, is.null)] <- NA 
unlist(a) 
# p1 p2 p1 p2 p1 p2 p1 p2 
# 2 5 3 4 NA NA 4 5 
1

Si vous avez affaire à une longue JSON complexe avec plusieurs niveaux, vous devriez Essayez ceci:

J'ai extrait les données du journal de jeu du site Web nba.com/stats. Le problème est, certains joueurs ont une valeur NULL pour 3 points lancers francs (la plupart des centres) et jsonlite :: fromJSON semble gérer les valeurs NULL très bien:

#### Player game logs URL: one record per player per game played #### 
gameLogsURL <- paste("http://stats.nba.com/stats/leaguegamelog?Counter=1000&Direction=DESC&LeagueID=00&PlayerOrTeam=P&Season=2016-17&SeasonType=Regular+Season&Sorter=PTS") 

#### Import game logs data from JSON #### 
# use jsonlite::fromJSON to handle NULL values 
gameLogsData <- jsonlite::fromJSON(gameLogsURL, simplifyDataFrame = TRUE) 
# Save into a data frame and add column names 
gameLogs <- data.frame(gameLogsData$resultSets$rowSet) 
colnames(gameLogs) <- gameLogsData$resultSets$headers[[1]]