我想将一个函数应用于列表中的列表。第二级列表由任意数量的字符串组成(这就是为什么,在我缺少的东西中,列表内列表数据结构是最合适的)。我想知道最有效的方法是什么。这是一个通过循环实现我想要的简单示例:
#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信息恢复到结果数据结构......这对我来说似乎更复杂但我对建议持开放态度。
答案 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