我有以下列表:
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))
但也许有更优雅/简洁/更新的东西?
答案 0 :(得分:2)
这与expand.grid
函数的作用非常接近;但是,它会返回一个data.frame(您可以考虑使用它)。但是转换为带有
# library(magrittr)
do.call(`expand.grid`, c(lst,stringsAsFactors = FALSE)) %>% split(., 1:nrow(.))
应该像你之后的行为一样
答案 1 :(得分:1)
我不知道它是否更优雅或简洁,我想它不是更新但是,它仍然可以是获得结果的另一种方式:
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