2016-02-28 53 views
0

的比例在R虚拟变量填充缺失值我在R.一个新的学习现在,我取得了填充缺失值的麻烦,需要你的帮助。我有一个这样的数据帧df:由non_missing价值

a <- c(0,0,0,1,1,1,NA) 
b <- c(1,0,1,0,1,0,NA) 
c <- c(0,1,NA,0,1,0,1) 
df <- data.frame(a,b,c) 

我想根据非NA值的比率来推算这些变量的缺失值。例如:变量a有0%的50%和1%的50%。因此,NA值应该被置换为0和1以保持比率相同。 这里是我的代码:

ratio0 <- function(x) { # ratio 0 of non NA missing value 
      table(x)[1]/sum(table(x)[1],table(x)[2]) 
    } 
    ratio1 <- function(x) { # ratio 1 of non NA missing value 
      table(x)[2]/sum(table(x)[1],table(x)[2]) 
    } 

    for(i in 1:ncol(df)) { 
     df[is.na(df[,i]), i] <- sample(c(0,1),sum(is.na(df[,i])),replace=TRUE,prob=c(ratio0(df[,i]),ratio1(df[,i]))) 
    } 

当应用上面的代码中,我得到了错误: “错误在sample.int(长度(X),大小,替换,概率):NA在概率向量”。

可否请你让我知道我的错误?

因为当我试图为一个变量应用代码,它的工作原理。例如,下面的代码来计算数据框df的第三列的缺失值。

df[is.na(df[,3]), 3] <- sample(c(0,1), sum(is.na(df[,3])), replace=TRUE, prob=c(ratio0(df[,3]), ratio1(df[,3]))) 

非常感谢您的帮助。

+0

你能分享预期产出吗?你是否将两个“NA”值替换? – mtoto

+0

我想用0或1代替NA值。在数据集中,例如:变量a有500个NA值。这500个NA值应该被0或1代替。0和1的比率取决于非NA值中0和1的比率。 – Celine

+0

您的意思是更换的可能性,如您的示例中的比率将随替换0或1而更改。 – mtoto

回答

1

如果你想一个比功能,我会做财产以后这样

ratio <- function(x, which) { 
    b <- !is.na(x) 
    sum(x[b] == which)/sum(b) 
} 

,但如果我理解正确的话,你可以使用不缺值向量从中直接

品尝
fun <- function(x) { 
    b <- is.na(x) 
    x[b] <- sample(x[!b], sum(b), replace=TRUE) 
    x 
} 

as.data.frame(lapply(df, fun), stringsAsFactors = FALSE) 
+0

谢谢弗洛里安。我应用了你的代码,它运行良好。但是,你能简单介绍一下代码的工作原理吗? – Celine

+0

is.na(x)将为每个NA值返回TRUE,您可以使用逻辑类型的向量来索引其他向量或列表。 所以b为逻辑 类型的矢量的总和(b)为您NA值的数量,因此 X并[b] 给你NA值和 样品(X [!B],和(B ),替换= TRUE) 给你从非取样NA NA值(总和(b)) 如果lapply使用上的data.frame它将应用在每列中的功能 和的长度的值的向量返回的结果的列表,并可以再次打开该成data.frame通过使用as.data.frame – Florian

+0

或代码示例 回答'y < - C(0,1,NA,1,1,0,NA, 1)'' is.na(Y)'' Y [!is.na(Y)]'' 总和(is.na(Y))' – Florian

1

我们可以构造一个自定义函数,因此apply()它将以列向方向data.frame

# Function to replace NA's 
replacer <- function(x) { 

probs <- prop.table(table(x)) # Get proportions 
y <- sample(c(0,1),length(which(is.na(x))), prob = probs, replace = TRUE)# Generate sample 
x[is.na(x)] <- y # Replace values 
return(x) 

} 

> apply(df,2,replacer) 
#  a b c 
#[1,] 0 1 0 
#[2,] 0 0 1 
#[3,] 0 1 1 
#[4,] 1 0 0 
#[5,] 1 1 1 
#[6,] 1 0 0 
#[7,] 1 1 1 
+0

感谢Mtoto。 :-) – Celine