1

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)
6
  • sounds like the ?compose function in the purrr package may be helpful for your case. Commented Jul 19, 2019 at 18:28
  • You find Map ugly? Commented Jul 19, 2019 at 18:49
  • 1
    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]]) }) Commented Jul 19, 2019 at 19:32
  • 1
    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? Commented Jul 20, 2019 at 8:26
  • 1
    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) Commented Jul 20, 2019 at 8:49

1 Answer 1

1

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)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.