On 19.05.2011 14:58, Duncan Murdoch wrote: > On 19/05/2011 8:15 AM, Janko Thyson wrote: >> Dear list, >> >> I hope this is the right place to post a feature request. If there's >> exists a more formal channel (e.g. as for bug reports), I'd appreciate a >> pointer. > > This is a good place to post. > >> >> I work a lot with named nested lists with arbitrary degrees of >> "nestedness". In order to retrieve the names and/or values of "bottom >> layer/bottom tier", I love the functionality of 'unlist()', or >> 'names(unlist(x))', respectively as it avoids traversing the nested >> lists via recursive loop constructs. I'm also aware that the general >> suggestion is probably to keep nestedness as low as possible when >> working with lists, but arbitrary deeply nested lists came in quite >> handy for me as long as each element is named and as long as I can >> quickly add and retrieve element values via "name paths". >> >> Here's a little example list: >> lst<- list(a=list(a.1=list(a.1.1=NA, a.1.2=5), a.2=list()), b=NULL) >> >> It would be awesome if 'unlist(x)' could be extended with the following >> functionality: >> >> 1) An argument such as 'delim' that controls how the respective layer >> names are pasted. >> Right now, they are always separated by a dot: >> > names(unlist(lst)) >> [1] "a.a.1.a.1.1" "a.a.1.a.1.2" >> Desired: >> > names(unlist(lst, delim="/")) >> [1] "a/a.1/a.1.1" "a/a.1/a.1.2" >> > names(unlist(lst, delim="_")) >> [1] "a_a.1_a.1.1" "a_a.1_a.1.2" >> >> 2) An argument that allows to include either elements of zero length or >> of value NULL to be *included* in the resulting output. >> Right now, they are dropped (which makes perfect sense as NULL values >> and zero length values are dropped in vectors): >> > c(1,2, NULL, numeric()) >> [1] 1 2 >> > unlist(lst) >> a.a.1.a.1.1 a.a.1.a.1.2 >> NA 5 >> Desired: >> > unlist(lst, delim="/", keep.special=TRUE) >> $a/a.1/a.1.1 >> [1] NA >> >> $a/a.1/a.1.2 >> [1] 5 >> >> $a/a.2 >> list() >> >> $b >> NULL >> Of course, this would not be a true 'unlist' anymore, but something like >> 'retrieveBottomLayer()'. >> >> Thanks a lot for providing such fast stuff as 'unlist()'! Unfortunately, >> I don't know my way around internal C routines and therefore I would >> greatly appreciate if core team developers would consider my two >> suggestions. > > The suggestions seem reasonable, but are difficult to implement. The > problem is that unlist() is a generic function, but there's no > unlist.default() in R: the default and method dispatch are > implemented at the C level. Normally adding arguments to the default > method doesn't cause problems elsewhere, because methods only need to > be compatible with the generic. But since there's no way to modify > the argument list of the default method in this case, the generic > function would need to be modified, and that means every unlist method > would need to be modified too. > > So I wouldn't want to take this on.
Okay, get it. Thanks for the insight. > > In case someone else does, I'd suggest a different change than the > "keep.special" argument. I think a "coerce=TRUE" argument would be > better: If TRUE, you get the current behaviour, which coerces > components according to the hierarchy listed on the help page. If > FALSE, then no coercion is done, and unlist() just flattens the list > into a new one, e.g. > > unlist( list(1, 2, NULL, list("A", "B")), coerce=FALSE) > > would return list(1, 2, NULL, "A", "B") instead of c("1", "2", "A", "B"). > > One workaround I thought of was to add an element to the list that > couldn't be coerced, but this doesn't work. For example: > > e <- environment() # can't be coerced > x <- list(1, 2, NULL, list("A", "B"), e) > unlist(x) > > # Returns list(1,2,"A","B",e) > > I think it would be reasonable for this version to retain the NULL, > since it is not doing any coercion. Thanks for taking the time to address this. A function that also seemed pretty fast to me with respect to retrieving list structures is 'str(x)' and I thought about rewriting it to have it return the desired result. But as far as I understand the 'str.default()' method also "just" depends on recursive looping. Can you think of any other more efficient way to get the job done? Best regards, Janko > > Duncan Murdoch > > > -- ------------------------------------------------------------------------ *Janko Thyson* janko.thy...@googlemail.com <mailto:janko.thy...@googlemail.com> Jesuitenstraße 3 D-85049 Ingolstadt Mobile: +49 (0)176 83294257 This e-mail and any attachment is for authorized use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. [[alternative HTML version deleted]]
______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel