R语言:按分组条件从不同列汇总行数据
按Natura 2000分组汇总指定面积的解决方案
问题描述
现有如下数据集:
| Name | Total_Surface | N2000 | SurfaceN2000 |
|---|---|---|---|
| A | 1 | Yes | 0.5 |
| B | 5 | No | NA |
| C | 11 | No | NA |
| D | 10 | Yes | 5 |
需要按N2000因子分组计算总面积,规则为:
- 当站点属于N2000网络(
N2000 = "Yes")时,使用SurfaceN2000列的数据求和 - 不属于时(
N2000 = "No"),使用Total_Surface列的数据求和
用户尝试的代码未达到预期效果:
df %>% group_by(N2000) %>% summarise(surface= case_when(N2000== "No" ~ sum(Total_Surface,na.rm = TRUE), N2000== "Yes" ~ sum(SurfaceN2000,na.rm = TRUE)))
期望输出:
| N2000 | Surface |
|---|---|
| Yes | 5.5 |
| No | 16 |
问题分析
你之前的代码错误在于:group_by后,case_when会对组内的每一行进行判断,而sum返回的是组内总和(长度为1),但case_when会尝试将这个值匹配到组内的每一行,导致summarise收到长度不等于1的结果,进而报错或返回异常值。
解决方案
方法1:新增中间列后分组求和
先为每行确定要使用的面积值,再分组汇总,逻辑清晰且易于维护:
library(dplyr) df %>% # 为每行标记要使用的面积数据 mutate(target_surface = case_when( N2000 == "Yes" ~ SurfaceN2000, N2000 == "No" ~ Total_Surface )) %>% group_by(N2000) %>% summarise(Surface = sum(target_surface, na.rm = TRUE))
方法2:直接在summarise中按组判断
如果不想新增列,可以利用cur_group()或first()获取当前组的N2000值,直接选择对应列求和:
# 使用cur_group()获取当前组信息 df %>% group_by(N2000) %>% summarise(Surface = ifelse(cur_group()$N2000 == "Yes", sum(SurfaceN2000, na.rm = TRUE), sum(Total_Surface, na.rm = TRUE))) # 或使用first()取组内首个N2000值判断 df %>% group_by(N2000) %>% summarise(Surface = case_when( first(N2000) == "Yes" ~ sum(SurfaceN2000, na.rm = TRUE), first(N2000) == "No" ~ sum(Total_Surface, na.rm = TRUE) ))
以上两种方法都能输出你期望的结果。
内容的提问来源于stack exchange,提问作者Lara
相关产品推荐
相关产品推荐

