[R] recursive lapply and keeping track of data

Giovanni Gherdovich g.gherdovich at gmail.com
Mon Aug 14 20:43:27 CEST 2017


Hello,

I'm writing a program that takes a tree in input (nested lists) and
returns a copy of it replacing the leaves with something else (eg: a
computation done on the original leaves).
In the example below, the tree is composed by countries and cities,
and the leaves (children of the cities) are vectors of numbers. The
program takes this tree and replaces the vectors at the bottom by
their mean.

I use a recursive function and lapply, and I give names to the
returned list after I get them from lapply. I was happy until I
realised that when I have some anomaly in the data (in the example at
Spain/Madrid I have NULL instead of a vector -- I simulate an error
artificially with stop()) I have no way to trace where in the original
tree is the problem, as the names are lost when I do lapply. I was
thinking to use tryCatch() and do something smart at error/warning,
but I'm afraid the information is all lost.

Is there any obvious way I am missing that would give me the debug
information I need? In the example above ideally I'd like to know that
the program stopped at the path Spain/Madrid.


# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
data <- list("France" = list("Paris" = c(21, 34, 42),
                             "Marseille" = c(23, 51, 64),
                             "Toulouse" = c(78, 43, 25)),
             "Germany" = list("Berlin" = c(43, 20, 87),
                              "Munich" = c(89, 45, 34),
                              "Hamburg" = c(98, 78, 32)),
             "Spain" = list("Barcelona" = c(43, 49, 72),
                            "Madrid" = NULL,
                            "Valencia" = c(23, 23, 76)))

leaf.func <- function(data) {
        if(is.null(data)) stop()
        return(mean(data))
}

visit.level <- function(data, depth) {
        if (depth == 2) {
                return(leaf.func(data))
        } else {
                res <- lapply(data, visit.level, depth + 1)
                names(res) <- names(data)
                return(res)
        }
}

new.data <- visit.level(data, 0)
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~


Thanks,
Giovanni



More information about the R-help mailing list