2011-10-30 13 views
39

Ho trovato questo comportamento strano e volevo che gli utenti più esperti condividessero i loro pensieri e soluzioni alternative. sull'esecuzione di codice di seguito in R:Assegnazione di NULL a un elemento dell'elenco in R?

sampleList <- list() 
d<- data.frame(x1=letters[1:10],x2=1:10,stringsAsFactors=FALSE) 
for(i in 1:nrow(d)) 
     sampleList[[i]] <- d$x1[i] 

print(sampleList[[1]]) 
print(sampleList[[2]]) 
print(sampleList[[3]]) 
print(length(sampleList)) 
sampleList[[2]] <- NULL 
print(length(sampleList)) 
print(sampleList[[2]]) 
print(sampleList[[3]]) 

L'elenco elementi vengono spostati in su. Forse è come previsto, ma sto cercando di implementare una funzione in cui unisco due elementi di un elenco e ne rilascia uno. Praticamente voglio perdere quell'indice di lista o averlo come NULL.

C'è un modo in cui posso assegnare NULL ad esso e non vedere il comportamento di cui sopra?

Grazie per i vostri suggerimenti.

+0

Sarebbe 'unlist' aiutare il vostro caso? –

+1

Stai usando R sbagliato - prova ad implementare più vettorizzazione, altrimenti i tuoi codici rimarranno lenti, brutti e controintuitivi. – mbq

risposta

49

Buona domanda.

Scopri i R-FAQ:

In R, se x è una lista, allora x [i] < - NULL e x [[i]] < - NULL rimuovere gli elementi indicati da x. Il primo di questi è incompatibile con S, dove è un no-op. (Si noti che è possibile impostare gli elementi NULL utilizzando x [i] < - elenco (NULL).)

consideri il seguente esempio:

> t <- list(1,2,3,4) 
> t[[3]] <- NULL   # removing 3'd element (with following shifting) 
> t[2] <- list(NULL)  # setting 2'd element to NULL. 
> t 
[[1]] 
[2] 1 

[[2]] 
NULL 

[[3]] 
[3] 4 

UPDATE:

Come il autore di the R Inferno commentato, ci possono essere situazioni più sottili quando si ha a che fare con NULL. Prendere in considerazione la struttura abbastanza generale di codice:

# x is some list(), now we want to process it. 
> for (i in 1:n) x[[i]] <- some_function(...) 

ora essere consapevoli del fatto che, se i rendimenti some_function()NULL, voi forse non sarà possibile ottenere ciò che si vuole: alcuni elementi sarà solo scompaiono. dovresti piuttosto usare la funzione lapply. Date un'occhiata a questo esempio giocattolo:

> initial <- list(1,2,3,4) 
> processed_by_for <- list(0,0,0,0) 
> processed_by_lapply <- list(0,0,0,0) 
> toy_function <- function(x) {if (x%%2==0) return(x) else return(NULL)} 
> for (i in 1:4) processed_by_for[[i]] <- toy_function(initial[[i]]) 
> processed_by_lapply <- lapply(initial, toy_function) 
> processed_by_for 
    [[1]] 
    [1] 0 

    [[2]] 
    [1] 2 

    [[3]] 
    NULL 

    [[4]] 
    [1] 4 

> processed_by_lapply 
    [[1]] 
    NULL 

    [[2]] 
    [1] 2 

    [[3]] 
    NULL 

    [[4]] 
    [1] 4 
+14

Questo è Circle 8.1.55 di 'The R Inferno' http://www.burns-stat.com/pages/Tutor/R_inferno.pdf Circle 8.1.56 è una versione più sottile di questo. –

+0

@Patric, ho aggiornato la risposta in base al tuo commento. – Max

+0

Grazie per la spiegazione dettagliata. Come si leggono i manuali e non si trascurano queste sottigliezze !!!! – harshsinghal

5

La tua domanda mi confonde un po '.

L'assegnazione di null a un oggetto esistente elimina in modo esatto quell'oggetto (questo può essere molto utile ad esempio se si dispone di un frame di dati e si desidera eliminare colonne specifiche). Questo è quello che hai fatto. Non sono in grado di determinare cosa vuoi che tu voglia. Si potrebbe provare

sampleList[[2]] <- NA 

invece di NULL, ma se da "Voglio perdere" intendi eliminarlo, allora hai già riuscito. Ecco perché "Gli elementi dell'elenco vengono spostati".

0
obj = list(x = "Some Value") 
obj = c(obj,list(y=NULL)) #ADDING NEW VALUE 
obj['x'] = list(NULL) #SETTING EXISTING VALUE 
obj 
+1

Qual è la differenza rispetto alla risposta accettata? –

Problemi correlati