列表中类似于笛卡尔积

博维尔上校

我有以下清单:

lst = list(
    cat = c("room","shower","garden"),
    dog = c("street", "garden")
)

我将获得输出:

list(
    list(
        animal="cat",
        place ="room"
    ),
    list(
        animal="cat",
        place ="shower"
    ),
    list(
        animal="cat",
        place ="garden"
    ),
    list(
        animal="dog",
        place ="street"
    ),
    list(
        animal="dog",
        place ="garden"
    )
)

目前,我使用以下代码:

library(plyr)

grasp <- function(animal, places)
{
    llply(places, function(u) list(animal=animal, place=u))
}

Reduce(append, Map(grasp, names(lst), lst))

但是,也许还有一些更优雅/简洁/更新的东西?

ath

我不知道它是否更优雅或更简洁,我想它不是新的,但是,它仍然可以是获得结果的另一种方式:

unlist(lapply(names(lst),function(x){
                             lapply(lst[[x]],function(y,x){
                                               list(animal=x,place=y)
                                                },x=x)
                              }),recursive=F)

plyr在一个列表中对我的解决方案和您的方法进行了基准测试,每个“动物”有1000个“动物”和50个“位置”(我尝试了更多,但是在我的计算机上花了太长时间...),这是结果(我没有对magrittr方法进行基准测试,因为我的“虚拟”列表出现错误):

base_meth<-function(){unlist(lapply(names(lst),function(x){lapply(lst[[x]],function(y,x){list(animal=x,place=y)},x=x)}),recursive=F)}

plyr_meth<-function(){Reduce(append, Map(grasp, names(lst), lst))}

microbenchmark(base_meth(),plyr_meth(),unit="relative",times=500)

 # Unit: relative
 #        expr      min       lq     mean   median       uq      max neval cld
 # base_meth() 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000   500  a 
 # plyr_meth() 6.885256 6.844418 5.798948 6.527788 5.475684 7.589215   500   b

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章