[英]r expand dataset with filled in data
我有一個包含 4 列的數據集。 現在可以取 2 個值。(1 或 0)。 缺少數據的三列(X1、X2、X3)。
Row# X1 X2 X3 Y
1 1 0 0 1
2 0 1 1 0
3 NA 0 0 0
4 1 1 1 0
5 1 NA NA 1
6 1 0 0 1
7 NA NA NA 0
8 0 1 0 1
9 NA NA 1 0
10 0 0 1 1
11 NA NA 0 0
12 0 0 0 0
13 0 0 1 1
14 NA 0 NA 0
我有興趣為 NA 的可能值創建填充數據集。 我的意思是創建可能的數據行,如下所示
Row# X1 X2 X3 Y Probability Comments
1 1 0 0 1 1 No missing
2 0 1 1 0 1 No missing
3 1 0 0 0 0.5 X1 Missing
4 0 0 0 0 0.5 X1 Missing
5 1 1 1 0 1 No missing
6 1 1 0 1 0.25 X1, X2 missing
7 1 0 0 1 0.25 X1, X2 missing
8 1 1 1 1 0.25 X1, X2 missing
9 1 0 1 1 0.25 X1, X2 missing
10 1 0 0 1 1 No missing
11 0 0 0 0 0.125 X1, X2, x3 missing
12 1 0 0 0 0.125 X1, X2, x3 missing
13 0 1 0 0 0.125 X1, X2, x3 missing
14 0 0 1 0 0.125 X1, X2, x3 missing
15 1 1 0 0 0.125 X1, X2, x3 missing
16 1 0 1 0 0.125 X1, X2, x3 missing
17 0 1 1 0 0.125 X1, X2, x3 missing
18 1 1 1 0 0.125 X1, X2, x3 missing
19 . . . . . ......
20 . . . . . ......
21 . . . . . ......
22 . . . . . ......
請注意,最終數據集將包含 5 列(X1、X2、X3、Y、Possibility)
基於此邏輯計算列Probability
。
讓我們從第一個數據集中的第 1 行和第 2 行開始。 前兩行(1,2)沒有任何缺失數據,因此在預期的 output 中生成相同的兩行,概率為 1。
讓我們看看原始數據集中的第 3 行。 這在 X1 列中缺少值。 因此在預期的 output 中生成了兩行 3,4。 因此概率為 0.5, 0.5。 1/2=0.5
讓我們看看原始數據集中的第 5 行。 這包含 X2 和 X3 列中的缺失數據。 所以這將在預期數據中生成 4 行,第 6、7、8.9 行。 所以概率是 0.25, 0.25,0.25, 0.25, 1/4 = 0.25
原始數據集的第 7 行缺少 x1、x2、x3 的值。 所以這個場景將在預期的 output 數據集中生成 8 行,第 11 行 - 第 18 行。 因此概率 0.125, 1/8 = 0.125
我可以使用 8 個 ifelse 語句和 for 循環來做到這一點。 但我想知道是否有任何更簡單、更簡潔的方法來實現這一目標。 謝謝。
我使用 expand.grid 為任何數字的{0,1}
組合定義了一個expand.grid
。 對於n
等於0
,我使用了一維的 data.frame 來避免沒有NA
的行的復雜性。
comb <- function(n) {
if(n==0) return(data.frame(Var1 = c(1)))
expand.grid(rep(list(0:1),n))
}
現在我正在使用應用並替換 function 來創建行列表。 我使用了dplyr
中的mutate
來創建概率列。
df = apply(df, 1, function(v){
NA_count = length(which(is.na(v)))
apply(comb(NA_count) , 1 , FUN = replace , x = v, list =
which(is.na(v))) %>%
t %>% as.data.frame() %>%
mutate( Probability = (1/2)^length(which(is.na(v))))
})
最后,我將所有列表與do.call
放在一起。
do.call(rbind,df)
這可以簡化 - 但如果這更接近您的需要,請告訴我。
這里有2個功能:
一個 function make_mat(x, k)
創建一個包含 0 和 1 的向量(例如, make_mat(7,4)
是0 1 1 1
,它是 4 位長,二進制等於 7)
第二個 function sub_mat
將創建一個2^n_repl
行的矩陣,其中n_repl
是要替換的NA
的數量。
為原始數據框中的每一行創建一個列表。 現在,計算列表的行數num_row
,並將probability
設置為1/num_row
。
make_mat <- function(x, k) {
return(rev(as.integer(intToBits(x))[1:k]))
}
sub_mat <- function(x) {
n_repl <- sum(+(is.na(x)))
mat_repl <- t(sapply(1:2^n_repl-1, make_mat, k = n_repl))
new_mat <- matrix(rep(x, 2^n_repl), ncol = length(x), byrow = T)
new_mat[is.na(new_mat)] <- mat_repl
new_mat
}
lst <- apply(df, 1, sub_mat)
num_row <- sapply(lst, nrow, simplify = T)
result <- as.data.frame(Reduce(rbind, Map(cbind, lst, 1/num_row)))
names(result) <- c(names(df), "probability")
result
Output
X1 X2 X3 Y probability
1 1 0 0 1 1.000
2 0 1 1 0 1.000
3 0 0 0 0 0.500
4 1 0 0 0 0.500
5 1 1 1 0 1.000
6 1 0 0 1 0.250
7 1 0 1 1 0.250
8 1 1 0 1 0.250
9 1 1 1 1 0.250
10 1 0 0 1 1.000
11 0 0 0 0 0.125
12 0 0 1 0 0.125
13 0 1 0 0 0.125
14 0 1 1 0 0.125
15 1 0 0 0 0.125
16 1 0 1 0 0.125
17 1 1 0 0 0.125
18 1 1 1 0 0.125
19 0 1 0 1 1.000
20 0 0 1 0 0.250
21 0 1 1 0 0.250
22 1 0 1 0 0.250
23 1 1 1 0 0.250
24 0 0 1 1 1.000
25 0 0 0 0 0.250
26 0 1 0 0 0.250
27 1 0 0 0 0.250
28 1 1 0 0 0.250
29 0 0 0 0 1.000
30 0 0 1 1 1.000
31 0 0 0 0 0.250
32 0 0 1 0 0.250
33 1 0 0 0 0.250
34 1 0 1 0 0.250
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.