我想計算與具有大數據集的幾個組合的NA的平均值和計數值。這可能是最容易解釋的一些測試數據。我在Macbook Pro上使用最新版本的R,並使用data.table包(數據很大,> 1M行)。 (注意:在發佈這個帖子後,我注意到我意外地使用了sum()而不是mean()作爲下面的「m =」變量。我沒有編輯它,因爲我不想重新運行所有的東西, 「T認爲它很重要,許多)按R計算平均值和多個組合的組合,data.table
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比1 | 2。特別是通過yr-id,我想使用keep和keep2(因此壓縮id2)來計算平均比率和ratio2。我想通過keep/keep2計算比率和ratio2或者通過保持*比率,keep2 *比率,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
這讓我把所有的公式在一起,但1是比較慢和2(我可以在ratio*keep2
,ratio2*keep
和ratio2*keep2
添加)它沒有得到正確數量的NAS(見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)
輝煌。我仍然在這裏瞭解細節,甚至不知道詳細的選項。 –
第二部分:第二種方法(測試3)不起作用(我認爲),因爲比率*保持即使在保持= 0時也給NA。有沒有辦法做一些像sum(is.na(ratios [keep] ))與子集比率,然後評估is.na()函數?我寧願使用第二種方法,因爲在真實數據中,我有7個版本的「保留」,因此迭代7次,然後必須重新合併這7個數據集。在步驟中完成這一切會更好。 –
@JesseBlocher,看看爲什麼'NA'不同的編輯。我還沒有想出一種方法來做到這一點比多重保持和比率對的循環更好。 – mt1022