1
votes

Using base R, I would like to apply a different function to each element of a nested list. I know how to apply the same function to a nested list with

lapply(list, lapply, function).

However, I'm looking for an elegant way to apply a different function to each element. The code below works, but I find the use of

function(x) lapply(x, function(x))

is ugly so I'm hoping there's a more elegant solution.

Data <- list(
    Panel1 = list(
        DF1 = data.frame(A = rnorm(10), B = rnorm(10)),
        DF2 = data.frame(A = rnorm(10), B = rnorm(10))
    ),
    Panel2 = list(
        DF1 = data.frame(C = rnorm(10), D = rnorm(10)),
        DF2 = data.frame(C = rnorm(10), D = rnorm(10))
        )
)

Fns <- list(
    function(x) lapply(x, function(x) x[1:5, c("B", "A")]),
    function(x) lapply(x, function(x) x[1:5, c("D", "C")])
)

Map(function(a, b) b(a), Data, Fns)
1
sounds like the ?compose function in the purrr package may be helpful for your case.Chuan
You find Map ugly?Rui Barradas
This is another way to do it but I don't think it is more elegant lapply(1:2,function(f){ funx <- Fns[[f]] funx(Data[[f]]) })Mike
I have two questions: (1) you want to apply different functions over a nested list, but your example uses the same function (subsetting with []) and only the arguments differ. Do you want to do the latter or the former? (2) There might be more concise approaches using the tidyverse, but if I understand your question correctly, you are looking for a Base R approach, right?TimTeaFan
Further, if you want to apply the same function with different arguments, the next question would be: can the arguments be chosen by a function. Then also a nested lapply might work: sub_fn <- function(ls, x) lapply(ls, function(x) x[1:5, colnames(x)]) lapply(Data, sub_fn)TimTeaFan

1 Answers

1
votes

Alright I think I can answer my own question. This works and I think it is as simple as you can get with base R.

Data <- list(
    Panel1 = list(
        DF1 = data.frame(A = rnorm(10), B = rnorm(10)),
        DF2 = data.frame(A = rnorm(10), B = rnorm(10))
    ),
    Panel2 = list(
        DF1 = data.frame(C = rnorm(10), D = rnorm(10)),
        DF2 = data.frame(C = rnorm(10), D = rnorm(10))
    )
)

Fns <- list(
    function(x) x[1:5, c("B", "A")],
    function(x) x[1:5, c("D", "C")]
)

Map(function(a, b) lapply(a, b), Data, Fns)