I can define a list containing NULL elements:> myList <- list("aaa",NULL,TRUE) > names(myList) <- c("first","second","third") > myList$first [1] "aaa" $second NULL $third [1] TRUE> length(myList)[1] 3 However, if I assign NULL to any of the list element then such element is deleted from the list:> myList$second <- NULL > myList$first [1] "aaa" $third [1] TRUE> length(myList)[1] 2> # > myList$first <- NULL > myList$third [1] TRUE> length(myList)[1] 1 Instead vectors cannot include NULL element:> vec <- c(TRUE,NULL,FALSE) > vec[1] TRUE FALSE> length(vec)[1] 2> vec[1] <- NULLError in vec[1] <- NULL : replacement has length zero Is the above shown behaviour of list data structures to be expected ? I took me a lot of sweat to figure out this wierd behaviour was the cause of a bug in my big program. In general, if I have a list with some elements initialized to NULL, that can be changed dynamically, then how can I reinitialize such elements to NULL without deleting them from the list ? Thank you in advance, Maura [[alternative HTML version deleted]]
'The R Inferno' page 59. Patrick Burns patrick at burns-stat.com +44 (0)20 8525 0696 http://www.burns-stat.com (home of "The R Inferno" and "A Guide for the Unwilling S User") mauede at alice.it wrote:> I can define a list containing NULL elements: > >> myList <- list("aaa",NULL,TRUE) >> names(myList) <- c("first","second","third") >> myList > $first > [1] "aaa" > $second > NULL > $third > [1] TRUE >> length(myList) > [1] 3 > > However, if I assign NULL to any of the list element then such > element is deleted from the list: > >> myList$second <- NULL >> myList > $first > [1] "aaa" > $third > [1] TRUE >> length(myList) > [1] 2 >> # >> myList$first <- NULL >> myList > $third > [1] TRUE >> length(myList) > [1] 1 > > Instead vectors cannot include NULL element: > >> vec <- c(TRUE,NULL,FALSE) >> vec > [1] TRUE FALSE >> length(vec) > [1] 2 >> vec[1] <- NULL > Error in vec[1] <- NULL : replacement has length zero > > Is the above shown behaviour of list data structures to be expected ? > I took me a lot of sweat to figure out this wierd behaviour was the cause of a bug > in my big program. > In general, if I have a list with some elements initialized to NULL, that can be changed > dynamically, then how can I reinitialize such elements to NULL without deleting them > from the list ? > > Thank you in advance, > Maura > > > > > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
On 10/25/2009 03:43 PM, mauede at alice.it wrote:> I can define a list containing NULL elements: > > >> myList<- list("aaa",NULL,TRUE) >> names(myList)<- c("first","second","third") >> myList >> > $first > [1] "aaa" > $second > NULL > $third > [1] TRUE > >> length(myList) >> > [1] 3 > > However, if I assign NULL to any of the list element then such > element is deleted from the list: > > >> myList$second<- NULL >> myList >> > $first > [1] "aaa" > $third > [1] TRUE > >> length(myList) >> > [1] 2 > >> # >> myList$first<- NULL >> myList >> > $third > [1] TRUE > >> length(myList) >> > [1] 1 > > Instead vectors cannot include NULL element: > > >> vec<- c(TRUE,NULL,FALSE) >> vec >> > [1] TRUE FALSE > >> length(vec) >> > [1] 2 > >> vec[1]<- NULL >> > Error in vec[1]<- NULL : replacement has length zero > > Is the above shown behaviour of list data structures to be expected ? > I took me a lot of sweat to figure out this wierd behaviour was the cause of a bug > in my big program. > In general, if I have a list with some elements initialized to NULL, that can be changed > dynamically, then how can I reinitialize such elements to NULL without deleting them > from the list ? > >Hi Maura, As Patrick indicated, you can assign NULL to an existing element of a list with: mylist[2]<-list(NULL) but only with the single bracket extractor. If you try this: mylist$second<-list(NULL) #OR mylist[[2]]<-list(NULL) you will get the unexpected result of the element becoming a list with a component that is NULL. This also happens if you try to add a new element: mylist[4]<-list(NULL) is okay, but: mylist[[4]]<-list(NULL) #OR mylist$fourth<-list(NULL) lands you in the same pickle. The single bracket extractor gets you the list component, but the double brackets or the equivalent extraction by name gets you what is _in_ that component. Instead of "make this list component contain NULL" the command is saying "make this list component contain a list that contains NULL". When you just assign NULL, it is like saying "make this component of the list NULL" (i.e. not there). A vector is atomic, all components must be of the same data type. So any _something_ (e.g. numeric, character, logical) is not the same as _nothing_ (NULL). The concatenation function, when confronted with two somethings separated by a nothing, simply drops the nothing. Jim
tlumley at u.washington.edu
2009-Oct-26 01:21 UTC
[R] NULL elements in lists ... a nightmare
It is perhaps also worth mentioning that this is the very first question in the actual R questions section of the R FAQ. 7.1 How can I set components of a list to NULL? You can use x[i] <- list(NULL) to set component i of the list x to NULL, similarly for named components. Do not set x[i] or x[[i]] to NULL, because this will remove the corresponding component from the list. -thomas On Sun, 25 Oct 2009, Jim Lemon wrote:> On 10/25/2009 03:43 PM, mauede at alice.it wrote: >> I can define a list containing NULL elements: >> >> >>> myList<- list("aaa",NULL,TRUE) >>> names(myList)<- c("first","second","third") >>> myList >>> >> $first >> [1] "aaa" >> $second >> NULL >> $third >> [1] TRUE >> >>> length(myList) >>> >> [1] 3 >> >> However, if I assign NULL to any of the list element then such >> element is deleted from the list: >> >> >>> myList$second<- NULL >>> myList >>> >> $first >> [1] "aaa" >> $third >> [1] TRUE >> >>> length(myList) >>> >> [1] 2 >> >>> # >>> myList$first<- NULL >>> myList >>> >> $third >> [1] TRUE >> >>> length(myList) >>> >> [1] 1 >> >> Instead vectors cannot include NULL element: >> >> >>> vec<- c(TRUE,NULL,FALSE) >>> vec >>> >> [1] TRUE FALSE >> >>> length(vec) >>> >> [1] 2 >> >>> vec[1]<- NULL >>> >> Error in vec[1]<- NULL : replacement has length zero >> >> Is the above shown behaviour of list data structures to be expected ? >> I took me a lot of sweat to figure out this wierd behaviour was the cause >> of a bug >> in my big program. >> In general, if I have a list with some elements initialized to NULL, that >> can be changed >> dynamically, then how can I reinitialize such elements to NULL without >> deleting them >> from the list ? >> >> > Hi Maura, > As Patrick indicated, you can assign NULL to an existing element of a list > with: > > mylist[2]<-list(NULL) > > but only with the single bracket extractor. If you try this: > > mylist$second<-list(NULL) > #OR > mylist[[2]]<-list(NULL) > > you will get the unexpected result of the element becoming a list with a > component that is NULL. This also happens if you try to add a new element: > > mylist[4]<-list(NULL) > > is okay, but: > > mylist[[4]]<-list(NULL) > #OR > mylist$fourth<-list(NULL) > > lands you in the same pickle. The single bracket extractor gets you the list > component, but the double brackets or the equivalent extraction by name gets > you what is _in_ that component. Instead of "make this list component contain > NULL" the command is saying "make this list component contain a list that > contains NULL". When you just assign NULL, it is like saying "make this > component of the list NULL" (i.e. not there). > > A vector is atomic, all components must be of the same data type. So any > _something_ (e.g. numeric, character, logical) is not the same as _nothing_ > (NULL). The concatenation function, when confronted with two somethings > separated by a nothing, simply drops the nothing. > > Jim > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >Thomas Lumley Assoc. Professor, Biostatistics tlumley at u.washington.edu University of Washington, Seattle