R语言如何用vec1前4个高频值随机替换vec中的NA缺失值
R语言随机高频值替换缺失值实现方案
原始需求与现有代码
现有两个示例向量:
set.seed(10) vec1 <- c(1,1,5,1,2,5,1,7,9,1,3,1,1,2 ,2, 1, 2, 1, 3, 1,1,1,1,1,1,2,5,1,1,1,1,1,1,1,1,1,1,2,3,1,1,2,1,7,1,7,2,1,1,1) vec <- c(1,1,5,1,2,5,1,7,9,1,3,1,1,2 ,2, 1, 2, 1, 3, 1,1,1,1,1,1,2,5,1,NA, NA, NA, NA, NA, NA, NA)
需要满足以下要求:
- 用
vec1中出现频率最高的4个值,替换vec中的NA缺失值 - 替换取值随机排序,不需要按数值大小规则填充
- 兼容NA数量不是高频值数量整数倍的场景,适配大规模业务数据集
原有错误代码:
# 取出现频率最高的4个值 mfv <- as.numeric(names(sort(table(vec1),decreasing=TRUE)[1:4])) # 替换缺失值 result <- lapply(vec, function(n) replace(n, is.na(n), as.integer(mfv)))
错误原因
原有代码的替换逻辑存在两个核心问题:
- 逐元素遍历向量时,遇到NA传入了长度为4的
mfv向量,和单个元素的长度不匹配,直接触发报错 - 没有实现随机采样、适配NA总数量的逻辑,无法满足随机填充、兼容任意NA数量的要求,同时逐元素遍历的效率极低,不适合大规模数据集。
正确实现方案
采用向量化操作实现,效率远高于循环/lapply,适配任意规模数据:
set.seed(10) vec1 <- c(1,1,5,1,2,5,1,7,9,1,3,1,1,2 ,2, 1, 2, 1, 3, 1,1,1,1,1,1,2,5,1,1,1,1,1,1,1,1,1,1,2,3,1,1,2,1,7,1,7,2,1,1,1) vec <- c(1,1,5,1,2,5,1,7,9,1,3,1,1,2 ,2, 1, 2, 1, 3, 1,1,1,1,1,1,2,5,1,NA, NA, NA, NA, NA, NA, NA) # 1. 取top4高频值,原有逻辑正确 mfv <- as.numeric(names(sort(table(vec1), decreasing = TRUE)[1:4])) # 2. 统计vec中NA的总数量 na_total <- sum(is.na(vec)) # 3. 从mfv中有放回随机采样对应数量的值,直接替换NA # 如需固定随机结果可在本行前加set.seed,例如set.seed(123) vec[is.na(vec)] <- sample(x = mfv, size = na_total, replace = TRUE) # 输出结果 print(vec)
说明:sample函数的replace = TRUE参数开启有放回采样,不管NA总数量是多少都能生成对应长度的随机值,完美兼容非整数倍的场景。
内容的提问来源于stack exchange,提问作者ramen
相关产品推荐
相关产品推荐

