移除数据NA单元格(非行列)及bayestestR的overlap函数NA处理问题
合并非NA列值并修正bayestestR::overlap()的NA问题
问题描述
原始数据集
| A | B | C |
|---|---|---|
| 1 | NA | NA |
| NA | 2 | NA |
| NA | NA | 3 |
期望结果
| A | B | C |
|---|---|---|
| 1 | 2 | 3 |
背景与问题
数据集特征:任意一行中仅A/B/C中的一列有值,其余为NA;且A、B、C的非NA值长度可能不一致。
需要调用bayestestR::overlap(x,y)计算重叠系数,但保留NA时,overlap(a,a)的结果不是预期的1,而是0.98左右。尝试过以下代码,但仅能将非NA值移至顶部,仍有NA残留甚至全NA行,无法解决问题:
df <- data.table(df)[, lapply(.SD, function(x) x[order(is.na(x))])] df[!result[, Reduce(`&`, lapply(.SD, is.na))]] df[complete.cases(df), ]
解决方案
思路1:合并列得到无NA的单行数据
利用每列仅含非NA值的特点,提取各列的非NA值后合并为一行:
使用data.table实现
library(data.table) setDT(df) # 提取每列的非NA值 non_na_list <- df[, lapply(.SD, function(x) x[!is.na(x)])] # 转置后去除NA,再转回data.table格式 result <- as.data.table(t(na.omit(t(non_na_list))))
使用dplyr+tidyr实现
library(dplyr) library(tidyr) result <- df %>% # 提取每列的非NA值 summarise(across(everything(), ~ .x[!is.na(.x)])) %>% # 移除全NA的列(如果存在) select(where(~ length(.x) > 0)) %>% # 将列表列展开为单行 unnest(cols = everything())
思路2:让overlap()忽略NA直接计算
无需修改数据集,在传入overlap()前手动去除NA值即可:
library(bayestestR) # 计算同一列自身的重叠系数(结果应为1) a_clean <- na.omit(df$A) overlap(a_clean, a_clean) # 计算不同列的重叠系数 b_clean <- na.omit(df$B) c_clean <- na.omit(df$C) overlap(a_clean, b_clean) overlap(b_clean, c_clean)
说明
你之前的代码仅对列内的NA进行排序,没有处理列间长度不一致的问题。上述两种思路分别从整理数据集和直接处理输入向量两个角度解决问题,可根据实际需求选择。
内容的提问来源于stack exchange,提问作者Daniil M. Ozernyi
相关产品推荐
相关产品推荐

