如何忽略NA值,检查多列是否逐行等价?
检查数据框指定列每行值是否一致(忽略NA)
需求:检查数据框中指定列的每行内所有非NA值是否相等;若某行全部为NA,则返回NA。
示例数据
library(dplyr) library(tibble) dat <- tribble( ~a, ~b, ~c, ~d, 4, "blue", "blue", NA, 7, NA, "red", "green", 8, "green", "green", "green", 6, "blue", NA, NA, 1, NA, NA, NA ) dat #> # A tibble: 5 × 4 #> a b c d #> <dbl> <chr> <chr> <chr> #> 1 4 blue blue <NA> #> 2 7 <NA> red green #> 3 8 green green green #> 4 6 blue <NA> <NA> #> 5 1 <NA> <NA> <NA>
期望输出
以检查b:d列为例,期望得到如下结果:
expected <- tribble( ~a, ~b, ~c, ~d, ~agreement, 4, "blue", "blue", NA, TRUE, 7, NA, "red", "green", FALSE, 8, "green", "green", "green", TRUE, 6, "blue", NA, NA, TRUE, 1, NA, NA, NA, NA ) expected #> # A tibble: 5 × 5 #> a b c d agreement #> <dbl> <chr> <chr> <chr> <lgl> #> 1 4 blue blue <NA> TRUE #> 2 7 <NA> red green FALSE #> 3 8 green green green TRUE #> 4 6 blue <NA> <NA> TRUE #> 5 1 <NA> <NA> <NA> NA
解决方案
方法1:tidyverse风格
用dplyr的行处理函数结合条件判断实现:
dat %>% rowwise() %>% mutate(agreement = case_when( all(is.na(c_across(b:d))) ~ NA, n_distinct(c_across(b:d), na.rm = TRUE) == 1 ~ TRUE, TRUE ~ FALSE )) %>% ungroup()
方法2:基础R风格
自定义判断函数,结合apply逐行处理:
check_agreement <- function(row) { non_na_vals <- row[!is.na(row)] if (length(non_na_vals) == 0) return(NA) all(non_na_vals == non_na_vals[1]) } dat$agreement <- apply(dat[, c("b", "c", "d")], 1, check_agreement)
两种方法均可得到与期望输出一致的结果。
内容的提问来源于stack exchange,提问作者mac
相关产品推荐
相关产品推荐

