我想拿出一个变种mapply(称它为xapply现在),它结合了功能(在某种程度上)的expand.grid和mapply.也就是说,对于一个功能FUN和参数列表L1,L2,L3,...的长度未知,但应该产生长度的列表n1*n2*n3(其中,ni是列表的长度i),这是施加的结果FUN到的元素的所有组合名单.
如果expand.grid用于生成列表而不是数据框列表,则可以使用它,但我记得列表可能是不一定适合数据框的事物列表.
如果有三个要扩展的列表,这个功能可以正常工作,但我很好奇一个更通用的解决方案.(FLATTEN未使用,但我可以想象这FLATTEN=FALSE将生成嵌套列表而不是单个列表...)
xapply3 <- function(FUN,L1,L2,L3,FLATTEN=TRUE,MoreArgs=NULL) {
retlist <- list()
count <- 1
for (i in seq_along(L1)) {
for (j in seq_along(L2)) {
for (k in seq_along(L3)) {
retlist[[count]] <- do.call(FUN,c(list(L1[[i]],L2[[j]],L3[[k]]),MoreArgs))
count <- count+1
}
}
}
retlist
}
Run Code Online (Sandbox Code Playgroud)
编辑:忘了返回结果.有人可能通过combn在那里制作一份指数清单来解决这个问题......
我想我对自己的问题有一个解决方案,但也许有人可以做得更好(而且我还没有实现FLATTEN=FALSE......)
xapply <- function(FUN,...,FLATTEN=TRUE,MoreArgs=NULL) {
L <- list(...)
inds <- do.call(expand.grid,lapply(L,seq_along)) ## Marek's suggestion
retlist <- list()
for (i in 1:nrow(inds)) {
arglist <- mapply(function(x,j) x[[j]],L,as.list(inds[i,]),SIMPLIFY=FALSE)
if (FLATTEN) {
retlist[[i]] <- do.call(FUN,c(arglist,MoreArgs))
}
}
retlist
}
Run Code Online (Sandbox Code Playgroud)
编辑:我尝试了@baptiste的建议,但这并不容易(或者不适合我)。我得到的最接近的是
xapply2 <- function(FUN,...,FLATTEN=TRUE,MoreArgs=NULL) {
L <- list(...)
xx <- do.call(expand.grid,L)
f <- function(...) {
do.call(FUN,lapply(list(...),"[[",1))
}
mlply(xx,f)
}
Run Code Online (Sandbox Code Playgroud)
这仍然不起作用。expand.grid确实比我想象的更灵活(尽管它创建了一个无法打印的奇怪数据框),但是内部发生了足够的魔法mlply,我无法完全让它工作。
这是一个测试用例:
L1 <- list(data.frame(x=1:10,y=1:10),
data.frame(x=runif(10),y=runif(10)),
data.frame(x=rnorm(10),y=rnorm(10)))
L2 <- list(y~1,y~x,y~poly(x,2))
z <- xapply(lm,L2,L1)
xapply(lm,L2,L1)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1310 次 |
| 最近记录: |