1

Passing names (or indicies) to lapply allows the element name to be accessed within the function (as per the solutions given here). How can the same approach be applied to deal with lists of lists?

In the example below, each list element ("A" and "B") is itself a list, containing multiple named dataframes ("df_001" and so on).

list_of_lists <- list("A" = list("df_001" = data.frame(X = 1, Y = 1), "df_002" = data.frame(X = 1, Y = 2), "df_003" = data.frame(X = 2, Y = 1)),
                      "B" = list("df_004" = data.frame(X = 1, Y = 1), "df_005" = data.frame(X = 1, Y = 2), "df_006" = data.frame(X = 2, Y = 1)))

I'd like to apply, to each of these dataframes, a function which can paste both its dataframe name (e.g. "df_001") and its parent list name (e.g. "A"). For example, generate a plot for each dataframe with a title alike "A: df_001" or "B: df_004" etc

I can do so for each seperate list element ("A" or "B"), as below

plot_with_name <- function(z) {
  dat <- list_of_lists[["A"]][[z]]
  plot(dat[, 1], dat[, 2],
       main = paste("A: ", z) )
}
lapply( names(list_of_lists[["A"]]), plot_with_name )
# then repeat, replacing "A" with "B"

but I'm curious as to whether this can be done without needing to split the list.

My proto-idea is to use a nested lapply call. The attempt below applies a function to all dataframes, but does not call the names. Perhaps it can be modified to do so (?)

lapply( list_of_lists, lapply, function(x) { plot(x[, 1],x[, 2]) } ) # generates plots WITHOUT names

Any help is greatly appreciated. Thanks

Community
  • 1
  • 1
pyg
  • 716
  • 6
  • 18
  • 1
    This is a bit of a work-around, but how about: `ul <- unlist(list_of_lists, rec=FALSE); Map(function(d,n) plot(d[,1],d[,2], main=n), ul, names(ul))` ? – thelatemail Feb 14 '17 at 05:00
  • Another work-around: `library(data.table); library(ggplot2); ggplot(melt(list_of_lists), aes(x = variable, y = value)) + geom_boxplot() + facet_wrap(~interaction(L1, L2))` – Henrik Feb 14 '17 at 05:20
  • thank you all for your suggestions. i've chosen @Chirayu's as the solution, though I appreciate it's by and large equivalent to the `Map()` suggestion – pyg Feb 16 '17 at 07:00

2 Answers2

1

Similar to thelatemail anwser:

xx=unlist(list_of_lists, recursive=FALSE)
mapply(plot, x = xx, main = names(xx), SIMPLIFY = FALSE)
Chirayu Chamoli
  • 2,076
  • 1
  • 17
  • 32
0

Not the most elegant solution, but it works:

nms_list <- names(list_of_lists)    

for (i in seq_along(nms_list)) {
  m <- length(list_of_lists[[nms_list[i]]])
  for (l in 1:m) {
    dat <- list_of_lists[[nms_list[i]]][[l]]
    plot(dat[, 1], dat[, 2],
       main = paste(nms_list[i],":",  names(list_of_lists[[nms_list[i]]])[l]))
  }
}
lizzie
  • 606
  • 6
  • 15