idata.frame:なぜエラー「is.data.frame(df)は真実ではない」?
-
09-10-2019 - |
質問
私はExpと呼ばれる大きなデータフレームを使用しています(こちらをファイルします)R。では、パフォーマンスのために、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
おそらく私のエラーは、私がグループを指定している方法にありますか?誰かが私の模範を機能させる方法を知っていますか?
ETA:
私も試しました:
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の使用方法をまったく理解していないと思います。
解決
あなたが「大きな」データを使用していて、パフォーマンスを探していることを考えると、これは完璧にフィットしているようです 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
他のヒント
奇妙な行動ですが、ドキュメントでさえ、idata.frameは実験的であると言っています。おそらくバグを見つけました。おそらく、テストが.data.frame()であることをddplyの上部にある小切手を書き換えることができます。
いずれにせよ、これは(私のシステムで)時間を約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))
)
シェーンは、スクリプトの結果をキャッシュできるかどうかを別の投稿で尋ねました。私はあなたのワークフローについて本当に考えていませんが、これを実行して結果を毎日/時間ごとに保存するためにクロンをセットアップするのが最善かもしれません。