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

使用dplyr的case_when创建新列时的NA特殊处理问题

解决多列条件计分并处理NA的问题

样本数据框

x <- data.frame(x1 = c(NA, 1, 1, 0, 0 , NA),
                x2 = c(1, NA, 0, 0, NA, 0),
                x3 = c(0, NA, NA, 1, 0, 1),
                x4 = c(NA, 1, 1, NA, 0, 0))

需求说明

需要创建score列,规则如下:

  • 第一组(x1、x2):
    • 若x1或x2为1,加1分
    • 若x1和x2均为0,加0分
    • 其他情况记为NA
  • 第二组(x3、x4):
    • 若x3或x4为1,加1分
    • 若x3和x4均为0,加0分
    • 其他情况记为NA
  • 最终score为两组得分之和,且需忽略NA(即NA按0处理),期望结果为1, 2, 2, 1, 0, 1

问题分析

  • 直接相加两组case_when结果时,只要其中一组为NA,整体结果就会变成NA(R中NA与任何值运算结果都是NA)
  • 使用全局sum(..., na.rm=T)会对整个向量求和,得到单一值,无法实现逐行计算

解决方案

方法1:分步计算(清晰直观)

先分别计算两组得分,再逐行求和并忽略NA:

library(dplyr)

x <- x %>%
  mutate(
    # 计算第一组得分
    part1 = case_when(
      x1 == 0 & x2 == 0 ~ 0L,
      x1 == 1 | x2 == 1 ~ 1L,
      TRUE ~ NA_integer_
    ),
    # 计算第二组得分
    part2 = case_when(
      x3 == 0 & x4 == 0 ~ 0L,
      x3 == 1 | x4 == 1 ~ 1L,
      TRUE ~ NA_integer_
    ),
    # 逐行求和,自动忽略NA
    score = rowSums(cbind(part1, part2), na.rm = TRUE)
  )

方法2:简洁写法(无需中间列)

直接在rowSums中嵌套两组case_when逻辑:

library(dplyr)

x <- x %>%
  mutate(
    score = rowSums(
      cbind(
        case_when(x1 == 0 & x2 == 0 ~ 0L, x1 == 1 | x2 == 1 ~ 1L, TRUE ~ NA_integer_),
        case_when(x3 == 0 & x4 == 0 ~ 0L, x3 == 1 | x4 == 1 ~ 1L, TRUE ~ NA_integer_)
      ),
      na.rm = TRUE
    )
  )

运行后score列将得到期望的1, 2, 2, 1, 0, 1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 16:14:54