簡體   English   中英

r 用填充數據展開數據集

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM