我想逐行生成一个数据帧,在值列表上使用一些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))
,除了它是一个矩阵;因此我尝试了下一个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系统的插件中,某些页面有十几个或更多。
答案 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