2010-06-07 19 views
30

Mam wektor list i używam na nich unlist. Niektóre elementy w wektorach to NULL, a unlist wydaje się je upuszczać.Unikaj upuszczania wartości NULL pod wartości

Jak mogę temu zapobiec?

Oto prosty (nie) działający przykład pokazujący tę niechcianych funkcji z 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 

Odpowiedz

15

Kwestia jest taka, że ​​nie można mieć NULL w środku wektorze. Na przykład:

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

Możesz mieć NA w środku. Można mógłby przekształcić go do znaku, a następnie z powrotem do numeryczny, który automatycznie konwertuje wartości null NA (z ostrzeżeniem):

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

następnie umieścić nazwiska z powrotem, bo już zostało upuszczone przez poprzedni operacja:

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

Na 3.2.2, wygląda as.numeric (as.character (NULL)) zwraca wartość numeryczną (0). Nowym podejściem może być użycie lapply (b, function (x) ifelse (is.null (x), NA, x)) – cylondude

1

Poprawnym sposobem wskazania brakującej wartości jest NA (nie NULL). Oto kolejna wersja, która działa:

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

dzięki za odpowiedź. Oczywiście nie definiuję listy ręcznie, jest ona zwracana przez funkcję. W każdym razie zmiana NULL na NA przed "unlist" wydawało się załatwić sprawę. – nico

+0

@nico Jeśli to twoja funkcja, możesz rozważyć przepisanie jej, aby zwrócić 'NA' zamiast' NULL'. spójrz na strony pomocy na 'NA' i' NULL', aby zobaczyć różnice między tymi dwoma obiektami. – Marek

+1

@Marek: Nie, faktycznie jest to lista zwrócona przez zastosowanie 'coef' na liście obiektów zwróconych przez' nls'. Niektóre z tych obiektów mają wartość NULL, a 'coef (NULL)' zwraca 'NULL' ... – nico

29

W tym przypadku (listy głębokości jeden poziom) Należy też działa:

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

Jeśli masz do czynienia z długą złożonego JSON z kilku poziomach zalecana spróbuj tego:

Wyodrębniłem dane z dzienników gier ze strony internetowej nba.com/stats. Problem polega na tym, niektórzy gracze mają wartość NULL do 3 punktu rzutów wolnych (głównie centrów) i jsonlite :: fromJSON zdaje sobie wartości NULL bardzo dobrze:

#### 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]] 
Powiązane problemy