[解決済み] 大規模なdata.tableのNAを置換する最速の方法
質問
私は、大きな data.table 200k行200列の中に多くの欠損値が散らばっています。 これらの欠損値を可能な限り効率的にゼロに再コード化したい。
2つの選択肢がありますね。
1: data.frameに変換して使用する。
このような
2: ある種のクールなdata.tableサブ設定コマンド
タイプ1のかなり効率的な解決策で満足する。data.frameに変換してからdata.tableに戻しても、それほど時間はかからないでしょう。
どのように解決するのですか?
を使った解決策を紹介します。
データテーブル
's
:=
演算子で、AndrieとRamnathの回答に基づいています。
require(data.table) # v1.6.6
require(gdata) # v2.8.2
set.seed(1)
dt1 = create_dt(2e5, 200, 0.1)
dim(dt1)
[1] 200000 200 # more columns than Ramnath's answer which had 5 not 200
f_andrie = function(dt) remove_na(dt)
f_gdata = function(dt, un = 0) gdata::NAToUnknown(dt, un)
f_dowle = function(dt) { # see EDIT later for more elegant solution
na.replace = function(v,value=0) { v[is.na(v)] = value; v }
for (i in names(dt))
eval(parse(text=paste("dt[,",i,":=na.replace(",i,")]")))
}
system.time(a_gdata = f_gdata(dt1))
user system elapsed
18.805 12.301 134.985
system.time(a_andrie = f_andrie(dt1))
Error: cannot allocate vector of size 305.2 Mb
Timing stopped at: 14.541 7.764 68.285
system.time(f_dowle(dt1))
user system elapsed
7.452 4.144 19.590 # EDIT has faster than this
identical(a_gdata, dt1)
[1] TRUE
f_dowleは参照によってdt1を更新していることに注意してください。ローカルコピーが必要な場合は、明示的に
copy
関数は、データセット全体のローカルコピーを作成するために必要である。
setkey
,
key<-
と
:=
はコピーオンライトしない。
次に、f_dowleがどこに時間を費やしているのかを見てみましょう。
Rprof()
f_dowle(dt1)
Rprof(NULL)
summaryRprof()
$by.self
self.time self.pct total.time total.pct
"na.replace" 5.10 49.71 6.62 64.52
"[.data.table" 2.48 24.17 9.86 96.10
"is.na" 1.52 14.81 1.52 14.81
"gc" 0.22 2.14 0.22 2.14
"unique" 0.14 1.36 0.16 1.56
... snip ...
そこで、私が注目するのは
na.replace
と
is.na
ここで、いくつかのベクターコピーとベクタースキャンがあります。これらの問題は,小さなna.replace C関数を書くことでかなり簡単に解決できます。
NA
ベクター内の参照によって そうすれば、少なくとも20秒は半分になると思います。そのような関数はRのパッケージに存在するのでしょうか?
その理由
f_andrie
の全体をコピーしてしまうため、失敗する可能性があります。
dt1
の全体と同じ大きさの論理的な行列を作るか、あるいは
dt1
を数回繰り返す。他の2つのメソッドは、一度に1つの列に対して動作します。
NAToUnknown
).
EDIT (コメントでRamnathから要求された、よりエレガントな解決策) :
f_dowle2 = function(DT) {
for (i in names(DT))
DT[is.na(get(i)), (i):=0]
}
system.time(f_dowle2(dt1))
user system elapsed
6.468 0.760 7.250 # faster, too
identical(a_gdata, dt1)
[1] TRUE
最初からそのようにすればいいのに!と思いました。
EDIT2 (1年以上経った現在)
また
set()
. を呼び出すことによる(小さな)オーバーヘッドを避けることができるので、ループスルーされるカラムが多い場合は、この方が高速になることがあります。
[,:=,]
をループ内で使用します。
set
は、ループ可能な
:=
. 参照
?set
.
f_dowle3 = function(DT) {
# either of the following for loops
# by name :
for (j in names(DT))
set(DT,which(is.na(DT[[j]])),j,0)
# or by number (slightly faster than by name) :
for (j in seq_len(ncol(DT)))
set(DT,which(is.na(DT[[j]])),j,0)
}
関連
-
データボックス内の行/列の削除/追加を行うR言語
-
[解決済み] データフレームを結合(マージ)する方法(内側、外側、左側、右側)
-
[解決済み] リストに値が存在するかどうかを確認する最速の方法
-
[解決済み] R dataframeでNAの値をゼロに置き換えるには?
-
[解決済み] 非常に大きなテーブルをデータフレームとして高速に読み込む
-
[解決済み] [Solved] data.frameで全てまたは一部のNA(欠損値)を含む行を削除する。
-
[解決済み】data.table vs dplyr:一方がうまくできない、またはうまくできないことを行うことができますか?
-
[解決済み】エラー:Rで関数が見つかりませんでした。
-
[解決済み] セッションが作成されません。このバージョンのChromeDriverはChromeバージョンにしか対応していません ChromeDriver ChromeでSeleniumを使用した場合の74エラー
-
[解決済み] 2つの単語の最初の文字を大文字にします。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
RStudio の "plot.new() : figure margins too large" 問題を解決する。
-
R 描画エラー plot.new() : 図形の余白が大きすぎる
-
[解決済み] 0の値をすべてNAに置き換える
-
[解決済み] Rの%*%の意味 [重複]について
-
[解決済み] R dataframeでNAの値をゼロに置き換えるには?
-
[解決済み] パッケージ 'xxx' は利用できません (for R version x.y.z) 」という警告にどのように対処したらよいですか?
-
[解決済み] Rでtrycatchの書き方
-
[解決済み] ベクトル中のある要素のインデックスを求めるR関数はありますか?
-
[解決済み] ggplot2 を使って 2 つの変数を同じグラフに線でプロットする
-
[解決済み】data.table vs dplyr:一方がうまくできない、またはうまくできないことを行うことができますか?