将函数应用于列表中的列表

时间:2015-07-15 11:34:44

标签: r lapply

我想将一个函数应用于列表中的列表。第二级列表由任意数量的字符串组成(这就是为什么,在我缺少的东西中,列表内列表数据结构是最合适的)。我想知道最有效的方法是什么。这是一个通过循环实现我想要的简单示例:

#sample data
set.seed(12345)
mylist <- list()
mylist[[1]] <- list(sample(letters,3),sample(letters,4),sample(letters,5))
mylist[[2]] <- list(sample(letters,4),sample(letters,5))
mylist[[3]] <- list(sample(letters,5),sample(letters,3),sample(letters,4),sample(letters,2)

#working loop example
result <- list()
for(i in 1:length(mylist)){
  result[[i]] <- lapply(mylist[[i]],function(x,l) 0  + (l %in% x),l=letters)
}

有没有一种简单的方法可以将此循环转换为单行解决方案?

更广泛的背景是我想进一步减少result中的数据,例如(在这个简单的情况下)加起来得到每个字母出现在i上的次数,或者mylist的原始维度。所以最终的目标是:

final.result <- lapply(result,Reduce,f='+')

所以另一种方法是简单地将函数应用于unlist(mylist),然后以某种方式将i信息恢复到结果数据结构......这对我来说似乎更复杂但我对建议持开放态度。

1 个答案:

答案 0 :(得分:4)

对于您的第一个结果,您可以这样做:

result <- lapply(mylist, function(x){lapply(x, function(y) {+(letters %in% y)})})

要获得最终结果,您可以执行以下操作:

final.result <- lapply(mylist, function(x){colSums(do.call("rbind",lapply(x, function(y) {+(letters %in% y)})))})

或者,使用result

lapply(result, function(x){colSums(do.call("rbind", x))})

两者都给:

final.result
#[[1]]
# [1] 1 0 0 2 0 0 0 1 0 0 0 1 0 1 0 0 0 0 2 0 0 1 0 2 0 1
#
#[[2]]
# [1] 1 0 0 0 1 0 0 0 0 2 2 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1
#
#[[3]]
# [1] 1 0 0 0 1 1 0 0 1 1 0 0 1 1 1 0 1 1 1 1 0 0 0 0 1 1