基于多列多行计算data.frame新列ZONE的值
按UID分组生成ZONE列的解决方案
针对你的sf长格式数据框,我们可以用dplyr按UID分组,结合多条件判断生成符合要求的ZONE列,具体代码和解释如下:
代码实现
# 加载所需包 library(dplyr) library(sf) # 假设你的数据框名为df,包含UID、SPECIES、PERCENT及几何列 df <- df %>% group_by(UID) %>% mutate( # 标记当前UID是否所有物种都是NA all_species_na = all(is.na(SPECIES)), # 检查当前UID是否包含物种A或AT contains_A_AT = any(SPECIES %in% c("A", "AT"), na.rm = TRUE), # 计算当前UID中A和AT的PERCENT总和 A_AT_total_percent = sum(PERCENT[SPECIES %in% c("A", "AT")], na.rm = TRUE), # 按规则生成ZONE列 ZONE = case_when( all_species_na ~ NA_character_, !contains_A_AT ~ "Misc.", A_AT_total_percent >= 80 ~ "For", TRUE ~ "Gra" ) ) %>% ungroup() %>% # 移除临时辅助列(可选,若不需要可删除此步) select(-all_species_na, -contains_A_AT, -A_AT_total_percent)
代码解释
group_by(UID):确保所有计算都基于单个多边形(UID)分组进行,解决你之前未分组的问题all_species_na:判断当前UID下是否所有物种值都是NA,对应规则2contains_A_AT:检查当前UID是否包含物种A或AT,对应规则1和规则3的前置条件A_AT_total_percent:计算A和AT的总占比,对应规则3的阈值判断case_when:按优先级依次匹配规则,生成ZONE列:- 优先匹配所有物种为NA的情况,ZONE设为NA
- 若不含A/AT,ZONE设为"Misc."
- 若含A/AT且总占比≥80,ZONE设为"For"
- 剩余情况(含A/AT但总占比<80),ZONE设为"Gra"
ungroup():取消分组,避免后续操作受分组状态影响select():移除临时辅助列,保持数据结构简洁
内容的提问来源于stack exchange,提问作者Crippycajes
相关产品推荐
相关产品推荐

