i have a nested list whose fundamental element is data frames, and i want to traverse this list recursively to do some computation of each data frame, finally to get a nested list of results in the same structure as the input. I know "rapply" is exactly for such kind of task, but i met a problem that, rapply actually goes even deeper than i want, i.e. it decomposes every data frame and applies to each column instead (because a data frame itself is a list in R).
我有一个嵌套列表,其基本元素是数据帧,我想递归遍历此列表以对每个数据帧进行一些计算,最后得到与输入结构相同的嵌套结果列表。我知道“rapply”正是为了这样的任务,但是我遇到了一个问题,rapply实际上比我想要的更深,即它分解每个数据帧并应用于每一列(因为数据帧本身就是一个列表)在R)。
One workaround i can think about is to convert each data frame to matrix, but it will force to uniform the data types, so i don't like it really. I want to know if there is any way to control the recursive depth of rapply. Any idea? Thanks.
我能想到的一个解决方法是将每个数据帧转换为矩阵,但它会强制统一数据类型,所以我真的不喜欢它。我想知道是否有任何方法可以控制rapply的递归深度。任何想法?谢谢。
1 个解决方案
#1
6
1. wrap in proto
用原型包裹
When creating your list structure try wrapping the data frames in proto objects:
创建列表结构时,尝试在proto对象中包装数据框:
library(proto)
L <- list(a = proto(DF = BOD), b = proto(DF = BOD))
rapply(L, f = function(.) colSums(.$DF), how = "replace")
giving:
赠送:
$a
Time demand
22 89
$b
Time demand
22 89
Wrap the result of your function in a proto object too if you want to further rapply
it;
如果你想进一步提升它,你也可以将你的函数的结果包装在一个proto对象中;
f <- function(.) proto(result = colSums(.$DF))
out <- rapply(L, f = f, how = "replace")
str(out)
giving:
赠送:
List of 2
$ a:proto object
.. $ result: Named num [1:2] 22 89
.. ..- attr(*, "names")= chr [1:2] "Time" "demand"
$ b:proto object
.. $ result: Named num [1:2] 22 89
.. ..- attr(*, "names")= chr [1:2] "Time" "demand"
2. write your own rapply alternative
2.写自己的替代品
recurse <- function (L, f) {
if (inherits(L, "data.frame")) f(L)
else lapply(L, recurse, f)
}
L <- list(a = BOD, b = BOD)
recurse(L, colSums)
This gives:
这给出了:
$a
Time demand
22 89
$b
Time demand
22 89
ADDED: second approach
增加:第二种方法
#1
6
1. wrap in proto
用原型包裹
When creating your list structure try wrapping the data frames in proto objects:
创建列表结构时,尝试在proto对象中包装数据框:
library(proto)
L <- list(a = proto(DF = BOD), b = proto(DF = BOD))
rapply(L, f = function(.) colSums(.$DF), how = "replace")
giving:
赠送:
$a
Time demand
22 89
$b
Time demand
22 89
Wrap the result of your function in a proto object too if you want to further rapply
it;
如果你想进一步提升它,你也可以将你的函数的结果包装在一个proto对象中;
f <- function(.) proto(result = colSums(.$DF))
out <- rapply(L, f = f, how = "replace")
str(out)
giving:
赠送:
List of 2
$ a:proto object
.. $ result: Named num [1:2] 22 89
.. ..- attr(*, "names")= chr [1:2] "Time" "demand"
$ b:proto object
.. $ result: Named num [1:2] 22 89
.. ..- attr(*, "names")= chr [1:2] "Time" "demand"
2. write your own rapply alternative
2.写自己的替代品
recurse <- function (L, f) {
if (inherits(L, "data.frame")) f(L)
else lapply(L, recurse, f)
}
L <- list(a = BOD, b = BOD)
recurse(L, colSums)
This gives:
这给出了:
$a
Time demand
22 89
$b
Time demand
22 89
ADDED: second approach
增加:第二种方法