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、可能性)
第Probability
列就是按照这个逻辑计算出来的。
让我们从第一个数据集中的第 1 行和第 2 行开始。前两行 (1,2) 没有任何缺失数据,因此在预期输出中生成相同的两行并且概率为 1。
让我们看一下原始数据集中的第 3 行。这在 X1 列中有缺失值。因此在预期输出中生成了两行 3,4。因此概率为 0.5, 0.5。 1/2=0.5
让我们看一下原始数据集中的第 5 行。这包含 X2 和 X3 列中缺失的数据。所以这将在 Expected 数据中生成 4 行,第 6、7、8.9 行。所以概率是0.25,0.25,0.25,0.25,1/4 = 0.25
原始数据集的第 7 行缺少 x1、x2、x3 的值。因此,此场景将在预期输出数据集中生成 8 行,第 11 行至第 18 行。因此概率 0.125 , 1/8 = 0.125
我可以使用 8 个 ifelse 语句和 for 循环来做到这一点。但我想知道是否有更简单、更简单的方法来实现这一目标。谢谢。
我为使用 expand.grid
的任何数字定义了 {0,1}
组合的函数。对于等于 0
的 n
,我使用了具有 1 个维度的 data.frame 以避免没有 NA
.
的行的复杂化
comb <- function(n) {
if(n==0) return(data.frame(Var1 = c(1)))
expand.grid(rep(list(0:1),n))
}
现在我正在使用应用和替换函数来创建行列表。我使用 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个函数:
一个函数make_mat(x, k)
创建一个包含0和1的向量(例如,make_mat(7,4)
是0 1 1 1
,它有4位长,二进制等于7 )
第二个函数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
输出
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
我有一个包含 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、可能性)
第Probability
列就是按照这个逻辑计算出来的。
让我们从第一个数据集中的第 1 行和第 2 行开始。前两行 (1,2) 没有任何缺失数据,因此在预期输出中生成相同的两行并且概率为 1。
让我们看一下原始数据集中的第 3 行。这在 X1 列中有缺失值。因此在预期输出中生成了两行 3,4。因此概率为 0.5, 0.5。
1/2=0.5
让我们看一下原始数据集中的第 5 行。这包含 X2 和 X3 列中缺失的数据。所以这将在 Expected 数据中生成 4 行,第 6、7、8.9 行。所以概率是0.25,0.25,0.25,0.25,
1/4 = 0.25
原始数据集的第 7 行缺少 x1、x2、x3 的值。因此,此场景将在预期输出数据集中生成 8 行,第 11 行至第 18 行。因此概率 0.125 ,
1/8 = 0.125
我可以使用 8 个 ifelse 语句和 for 循环来做到这一点。但我想知道是否有更简单、更简单的方法来实现这一目标。谢谢。
我为使用 expand.grid
的任何数字定义了 {0,1}
组合的函数。对于等于 0
的 n
,我使用了具有 1 个维度的 data.frame 以避免没有 NA
.
comb <- function(n) {
if(n==0) return(data.frame(Var1 = c(1)))
expand.grid(rep(list(0:1),n))
}
现在我正在使用应用和替换函数来创建行列表。我使用 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个函数:
一个函数
make_mat(x, k)
创建一个包含0和1的向量(例如,make_mat(7,4)
是0 1 1 1
,它有4位长,二进制等于7 )第二个函数
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
输出
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