笛卡尔的产品,在一个列表中

时间:2022-07-18 22:04:47

I have the following list:

我有以下清单:

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

And I would to obtain the output:

我将得到输出:

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"
    )
)

For the moment, I use the code below:

目前,我使用下面的代码:

library(plyr)

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

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

But there's maybe something more elegant/concise/newer ?

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

2 个解决方案

#1


1  

I don't know if it is more elegant or concise and I guess it is not newer but, still, it can be another way of getting the results :

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

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

I benchmarked my solution and your plyr method on a list with 1000 "animals" and 50 "places" for each "animal" (I tried with more than that but it just took too long on my computer...) and here are the results (I didn't benchmark the magrittr method because I got an error with my "dummy" list) :

我基准测试解决方案和plyr方法列表与1000“动物”和“地方”,每个“动物”(我试着多,但是它在我的电脑上花了太长时间…)这是结果(我没有基准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

#2


2  

This is pretty close to what the expand.grid function does; however that returns a data.frame (which, you might consider using instead). But you convert to a list of lists of data.frames with

这和展开的很接近。网格函数;但是,它返回一个data.frame(您可以考虑使用它)。但是你要转换成一个数据列表

# library(magrittr)
do.call(`expand.grid`, c(lst,stringsAsFactors = FALSE)) %>% split(., 1:nrow(.))

which should behave like what you were after

你追求的是什么

#1


1  

I don't know if it is more elegant or concise and I guess it is not newer but, still, it can be another way of getting the results :

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

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

I benchmarked my solution and your plyr method on a list with 1000 "animals" and 50 "places" for each "animal" (I tried with more than that but it just took too long on my computer...) and here are the results (I didn't benchmark the magrittr method because I got an error with my "dummy" list) :

我基准测试解决方案和plyr方法列表与1000“动物”和“地方”,每个“动物”(我试着多,但是它在我的电脑上花了太长时间…)这是结果(我没有基准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

#2


2  

This is pretty close to what the expand.grid function does; however that returns a data.frame (which, you might consider using instead). But you convert to a list of lists of data.frames with

这和展开的很接近。网格函数;但是,它返回一个data.frame(您可以考虑使用它)。但是你要转换成一个数据列表

# library(magrittr)
do.call(`expand.grid`, c(lst,stringsAsFactors = FALSE)) %>% split(., 1:nrow(.))

which should behave like what you were after

你追求的是什么