7

我想逐行生成一个数据帧,通过apply在值列表上使用某种风格和一个为每个值返回单行数据帧的函数。作为一个玩具示例,假设我的价值观是i = 1:3并且我拥有:

f <- function(i) {
    return(data.frame(img=letters[i], cached=F, i=i, stringsAsFactors=F))
}

我一直在搞乱sapply,,lapply一堆转置等但没有成功(例如,d = sapply(1:3, f)看起来很有希望,但似乎是我想要的转置,所以我尝试d = t(sapply(1:3,f))了,除了它是一个矩阵;因此我尝试了next d = as.data.frame(t(sapply(1:3, f))),它看起来是正确的(它打印出来就像我想要的那样),但仍然是错误的,因为如果你尝试对其进行子集化,你会发现它d[,1]实际上是一个列表)。

最后我得到了这个,它有效:

d = apply(data.frame(i=1:3), 2, f)$i

这给了我想要的框架:

  img cached i
1   a  FALSE 1
2   b  FALSE 2
3   c  FALSE 3

有没有更好/更干净的方式来表达上述内容?对我来说,这一切都感觉非常笨拙和过于复杂。


编辑:正如几位读者所提到的,这个“玩具示例”无疑太简单了,而且确实f(1:3)会按照我的要求去做。实际功能是基于 Web 的指标仪表板的一部分,从各种数据库表中提取数据,并制作我打算缓存的适度复杂的图(大多数时候它们变化相对缓慢)。我猜,相关的部分是该函数通常需要几个参数,而这些参数不是一个简单的序列1:n。所以,让我重写这个例子,让它更真实一点:

library(digest)
gkey   <- function(...) {
  args <- list(...)
  return(digest(paste(args,sep=".",collapse=".")));
}

f <- function(conn, table, checknew.query, plot.query, plot.fun, params) {
  latest.data = queryExec(conn, table, checknew.query, params)
  key = gkey(table, latest.data, plot.query, plot.fun, params)
  out = getFromCacheOrPlot(key, conn, table, plot.query, plot.fun, params)
  return(out)
}

wherequeryExec构建查询,执行它并检索结果,gkey()根据其参数计算哈希键,getFromCacheOrPlot()使用key构建文件名(.png 图像),如果存在则从缓存中检索它,否则生成它。它还返回一个 data.frame,其中一行给我们文件名、一个 html<img=...>简介来显示它、绘图是否在缓存中,以及绘图使用了哪些参数。

所有这些都用于 wiki 系统的插件中,并且某些页面有十几个情节或更多。

4

2 回答 2

8

do.call(rbind, lapply(i, f))会做你要求的......但也会这样做:

data.frame(img=letters[i], cached=F, i=i, stringsAsFactors=F)

就像这样:

f(i)
于 2013-01-15T22:31:52.087 回答
3

那这个呢?无需使用任何风格的apply功能

foo <- function(x){
  i <- seq_len(x)
  data.frame(img=letters[i], cached=FALSE, i=i, stringsAsFactors=F)
}


  foo(5)
  img cached i
1   a  FALSE 1
2   b  FALSE 2
3   c  FALSE 3
4   d  FALSE 4
5   e  FALSE 5
于 2013-01-15T19:49:31.197 回答