我必须在“存储桶”中随机填充一组“失败”值。
例如,
| 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/