根据非NA值的出现概率,替换数据帧中列中的NA值

时间:2018-01-26 16:31:19

标签: r random data.table

我必须填充一套“失败”。 ' Bucket'中的值随机。

例如,

| Bucket | Failure | Id |
|--------|---------|----|
| B1     | F1      | 1  |
| B1     | F2      | 2  |
| B1     | F1      | 3  |
| B1     | null    | 4  |
| B1     | null    | 5  |
| B2     | F3      | 6  |
| B2     | F4      | 7  |
| B2     | null    | 8  |

在上表中,每个Bucket可以包含许多记录。其中一些记录将包含填充的故障,但大多数记录不会。我的目标是根据存储桶中的故障比例随机分配故障。例如,对于组合 - {B1,F1}与B1记录(填充失败)的比例相比,{B1,F2}为2/3 B1记录的比例(失败)填充)是1/3。

因此,具有 null 失败列(Id = 4,5)的B1的记录应随机获得F1或F2失败,但F1的比例与2/3相同,F2为1 / 3。该逻辑需要应用于表中的所有桶。

我看到这是一件复杂的事情。我相对来说是一个R菜鸟,因此,我们非常感谢任何代码示例。

介于两者之间,我看到了这个问题。但解决方案并没有运行:Fill missing value based on probability of occurrence

请参阅示例代码:

test <- data.frame(
bucket = c(rep('B1', 5), rep('B2',3))
    , failure = c('F1', 'F2', 'F1', NA, NA, 'F3', 'F4', NA)
    , Id = seq(1:8)
)

test

sample_fill_na = function(x) {
    x_na = is.na(x)
    x[x_na] = sample(x[!x_na], size = sum(x_na), replace = TRUE)
    return(x)
}

test[, failure := sample_fill_na(failure), by = bucket]

2 个答案:

答案 0 :(得分:1)

这是一个可能的解决方案,我们可以使用probs函数中的sample参数,并使用{{1}创建权重(sample将其转换为我们的概率)功能。

希望这有帮助!

table

输出:

library(data.table)
test <- data.frame(bucket = c(rep('B1', 5), rep('B2',3)), failure = c('F1', 'F2', 'F1', NA, NA, 'F3', 'F4', NA), Id = seq(1:8))

fillF <- function(x){
  y <- table(x)
  x[is.na(x)] <- sample(names(y),sum(is.na(x)),prob =y,replace=T)
  return(x)
}

setDT(test)[, failure := fillF(failure), by = bucket]

我们可以使用以下代码轻松检查比例:

   bucket failure Id
1:     B1      F1  1
2:     B1      F2  2
3:     B1      F1  3
4:     B1      F1  4
5:     B1      F1  5
6:     B2      F3  6
7:     B2      F4  7
8:     B2      F3  8

事实上,比例看起来还不错:

set.seed(1)
for(i in 1:9){test=rbind(test,test)}
setDT(test)[, failure := fillF(failure), by = bucket]
table(test$failure)

编辑:如果您的数据中有空组,我们就可以自行决定概率。有两个逻辑选项,始终填充默认值(例如 F1 F2 F3 F4 1705 855 749 787 ),或从所有选项中随机抽样。所以:

F1

答案 1 :(得分:1)

这是一个潜在的解决方案,它基本上以每个桶中的比例给出的概率对失败进行抽样。

test <- data.frame(
  bucket = c(rep('B1', 5), rep('B2',3))
  , failure = c('F1', 'F2', 'F1', NA, NA, 'F3', 'F4', NA)
  , Id = seq(1:8)
)

fillNA <- function(test) {
  uni <- unique(test$bucket)
  for (i in 1:length(uni)) {
    pos <- test$bucket == uni[i]
    tbl <- table(test[pos, 2])
    proportions <- tbl / sum(tbl)
    posNA <- pos & is.na(test[, 2])
    test[posNA, 2] <- sample(levels(test[, 2]), 
                             sum(posNA),
                             replace = TRUE,
                             prob = proportions)
  }
  return(test)
}
fillNA(test)

结果:

 bucket failure Id
1     B1      F1  1
2     B1      F2  2
3     B1      F1  3
4     B1      F1  4
5     B1      F1  5
6     B2      F3  6
7     B2      F4  7
8     B2      F4  8