You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R中使用case_when与rowSums时行统计结果不匹配问题

二进制变量编码与行和统计的NA处理差异

问题场景

构建含随机缺失值的二进制变量数据框:

set.seed(357)
# 生成二进制变量
var1 <- sample(c(0, 1, NA), 200, replace = TRUE, prob = c(0.4, 0.4, 0.2))
var2 <- sample(c(0, 1, NA), 200, replace = TRUE, prob = c(0.4, 0.5, 0.1))
var3 <- sample(c(0, 1, NA), 200, replace = TRUE, prob = c(0.4, 0.35, 0.25))

# 创建数据框
df <- data.frame(var1, var2, var3)

需求与疑问:

  • 生成x1:任意变量为1则x1=1,所有变量为0则x1=0,用case_when实现后,table(df$x1)输出0有11个,1有167个。
  • 用rowSums(cbind(var1, var2, var3), na.rm = F)生成x2统计行和,table(df$x2)输出0有11个,1有38个,2有51个,3有13个。但x2中1/2/3的总数(102)与x1中1的数量(167)不匹配;尝试na.rm = TRUE后,连0的数量也不匹配。

核心原因:NA的处理规则差异

1. x1的case_when逻辑

对应需求的case_when实现代码如下:

library(dplyr)
df <- df %>%
  mutate(x1 = case_when(
    var1 == 1 | var2 == 1 | var3 == 1 ~ 1,
    var1 == 0 & var2 == 0 & var3 == 0 ~ 0
    # 未匹配的情况(存在NA且无1的行)自动设为NA
  ))

这里的规则是:

  • 只要行内至少有一个1,不管有没有NA,都标记为1(比如NA,0,1或NA,1,0这类行都会归为1)。
  • 只有行内所有变量明确为0(无NA),才标记为0。
  • 存在NA且没有1的行(比如0,NA,NA)会被设为NA,不计入table(df$x1)的统计结果。

2. rowSums(na.rm = F)的逻辑

rowSums默认na.rm = FALSE,即行内只要有NA,行和直接返回NA。因此:

  • x2的1/2/3只统计了完全无NA且行内1的数量为1/2/3的行,也就是无缺失的有效行里有1的情况。
  • 那些有NA但包含1的行(比如NA,0,1),行和会是NA,不会被计入table(df$x2)的1/2/3中,这就是x1的1(167)和x2的1+2+3(102)数量差的来源(167-102=65行是有NA但含1的行)。

3. rowSums(na.rm = TRUE)的逻辑

当设置na.rm = TRUE时,rowSums会把NA当作0计算,此时:

  • 行和为0的情况包括:全0的行,以及有NA但没有1的行(比如NA,NA,0),所以table(df$x2)的0数量会比x1的0多,和x1的0定义完全不同。

哪个结果正确?

取决于你的业务需求:

  • 如果需要只要有1就标记为1,只有所有变量明确为0才标记为0,那x1的结果是正确的,完全符合你最初的规则。
  • 如果需要统计无缺失行内1的个数,那rowSums(na.rm = F)的结果是对的,但它不包含有NA但含1的行。
  • 如果需要把NA当作0来计算行和,那用rowSums(na.rm = TRUE),但此时的0和你最初定义的x1的0不是同一个概念。

内容的提问来源于stack exchange,提问作者esteban

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 09:58:25