简体   繁体   中英

How to Map() a function recursively (through nested lists) in R?

Disclaimer: this is not a duplicate of this question: How to combine rapply() and mapply(), or how to use mapply/Map recursively? On top of that question, I am asking how to incorporate extra arguments of functions into the recursion.

So I have lists:

A = list(list(list(c(1,2,3), c(2,3,4)),list(c(1,2,3),c(2,3,4))), list(c(4,3,2), c(3,2,1)))
B = list(list(list(c(1,2,3), c(2,3,4)),list(c(1,2,3),c(2,3,4))), list(c(4,3,2), c(3,2,1)))

And I need to apply different functions to it recursively that preserves the list structure. Presumably, a recursive function that does this goes like this, when the function is mean():

recursive = function(x, y){
  if(is.null(y)){
    if(is.atomic(x)){
      x*x
    } else{
      Map(recursive, x)
    }
  } else{
    if(is.atomic(y) && is.atomic(x)){
      x*y
    } else{
      Map(recursive, x, y)
    }
  }
}

So the desired result would be:

recursive(A,B)

I was wondering how could I generalize this recursion to any functions beyond just the hard-coded function(x,y) x*y here so that I could change functions conveniently? In that case, it would start with:

recursive = function(somefunction, x, y){
....
}

where

somefunction = function(x,y) x*y #or any other function taking x and y as inputs

Could anyone kindly show me a way out? Thank you so much.

You can use

recursive  <- function(fun, x, y) {
    if(is.atomic(x) && is.atomic(y)) {
        match.fun(fun)(x, y) 
    } else  {
        Map(recursive, x, y, MoreArgs=list(fun=fun))
    }
}

The reason is that Map calls mapply and mapply has a MoreArgs= parameter where you can specify other parameters you want to pass to the calling function that you do not want to iterate over.

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