[R] Extracting elements out of list in list in list

Rainer M Krug Rainer at krugs.de
Mon Jan 19 10:56:51 CET 2015


Brian Diggs <brian.s.diggs at gmail.com> writes:

> On 1/16/15 9:34 AM, Bert Gunter wrote:
>> Chee Hee's approach is both simpler and almost surely more efficient,
>> but I wanted to show another that walks the tree (i.e. the list)
>> directly using recursion at the R level to pull out the desired
>> components. This is in keeping with R's "functional" programming
>> paradigm and avoids the use of regular expressions to extract the
>> desired components from the unlist() version.
>>
>> extr <- function(x,nm){
>>    if(is.recursive(x)){
>>      wh <- names(x) %in% nm
>>      c(x[wh],lapply(x[!wh],extr,nm=nm) )
>>    } else NULL
>> }
>>
>> ## The return value contains a bunch of NULLs; so use unlist() to remove them
>>
>>> unlist(extr(x,"A"))
>> f1.x1.A f1.x2.A f2.x3.A f2.x4.A
>>       11      12      13      14
>>
>>
>> I would welcome any possibly "slicker" versions of the above.
>
> I don't know if you would consider this "slicker" or not, but it does
> not give a lot of NULLs that have to be filtered out. It does so by
> checking if the component of the list is itself a list before
> recursively calling extr on it, and by using unlist internally.
>
> extr <- function(x, nm) {
>     if(is.list(x)) {
>         sublists <- sapply(x, is.list)
>         c(unlist(x[nm]), unlist(sapply(x[sublists], extr, nm)))
>     } else {
>         message("Argument is not a list")
>         NULL
>     }
> }
>
> Running it on x gives
>
>> extr(x, "A")
> [1] 11 12 13 14
>

It indeed eliminates the NULLs - but calling the unlist in the
recursion, could be inefficient again. 
But benchmarks would be needed to see if this is the case.

But I am reallywondering that there is nothing available to do this easily.

I might look into this when I have some time.

Thanks everybody,

Rainer

>
>> Cheers,
>> Bert
>>
>> Bert Gunter
>> Genentech Nonclinical Biostatistics
>> (650) 467-7374
>>
>> "Data is not information. Information is not knowledge. And knowledge
>> is certainly not wisdom."
>> Clifford Stoll
>>
>>
>>
>>
>> On Fri, Jan 16, 2015 at 7:23 AM, Chel Hee Lee <chl948 at mail.usask.ca> wrote:
>>> This approach may not be fancy as what you are looking for.
>>>
>>>> xl <- unlist(x)
>>>> xl[grep("A", names(xl))]
>>> f1.x1.A f1.x2.A f2.x3.A f2.x4.A
>>>       11      12      13      14
>>>>
>>>
>>> I hope this helps.
>>>
>>> Chel Hee Lee
>>>
>>> On 01/16/2015 04:40 AM, Rainer M Krug wrote:
>>>>
>>>> Hi
>>>>
>>>> Consider the following variable:
>>>>
>>>> --8<---------------cut here---------------start------------->8---
>>>> x1 <- list(
>>>>     A = 11,
>>>>     B = 21,
>>>>     C = 31
>>>> )
>>>>
>>>> x2 <- list(
>>>>     A = 12,
>>>>     B = 22,
>>>>     C = 32
>>>> )
>>>>
>>>> x3 <- list(
>>>>     A = 13,
>>>>     B = 23,
>>>>     C = 33
>>>> )
>>>>
>>>> x4 <- list(
>>>>     A = 14,
>>>>     B = 24,
>>>>     C = 34
>>>> )
>>>>
>>>> y1 <- list(
>>>>     x1 = x1,
>>>>     x2 = x2
>>>> )
>>>>
>>>> y2 <- list(
>>>>     x3 = x3,
>>>>     x4 = x4
>>>> )
>>>>
>>>> x <- list(
>>>>     f1 = y1,
>>>>     f2 = y2
>>>> )
>>>> --8<---------------cut here---------------end--------------->8---
>>>>
>>>>
>>>> To extract all fields named "A" from y1, I can do
>>>>
>>>> ,----
>>>> | > sapply(y1, "[[", "A")
>>>> | x1 x2
>>>> | 11 12
>>>> `----
>>>>
>>>> But how can I do the same for x?
>>>>
>>>> I could put an sapply into an sapply, but this would be less then
>>>> elegant.
>>>>
>>>> Is there an easier way of doing this?
>>>>
>>>> Thanks,
>>>>
>>>> Rainer
>

-- 
Rainer M. Krug
email: Rainer<at>krugs<dot>de
PGP: 0x0F52F982
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 494 bytes
Desc: not available
URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20150119/0146db4f/attachment.bin>


More information about the R-help mailing list