使用样本函数sample()将R中的NA替换为某些条件

时间:2017-07-19 23:12:01

标签: r

我的数据集缺少一些值,现在我需要使用sample()函数来计算10次替换NA,但sample()函数有更多要求。

ID <- c(rep(1,4), rep(3, 5), rep(4,4),rep(5,5),rep(6,5))
Begin <- c(0,2.5,3.5,3,7,8,7,25,25,10,15,0,0,1,NA,10,11,13,NA,NA, 8, 12, NA)
End <- c(1.5,3.5,NA,6,12,8,11,29,35, 12,19,NA,28,5,20,30,20,25,6,7,13,NA, 23)
GA <- c(23, 34, 38, 16, 20, 38, 32, 28, 30, 34,25,45,34,23, 34, 38, 16, 20, 38, 32, 28, 30, 34)
df <- data.table(ID, Begin, End, GA)
   ID Begin  End GA
 1:  1   0.0  1.5 23
 2:  1   2.5  3.5 34
 3:  1   3.5   NA 38
 4:  1   3.0  6.0 16
 5:  3   7.0 12.0 20
 6:  3   8.0  8.0 38
 7:  3   7.0 11.0 32
 8:  3  25.0 29.0 28
 9:  3  25.0 35.0 30
10:  4  10.0 12.0 34
11:  4  15.0 19.0 25
12:  4   0.0   NA 45
13:  4   0.0 28.0 34
14:  5   1.0  5.0 23
15:  5    NA 20.0 34
16:  5  10.0 30.0 38
17:  5  11.0 20.0 16
18:  5  13.0 25.0 20
19:  6    NA  6.0 38
20:  6    NA  7.0 32
21:  6   8.0 13.0 28
22:  6  12.0   NA 30
23:  6    NA 23.0 34
  1. 按ID分组
  2. 如果我们采样结束变量,NA范围,需要小于GA,大于Begin,大于前一行,小于下一行。
  3. 如果我们采样开始变量,范围NA,需要小于结束变量,但大于前一行结束
  4. 示例:

    第3行,结束变量是NA,因此当我们采样时,NA需要在[3.5,6]范围内

    第12行,结束变量为NA,NA必须在[19,28]

    范围内

    第15行,Begin是NA,因此NA&gt; = 5&amp; NA <= 20且NA <= 34,因此范围[5,20]

    第19行,开头是NA,[0,6]

    第20行,Begin为NA,NA&gt; = 6,NA <= 7,因此范围[6,7]

    第22行,结束为NA,NA范围[13,23]

    第23行,Begin为NA,NA&gt; =我们只为第22行采样的值,NA <= 23

1 个答案:

答案 0 :(得分:2)

我不确定这是否涵盖所有特殊情况(例如,如果存在多个NAs),但对于给定的样本,它应该有效。

可能还有一个更好的解决方案,它不包括创建变量_pre_next

我使用for循环来创建值rowise(INDEX)。而不是sample()我使用了runif()因为我认为你不想只获得整数。

df[, INDEX := 1:.N]
df[, End_next := shift(End, type = "lead")]
df[, End_pre := shift(End, type = "lag")]
df[, ID_pre := shift(ID, type = "lag")]
df[, ID_next := shift(ID, type = "lead")]

for (i.row in c(1:dim(df)[1])) {
  # i.row = 3
  # adjust the values after last sample
  df[, Begin_pre := shift(Begin, type = "lag")]
  df[, End_pre := shift(End, type = "lag")]

  # replace NA with sample (runif)
  df[is.na(Begin) & INDEX == i.row,
     Begin := runif(1, min = ifelse(ID_pre == ID, End_pre,0), max = End)]
  df[is.na(End) & INDEX == i.row,
     End := runif(1, min = max(Begin, ifelse(ID_pre == ID, End_pre, Begin)),
                     max = min(GA, ifelse(ID_next == ID, End_next, GA)))]
}

我希望这会对你有所帮助。