[英]How to handle missing data (NA) in for loops in R
我正在嘗試計算觀察數據和模擬數據的卡方差異,並使用貝葉斯推理評估模型擬合。 觀察到的數據集包含缺失(“NA”)值。 但是,模擬的沒有缺失值。 因此,我無法比較它們之間的差異統計數據。
下面給出的代碼是一個示例,與我的工作類似:
p <- array(runif(3000*195*6, 0, 1), c(3000, 195, 6))
N <- array(rpois(3000*195, 10), c(3000, 195))
y <- array(0, c(195, 6))
for(j in 1:195){
for(k in 1:6){
y[j,k] <- (rbinom(1, N[j], p[1,j,k]))
}
}
foo <- runif(50, 1, 195)
bar <- runif(50, 1, 6)
for(i in 1:50){
y[foo[i], bar[i]] <- NA
}
該代碼導出響應變量 y,其中包括一些缺失值(“NA”)。 然后,我計算了數據“y”和模擬的“理想”數據集“y.new”的卡方。 相反,y.new 沒有任何缺失值。 因此,當我嘗試比較 E 和 E.new 的總和時,如果我遺漏了 y 而不是 y.new 中的缺失數據,E.new 應該總是更大。
eval <- array(NA, c(3000, 195, 6))
E <- array(NA, c(3000, 195, 6))
E.new <- array(NA, c(3000, 195, 6))
y.new <- array(NA, c(195, 6))
for(i in 1:3000){
for(j in 1:195){
for(k in 1:6){
eval[i,j,k] <- p[i,j,k]*N[i,j]
E[i,j,k] <- ((y[j,k] - eval[i,j,k])^2) / (eval[i,j,k] + 0.5)
y.new[i,j,k] <- rbinom(1, N[i,j], p[i,j,k]) # Create new "ideal" dataset
E.new[i,j,k] <- ((y.new[i,j,k] - eval[i,j,k])^2) / (eval[i,j,k] + 0.5)
}
}
} # very slow! think about how to vectorize instead of nested for loops
fit <- sum(E)
fit.new <- sum(E.new)
現在,我的問題是如何處理缺失值? 目前,由於缺少值,上面的代碼無法從 y 中減去 eval。 即使可以, fit 和 fit.new 也沒有可比性。 我的想法是找到 y 中缺失值的位置,並從我正在使用的所有其他數組中刪除相同的 [j,k] 值。 關於如何最好地做到這一點的任何建議?
編輯:我得到一個非常奇怪的結果。 無論我是按上面還是下面的方式運行代碼(使用掃描),E[1,,] 都比 E[>1,,] 小得多。 特別奇怪的是 eval[1,,] 和 eval[>1,,] 看起來是一樣的。 我什至嘗試復制 y[j,k] 使其成為 y[i,j,k],其中每個 y[i,,] 都相等,只是想看看是否是處理不同大小矩陣的問題。 有誰知道為什么會這樣? 從理論上講,有了這個模擬數據,我認為 E[i,,] 和 E.new[i,,] 的所有迭代應該有些相似。 下面是一些摘要信息,以顯示我在說什么。 這似乎是一個新問題,但它與我原來的問題有關,我只是認為一定是 NA 導致了這個問題,但似乎這可能不是唯一發生的事情。
> summary(eval[1,,])
V1 V2 V3 V4
Min. : 0.01167 Min. : 0.01476 Min. : 0.0293 Min. : 0.01953
1st Qu.: 2.60909 1st Qu.: 2.35093 1st Qu.: 2.5239 1st Qu.: 1.85789
Median : 4.85460 Median : 5.12719 Median : 5.2480 Median : 4.35639
Mean : 5.09371 Mean : 5.39451 Mean : 5.3891 Mean : 4.72061
3rd Qu.: 6.91273 3rd Qu.: 7.44676 3rd Qu.: 7.5431 3rd Qu.: 7.06119
Max. :15.81298 Max. :14.94309 Max. :14.9851 Max. :16.25751
> summary(eval1[2,,])
V1 V2 V3 V4
Min. : 0.06346 Min. : 0.06468 Min. : 0.2092 Min. : 0.006769
1st Qu.: 2.44825 1st Qu.: 1.93702 1st Qu.: 2.4226 1st Qu.: 2.426689
Median : 4.16865 Median : 4.01536 Median : 5.0771 Median : 4.833679
Mean : 4.85646 Mean : 4.64887 Mean : 5.3450 Mean : 5.169656
3rd Qu.: 6.64691 3rd Qu.: 6.96278 3rd Qu.: 7.7034 3rd Qu.: 7.229125
Max. :13.00335 Max. :13.79093 Max. :17.2673 Max. :17.915080
> summary(E[1,,])
V1 V2 V3 V4
Min. :0.00001 Min. :0.00000 Min. :0.000003 Min. :0.000008
1st Qu.:0.02744 1st Qu.:0.02723 1st Qu.:0.023008 1st Qu.:0.035854
Median :0.11750 Median :0.11889 Median :0.109138 Median :0.146706
Mean :0.39880 Mean :0.41636 Mean :0.353876 Mean :0.479533
3rd Qu.:0.46435 3rd Qu.:0.40993 3rd Qu.:0.390625 3rd Qu.:0.604021
Max. :4.43466 Max. :4.83871 Max. :6.254577 Max. :5.231650
NA's :10 NA's :8 NA's :8 NA's :10
> summary(E[2,,])
V1 V2 V3
Min. : 0.0000 Min. : 0.00003 Min. : 0.00002
1st Qu.: 0.8213 1st Qu.: 0.42091 1st Qu.: 0.36853
Median : 2.0454 Median : 2.31697 Median : 2.39892
Mean : 8.0619 Mean : 9.40838 Mean : 6.38919
3rd Qu.: 5.6755 3rd Qu.: 6.34782 3rd Qu.: 4.89749
Max. :395.9499 Max. :172.83324 Max. :120.93648
NA's :10 NA's :8 NA's :8
謝謝,丹
您可以在內部循環中添加一個測試並更改循環的順序,如下所示:
...
for(j in 1:195){
for(k in 1:6){
if ( !is.na(y(j,k)) ) {
for(i in 1:3000){
...
}
}
}
}
...
為了更有效地矢量化內部循環(如上面的評論所述)。
也可以定義一個邏輯數組,其維度與y
相同,表示已定義位置的子集,例如subset <-.is.na(y)
並改為使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.