根据出现概率用非 NA 值替换数据框中列中的 NA 值

标签 r random data.table

我必须在“存储桶”中随机填充一组“失败”值。

例如,

| 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 记录(已填充故障)的比例相比,为 2/3 对于 {B1, F2},B1 记录(已填充故障)的比例为 2/3已填充)为 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]

最佳答案

这是一个可能的解决方案,我们可以在sample函数中使用probs参数,并创建权重(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)填充,或从所有选项中随机采样。所以:

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

fillF <- function(x){
  y <- table(x)
  if(sum(y)<1){y=c('F1'=1)} # always F1
  # if(sum(y)<1){y=y+1} # randomly sample from all possibilities
  x[is.na(x)] <- sample(names(y),sum(is.na(x)),prob =y,replace=T)
  return(x)
}

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

关于根据出现概率用非 NA 值替换数据框中列中的 NA 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48465546/

相关文章:

r - 数据框对象列中最长 NA 的长度

python - 在 Python 中采样截断的整数幂律?

r - 您如何将其转换为R中的data.table包语言?

r - 如何通过合并 csv 文件创建数据框,然后基于它创建 Shiny 的应用程序?

r - 第二个参数中的链函数

r - ggplot - 具有定义的小数位的对数轴标签

jquery - 使用 Jquery 显示三个 Div 中的一个随机 Div

php - 如何同时在两个文档中从 MySQL 中获取相同的 Random() 数据?

R 从短格式转换为长格式,并以短格式计数

r - 仅对数据表中的特定行应用 frollapply