如何使用apply逐行生成数据框?

时间:2013-01-15 19:43:57

标签: r dataframe apply

我想逐行生成一个数据帧,在值列表上使用一些apply的函数,并为每个值返回一行数据帧。作为一个玩具示例,假设我的值为i = 1:3且我有:

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

我一直在忙着sapplylapply,一堆转置等没有成功(例如,d = sapply(1:3, f)看起来很有希望,但似乎是转换我想要的是什么,所以我尝试d = t(sapply(1:3,f)),除了它是一个矩阵;因此我尝试了下一个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)
}

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

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

2 个答案:

答案 0 :(得分:8)

do.call(rbind, lapply(i, f))会做你所要求的......但也会如此:

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

一如既往:

f(i)

答案 1 :(得分: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