1

I'm performing a function over a list of lists using lapply. The sub-lists within the outer list are named, and I'd like to be able to access the names of those inner-lists to perform some conditional logic on. Let me walk through my attempts below:

# dput of my sample data
main_list <- structure(list(sublist1 = structure(list(df1 = structure(list(
    X1 = 0, X2 = 0), .Names = c("X1", "X2"), row.names = c(NA, 
-1L), class = "data.frame"), df2 = structure(list(X1 = 0, X2 = 0), .Names = c("X1", 
"X2"), row.names = c(NA, -1L), class = "data.frame")), .Names = c("df1", 
"df2")), sublist2 = structure(list(df3 = structure(list(X1 = 0, 
    X2 = 0), .Names = c("X1", "X2"), row.names = c(NA, -1L), class = "data.frame"), 
    df4 = structure(list(X1 = 0, X2 = 0), .Names = c("X1", "X2"
    ), row.names = c(NA, -1L), class = "data.frame")), .Names = c("df3", 
"df4"))), .Names = c("sublist1", "sublist2"))

Here are how my lists are named

> names(main_list)
[1] "sublist1" "sublist2"
> names(main_list$sublist1)
[1] "df1" "df2"

So the name of each inner list is sublist1 and sublist2 and then each of those sublists contain two data frames within.

Desired Output (Edited)

I want to be able to access the names of my sublists, i.e. sublist1 and sublist2 within a function to use during lapply. I edited my example function to have a more clear desired output:

> example <- function(input){
+   if(names(input)=="sublist1"){
+     return(1)
+   } else{
+     return(2)
+   }
+ }
> lapply(main_list,example)
$sublist1
[1] 2

$sublist2
[1] 2

Warning messages:
1: In if (names(input) == "sublist1") { :
  the condition has length > 1 and only the first element will be used
2: In if (names(input) == "sublist1") { :
  the condition has length > 1 and only the first element will be used

The proper output I want to receive would be:

> lapply(main_list,example)
$sublist1
[1] 1

$sublist2
[1] 2 

Attempts

Here are some of my unsuccessful attempts:

> lapply(main_list,names)
$sublist1
[1] "df1" "df2"

$sublist2
[1] "df3" "df4"

> lapply(main_list,colnames)
$sublist1
NULL

$sublist2
NULL

> test <- function(input){
   print(substitute(input))
 }
> lapply(main_list,test)
X[[i]]
X[[i]]
$sublist1
X[[i]]

$sublist2
X[[i]]

I can see the $sublist1 and $sublist2 appearing in my attempts, but I'm having issues actually storing and then acting upon those values.

ZachTurn
  • 636
  • 1
  • 5
  • 14
  • Could you be more specific about your desired output, instead of just giving pseudocode? One obvious option would be a loop. Another would be `Map(f, L, names(L))` with `f` written however you need. – Frank Jun 21 '16 at 01:45
  • Does this work: http://stackoverflow.com/questions/17499013/how-do-i-make-a-list-of-data-frames/17499462#17499462 – Mark Miller Jun 21 '16 at 01:57
  • I have not tried this with your data: http://stackoverflow.com/questions/9469504/access-and-preserve-list-names-in-lapply-function – Mark Miller Jun 21 '16 at 02:05
  • `names(input)` won't return `"sublist1"` unless `input` is `main_list`, just like `names(mtcars)` returns `"mpg" "cyl" ...`, not `"mtcars"`. Thus, skip the `lapply`, as you don't need to step inside your list. You can use `ifelse` to vectorize the equality checking (`if` isn't vectorized), but annoyingly `ifelse` strips attributes, including names, so you'll need to re-add them. Using a `magrittr` pipe so the order is clear: `ifelse(names(main_list) == 'sublist1', list(1), list(2)) %>% setNames(names(main_list))`. Edit, wrap it in a function, etc. – alistaire Jun 21 '16 at 03:57
  • Perhaps something like `mapply(function(lst, nm) { if (nm == "sublist1") ...}, main_list, names(main_list))`? – r2evans Jun 21 '16 at 04:38
  • Possible duplicate of [Access and preserve list names in lapply function](https://stackoverflow.com/questions/9469504/access-and-preserve-list-names-in-lapply-function) – Arsak Apr 24 '19 at 12:27

0 Answers0