简体   繁体   中英

How do I preserve list names when working with nested lists?

The advantage of using plyr 's llply over lapply is that it preserves list names. See ?llply for an explanation. I love that feature but cannot seem to get it to work in the case of a nested list. Example:

library(plyr) 
m <- as.list(1:2)
names(m) <- c('M1', 'M2')
foo <- list(m, m)
names(foo) <- paste0("R", 1:2)


result <- ldply(foo, function(x){
        ldply(x, function(z) { data.frame(a=z, b= z^2)})
})
> result
  .id a b
1  M1 1 1
2  M2 2 4
3  M1 1 1
4  M2 2 4

# if I don't operate on the inner list, I can preserve the outer list's names
result2 <- ldply(foo, function(x){
     data.frame(a = x[[1]], b = x[[1]]^2)
    })
> result2
  .id a b
1  R1 1 1
2  R2 1 1

Note that result does not contain R1 and R2 (which would get added in as .id if I didn't operate on the nested list inside each element of foo as is the case with result2 ). How do I make sure I get the outer list names added in when working on nested lists?

It seems that the column name is the problem:

result <- ldply(foo, function(x){
    df <- ldply(x, function(z) { data.frame(a=z, b= z^2)})
    names(df)[1] <- ".id2"; df
})
result
  .id .id2 a b
1  R1   M1 1 1
2  R1   M2 2 4
3  R2   M1 1 1
4  R2   M2 2 4

The problem is that ldply does not assign to the .id variable if there is already one. If you look at the results of one of your inner ldply once, it is fine:

> ldply(foo[[1]], function(z) { data.frame(a=z, b= z^2)})
  .id a b
1  M1 1 1
2  M2 2 4

Rename it out of the way and it works as expected.

result <- ldply(foo, function(x){
    rename(ldply(x, function(z) { data.frame(a=z, b= z^2)}),
           c(".id" = ".id2"))
})

gives

> result
  .id .id2 a b
1  R1   M1 1 1
2  R1   M2 2 4
3  R2   M1 1 1
4  R2   M2 2 4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM