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

使用dplyr的filter、mutate、case_when处理带NA的绝对差求和问题

问题描述

给定样本数据:

structure(list(role = c("r1", "c1", "r2", "c2"), v1 = c(1200, 
0, 1200, 0), v2 = c(900, 500, 900, 900), v3 = c(600, 800, 600, 
1800), v4 = c(300, 900, 300, 2700)), class = "data.frame", row.names = c(NA, 
-4L), codepage = 65001L)

需求:

  • 根据role列的值,对v1-v4分别与指定数值计算绝对差后求和,生成accuracy列:
    • 当role为r1或r2时,v1-v4分别与3600、2700、1800、300计算绝对差后求和;
    • 当role为c1或c2时,v1-v4分别与0、300、600、900计算绝对差后求和;

原尝试的dplyr代码:

data <- data %>% mutate(accuracy =
case_when((role == 'r1') ~ 
 abs(v1 - 3600) + abs(v2 - 2700) + abs(v3 - 1800) + abs(v4 - 300),
(role == 'r2') ~ 
abs(v1 - 3600) + abs(v2 - 2700) + abs(v3 - 1800) + abs(v4 - 300),
(role == 'c1') ~ 
abs(v1 - 0) + abs(v2 - 300) + abs(v3 - 600) + abs(v4 - 900),
(role == 'c2') ~
abs(v1 - 0) + abs(v2 - 300) + abs(v3 - 600) + abs(v4 - 900)))

问题:该代码在小数据集正常,但含大量NA的大数据集中accuracy列全为NA,需要将NA视为0参与计算,避免结果异常。

解决方案

核心思路

  1. 用coalesce()函数将v1-v4中的NA替换为0,消除绝对差计算时的NA传递;
  2. 简化case_when的条件判断,将同规则的role值合并,减少冗余代码;
  3. 处理role为NA或未知值的边界情况,确保所有行都能生成有效结果。

修正后的代码(不修改原始v列)

library(dplyr)

data <- data %>%
  mutate(
    accuracy = case_when(
      # 处理r1/r2组,嵌套coalesce将NA转0
      role %in% c("r1", "r2") ~ abs(coalesce(v1, 0) - 3600) + 
                                 abs(coalesce(v2, 0) - 2700) + 
                                 abs(coalesce(v3, 0) - 1800) + 
                                 abs(coalesce(v4, 0) - 300),
      # 处理c1/c2组
      role %in% c("c1", "c2") ~ abs(coalesce(v1, 0) - 0) + 
                                 abs(coalesce(v2, 0) - 300) + 
                                 abs(coalesce(v3, 0) - 600) + 
                                 abs(coalesce(v4, 0) - 900),
      # 处理role为NA或其他未知值,默认按0计算,可按需调整
      TRUE ~ abs(coalesce(v1, 0)) + abs(coalesce(v2, 0)) + abs(coalesce(v3, 0)) + abs(coalesce(v4, 0))
    )
  )

可选优化(提前替换v列NA)

如果允许修改原始v1-v4列,可提前统一替换NA,让计算代码更简洁:

data <- data %>%
  mutate(
    v1 = coalesce(v1, 0),
    v2 = coalesce(v2, 0),
    v3 = coalesce(v3, 0),
    v4 = coalesce(v4, 0),
    accuracy = case_when(
      role %in% c("r1", "r2") ~ abs(v1 - 3600) + abs(v2 - 2700) + abs(v3 - 1800) + abs(v4 - 300),
      role %in% c("c1", "c2") ~ abs(v1) + abs(v2 - 300) + abs(v3 - 600) + abs(v4 - 900),
      TRUE ~ v1 + v2 + v3 + v4
    )
  )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 01:52:12