如何用Base R或Tidyverse移除除id列外全为空的行?
移除除id列外所有单元格均为空的行
原始数据
df <- structure(list(id = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"), name = c("Sam", "Dave", NA, "Alan", "Ted", "Ana", NA, NA, "Max", NA, "Walt", NA), age = c(28, 32, NA, NA, 23, NA, 21, NA, NA, 22, 21, NA), height = c(NA, 161, NA, 168, 167, NA, 166, NA, 158, 171, NA, NA)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -12L))
需求说明
需要移除除id列外所有单元格均为NA的行,最终得到如下数据框:
final <- structure(list(id = c("A", "B", "D", "E", "F", "G", "I", "J", "K"), name = c("Sam", "Dave", "Alan", "Ted", "Ana", NA, "Max", NA, "Walt"), age = c(28, 32, NA, 23, NA, 21, NA, 22, 21), height = c(NA, 161, 168, 167, NA, 166, 158, 171, NA)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -9L))
Base R 实现
通过rowSums和is.na组合判断每行除id外的NA数量,筛选出至少有一个非NA值的行:
final_base <- df[rowSums(is.na(df[, -match("id", names(df))])) != (ncol(df) - 1), ]
df[, -match("id", names(df))]:提取除id列外的所有列is.na(...):将列转换为逻辑矩阵,NA值标记为TRUErowSums(...):计算每行的NA数量ncol(df)-1:除id外的总列数,当该行NA数量不等于该值时,说明存在非NA值,保留该行
tidyverse 实现
使用dplyr的filter和if_all函数,简洁实现筛选逻辑:
library(dplyr) final_tidy <- df %>% filter(!if_all(-id, is.na))
-id:指定除id列外的所有列if_all(-id, is.na):判断该行除id外的所有列是否全为NA!:取反,筛选出不满足全NA的行
两种方法得到的结果均与目标数据框final一致。
内容的提问来源于stack exchange,提问作者Shubham
相关产品推荐
相关产品推荐

