使用map_dfr传递含NA值向量时density函数报错的求助
问题排查与解决方案
错误根源
overlapping::overlap() 内部依赖 density() 计算分布,而 density() 会严格检查输入向量是否含NA——哪怕你全局做了NA过滤,如果按分组拆分后,某个分组的目标数值列仍残留NA(或过滤后变成空向量),就会触发该错误。你的!is.na(.x)过滤逻辑可能只是全局过滤了行,没有针对每个分组的单个数值列做精准的NA清除。
修正步骤与代码示例
假设你的数据结构如下(带不同数量NA的测试数据):
library(tidyverse) library(overlapping) set.seed(123) df <- tibble( group = rep(c("A", "B"), each = 100), val1 = c(rnorm(90), rep(NA, 10), rnorm(85), rep(NA, 15)), val2 = c(rnorm(95), rep(NA, 5), rnorm(92), rep(NA, 8)) )
正确实现代码
# 按分类列拆分数据集 df_split <- df %>% split(.$group) # 迭代所有数值列计算重叠度 result <- map_dfr(names(df)[-1], function(col) { # 对每个分组的目标列,单独清除NA group_vectors <- map(df_split, ~ .x[[col]] %>% na.omit()) # 处理极端情况:若某分组的列全为NA,返回NA避免报错 if (any(map_int(group_vectors, length) == 0)) { return(tibble(column = col, overlap_score = NA_real_)) } # 计算重叠度并整理结果 overlap_res <- overlap(group_vectors) tibble(column = col, overlap_score = overlap_res$OV) }) print(result)
关键说明
- 精准NA清除:必须针对每个分组的单个数值列执行
na.omit(),确保传入overlap()的每个向量都无NA。 - 空向量防护:如果某个分组的目标列全是NA,
na.omit()后会得到空向量,此时overlap()会报错,因此需要提前判断并返回NA值。 - 迭代逻辑验证:
map_dfr()的迭代单位是数值列,每个列对应两个分组的非NA向量列表,完全匹配overlap()的输入要求。
内容的提问来源于stack exchange,提问作者C.Robin
相关产品推荐
相关产品推荐

