【问题标题】:idata.frame: Why error "is.data.frame(df) is not TRUE"?idata.frame:为什么错误“is.data.frame(df) is not TRUE”?
【发布时间】:2011-04-28 05:10:36
【问题描述】:

我正在使用 R 中名为 exp (file here) 的大型数据框。出于性能考虑,建议我从 plyr 中检查 idata.frame() 函数。但我觉得我用错了。

我原来的电话,很慢但有效:

df.median<-ddply(exp, 
                 .(groupname,starttime,fPhase,fCycle), 
                 numcolwise(median), 
                 na.rm=TRUE)

使用 idata.frame,Error: is.data.frame(df) is not TRUE

library(plyr)
df.median<-ddply(idata.frame(exp), 
                 .(groupname,starttime,fPhase,fCycle), 
                 numcolwise(median), 
                 na.rm=TRUE)

所以,我想,也许这是我的数据。所以我尝试了baseball 数据集。 idata.frame 示例工作正常:dlply(idata.frame(baseball), "id", nrow) 但如果我尝试使用 baseball 进行类似于我想要的调用的操作,它就行不通了:

bb.median<-ddply(idata.frame(baseball), 
                 .(id,year,team), 
                 numcolwise(median), 
                 na.rm=TRUE)
>Error: is.data.frame(df) is not TRUE

也许我的错误在于我如何指定分组?有人知道如何使我的示例工作吗?

预计到达时间:

我也试过了:

groupVars <- c("groupname","starttime","fPhase","fCycle")
voi<-c('inadist','smldist','lardist')

i<-idata.frame(exp)
ag.median <- aggregate(i[,voi], i[,groupVars], median)
Error in i[, voi] : object of type 'environment' is not subsettable

它使用更快的方法来获取中位数,但会给出不同的错误。我认为我根本不了解如何使用 idata.frame。

【问题讨论】:

  • 是的,idata.frame 仍处于试验阶段,因此最好直接使用它而不是使用像 colwise 这样的汇总函数
  • 鉴于您正在寻找大数据的性能,我会花时间查看data.table

标签: performance r plyr data.table


【解决方案1】:

奇怪的行为,但即使在文档中它也说 idata.frame 是实验性的。你可能发现了一个错误。也许您可以重写 ddply 顶部的检查,即测试 is.data.frame()。

无论如何,这会减少大约 20% 的时间(在我的系统上):

system.time(df.median<-ddply(exp, .(groupname,starttime,fPhase,fCycle), function(x) data.frame(
inadist=median(x$inadist),
smldist=median(x$smldist),
lardist=median(x$lardist),
inadur=median(x$inadur),
smldur=median(x$smldur),
lardur=median(x$lardur),
emptyct=median(x$emptyct),
entct=median(x$entct),
inact=median(x$inact),
smlct=median(x$smlct),
larct=median(x$larct),
na.rm=TRUE))
) 

Shane 在另一篇文章中询问您是否可以缓存脚本的结果。我真的不知道你的工作流程,但最好设置一个计时来运行它并存储结果,每天/每小时一次。

【讨论】:

  • 有趣的是,指定列会加快速度(在我的系统上也是如此),但到目前为止,最快的解决方案是使用aggregate()。无论如何,我在这个问题中使用旧的慢调用的原因是因为它导致idata.frame() 窒息。我有很多使用 exp 数据帧的调用,我想如果我可以替换一个 idata.frame,它可能会显着加快所有调用。
  • 您可以在此调用中使用idata.frame - 但它只会提高大约 10% 的速度,因为您没有进行那么多拆分。
  • 是的,aggregate 目前将击败 ddply + colwise。思考如何为下一个版本做得更好。
【解决方案2】:

鉴于您正在处理“大”数据并寻求性能,这似乎非常适合 data.table

特别是lapply(.SD,FUN).SDcols 参数与by

设置data.table

library(data.table)
DT <- as.data.table(exp)
iexp <- idata.frame(exp)

哪些列是numeric

numeric_columns <- names(which(unlist(lapply(DT, is.numeric))))



dt.median <- DT[, lapply(.SD, median), by = list(groupname, starttime, fPhase, 
    fCycle), .SDcols = numeric_columns]

一些基准测试

library(rbenchmark)
benchmark(data.table = DT[, lapply(.SD, median), by = list(groupname, starttime, 
    fPhase, fCycle), .SDcols = numeric_columns], 
 plyr = ddply(exp, .(groupname, starttime, fPhase, fCycle), numcolwise(median), na.rm = TRUE), 
 idataframe = ddply(exp, .(groupname, starttime, fPhase, fCycle), function(x) data.frame(inadist = median(x$inadist), 
        smldist = median(x$smldist), lardist = median(x$lardist), inadur = median(x$inadur), 
        smldur = median(x$smldur), lardur = median(x$lardur), emptyct = median(x$emptyct), 
        entct = median(x$entct), inact = median(x$inact), smlct = median(x$smlct), 
        larct = median(x$larct), na.rm = TRUE)), 
 aggregate = aggregate(exp[, numeric_columns],
                       exp[, c("groupname", "starttime", "fPhase", "fCycle")], 
              median), 
 replications = 5)

##         test replications elapsed relative user.self 
## 4  aggregate            5    5.42    1.789      5.30   
## 1 data.table            5    3.03    1.000      3.03    
## 3 idataframe            5   11.81    3.898     11.77       
## 2       plyr            5    9.47    3.125      9.45       

【讨论】:

  • 不错!我可能会将其包含在下一次重构中。
猜你喜欢
  • 1970-01-01
  • 2023-02-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多