大規模なデータセットとのいくつかのグループの組み合わせにおける平均とNAの数を計算したいと思います。これはおそらく、いくつかのテストデータで説明するのが最も簡単です。私はMacBook Proで最新バージョンのRを使用しています。また、data.tableパッケージもあります(データは1M行以上です)。 (注:これを投稿した後、私は誤って、以下の "m ="変数にmean()の代わりにsum()を使用していたことに気づきました。私はすべてを再実行したくないので編集しませんでした。 「がtはR、data.tableの複数の組み合わせを持つグループ別平均とnmissを計算する
set.seed(4)
YR = data.table(yr=1962:2015)
ID = data.table(id=10001:11000)
ID2 = data.table(id2 = 20001:20050)
DT <- YR[,as.list(ID), by = yr] # intentional cartesian join
DT <- DT[,as.list(ID2), by = .(yr, id)] # intentional cartesian join
rm("YR","ID","ID2")
# 2.7M obs, now add data
DT[,`:=` (ratio = rep(sample(10),each=27000)+rnorm(nrow(DT)))]
DT <- DT[round(ratio %% 5) == 0, ratio:=NA] # make some of the ratios NA
DT[,`:=` (keep = as.integer(rnorm(nrow(DT)) > 0.7)) ] # add in the indicator variable
# do it again
DT[,`:=` (ratio2 = rep(sample(10),each=27000)+rnorm(nrow(DT)))]
DT <- DT[round(ratio2 %% 4) == 0, ratio2:=NA] # make some of the ratios NA
DT[,`:=` (keep2 = as.integer(rnorm(nrow(DT)) > 0.7)) ] # add in the indicator variable
だから、私が持っているものの識別情報(年、ID、ID2)と私が要約したいデータがある)多くのことを重要だと思う:keep1 | 2、RATIO1 | 2。特にyr-idによって、私は平均とratio2をkeepとkeep2(したがってid2を圧縮する)を使って計算したいと思います。私はこれを、keep/keep2で計算比とratio2、またはkeep * ratio、keep2 * ratio、keep * ratio2とkeep2 * ratio2の行列乗算でサブセット化することによって、考えました。
まず、正しい答えを取得しますが、遅いです私はこれをやっている方法:
system.time(test1 <- DT[,.SD[keep == 1,.(m = sum(ratio,na.rm = TRUE),
nmiss = sum(is.na(ratio)))
],by=.(yr,id)])
user system elapsed
23.083 0.191 23.319
これは、ほぼ同時期に同じようにうまく動作します。私は.SD以内に最初のではなく、メインのデータをサブセットする方が速いかもしれないと思った:
system.time(test2 <- DT[keep == 1,.SD[,.(m = sum(ratio,na.rm = TRUE),
nmiss = sum(is.na(ratio)))
],by=.(yr,id)])
user system elapsed
23.723 0.208 23.963
これらのアプローチのいずれかとの問題は、私は、各keep
変数に対して別々の計算を行う必要があるということです。したがって、私はこの方法を試してみました:
system.time(test3 <- DT[,.SD[,.(m = sum(ratio*keep,na.rm = TRUE),
nmiss = sum(is.na(ratio*keep)))
],by=.(yr,id)])
user system elapsed
25.997 0.191 26.217
これは遅く、2、それは正しい数を取得していないで、私は一緒にすべての数式を配置することができます(私はratio*keep2
、ratio2*keep
とratio2*keep2
に追加することもできます)が、1。 NA(nmiss
列を参照してください):
> summary(test1)
yr id m nmiss
Min. :1962 Min. :10001 Min. : -2.154 Min. :0.000
1st Qu.:1975 1st Qu.:10251 1st Qu.: 30.925 1st Qu.:0.000
Median :1988 Median :10500 Median : 53.828 Median :1.000
Mean :1988 Mean :10500 Mean : 59.653 Mean :1.207
3rd Qu.:2002 3rd Qu.:10750 3rd Qu.: 85.550 3rd Qu.:2.000
Max. :2015 Max. :11000 Max. :211.552 Max. :9.000
> summary(test2)
yr id m nmiss
Min. :1962 Min. :10001 Min. : -2.154 Min. :0.000
1st Qu.:1975 1st Qu.:10251 1st Qu.: 30.925 1st Qu.:0.000
Median :1988 Median :10500 Median : 53.828 Median :1.000
Mean :1988 Mean :10500 Mean : 59.653 Mean :1.207
3rd Qu.:2002 3rd Qu.:10750 3rd Qu.: 85.550 3rd Qu.:2.000
Max. :2015 Max. :11000 Max. :211.552 Max. :9.000
> summary(test3)
yr id m nmiss
Min. :1962 Min. :10001 Min. : -2.154 Min. : 0.00
1st Qu.:1975 1st Qu.:10251 1st Qu.: 30.925 1st Qu.: 2.00
Median :1988 Median :10500 Median : 53.828 Median : 4.00
Mean :1988 Mean :10500 Mean : 59.653 Mean : 4.99
3rd Qu.:2002 3rd Qu.:10750 3rd Qu.: 85.550 3rd Qu.: 8.00
Max. :2015 Max. :11000 Max. :211.552 Max. :20.00
YR-idで要約情報の私の4の組み合わせを取得するための最速の方法は何ですか? は今、私はオプション1または2を使用していること(キープのために、再びkeep2に一回)を2回繰り返し
ブリリアント。私はまだここで詳細を学んでおり、冗長オプションについても知らなかった。 –
パート2は何ですか:2番目の方法(test3)は機能しません。(私は思う)ratio = keepはNAを0にしても保持するからです。sum(is.na(ratios [keep] ))をサブセット比に変換し、is.na()関数を評価しますか?実際のデータには7つのバージョンの「保存」があり、これを7回繰り返して7つのデータセットを再マージする必要があるため、この2番目のアプローチを使用したいと思います。それはすべてのステップでそれを行うことがずっと良いでしょう。 –
@JesseBlocherについては、「NA」が異なる理由についての編集を参照してください。私は、複数のキープとレシオのペアのためのループよりも、これを一度に行う方法を思いついたわけではありません。 – mt1022