expand.grid和mapply的组合? [英] combination of expand.grid and mapply?

查看:65
本文介绍了expand.grid和mapply的组合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试提出mapply的变体(现在称为xapply),该变体结合了expand.gridmapply的功能(某种).也就是说,对于函数FUN和参数L1L2L3,...的列表,长度未知的,它应生成长度为n1*n2*n3的列表(其中ni是列表i的长度),这是将FUN应用于列表元素的所有组合的结果.

I am trying to come up with a variant of mapply (call it xapply for now) that combines the functionality (sort of) of expand.grid and mapply. That is, for a function FUN and a list of arguments L1, L2, L3, ... of unknown length, it should produce a list of length n1*n2*n3 (where ni is the length of list i) which is the result of applying FUN to all combinations of the elements of the list.

如果expand.grid用来生成列表列表而不是数据框架,则可能可以使用它,但是我要记住,列表可能是不一定很好地适合数据框架的事物的列表

If expand.grid worked to generate lists of lists rather than data frames, one might be able to use it, but I have in mind that the lists may be lists of things that won't necessarily fit into a data frame nicely.

如果恰好有三个要扩展的列表,则此功能正常运行,但我对更通用的解决方案感到好奇. (FLATTEN未使用,但我可以想象FLATTEN=FALSE会生成嵌套列表,而不是单个列表...)

This function works OK if there are exactly three lists to expand, but I am curious about a more generic solution. (FLATTEN is unused, but I can imagine that FLATTEN=FALSE would generate nested lists rather than a single list ...)

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
}

编辑:忘记返回结果.也许可以通过使用combn列出索引并从那里开始...

edit: forgot to return the result. One might be able to solve this by making a list of the indices with combn and going from there ...

推荐答案

我认为我对自己的问题有解决方案,但也许有人可以做得更好(而且我还没有实现FLATTEN=FALSE ...)

I think I have a solution to my own question, but perhaps someone can do better (and I haven't implemented 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
}

编辑:我尝试了@baptiste的建议,但这并不容易(或者对我而言并非如此).我最接近的是

edit: I tried @baptiste's suggestion, but it's not easy (or wasn't for me). The closest I got was

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

仍然不起作用. expand.grid确实比我想象的要灵活(尽管它创建了一个无法打印的怪异数据框),但是mlply内部发生了很多不可思议的魔术.

which still doesn't work. expand.grid is indeed more flexible than I thought (although it creates a weird data frame that can't be printed), but enough magic is happening inside mlply that I can't quite make it work.

这是一个测试用例:

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)

这篇关于expand.grid和mapply的组合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆