我想逐行生成一个数据帧,通过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 系统的插件中,并且某些页面有十几个情节或更多。