R语言基于dataframe列值按条件规则新建年份列的实现方法
实现思路
- 先明确数据结构:表中第一列为分析单元标识(如示例里的UA-1、UA-2),其余列均为不同年份对应的建成区面积占比数值,列名直接对应年份信息。
- 逐行按规则计算:
- 对每一行,排除标识列后遍历所有占比字段,找到占比的最大值,同时定位该最大值对应的列名,提取年份值
- 做阈值判断:如果该行占比最大值大于25,新增列就取最大值对应的年份;如果最大值小于等于25,新增列统一赋值为2005
- 特殊情况处理:如果同一行存在多个年份的占比同时为最大值,可根据业务需求选择取第一个匹配年份/最后一个匹配年份,以下代码默认取第一个匹配到的最大值对应年份。
R代码实现方案
首先先构造和描述一致的示例测试数据,方便验证效果:
# 构造示例数据 df <- data.frame( unit_id = c("UA-1", "UA-2", "UA-3"), `1985` = c(26, 12, 8), `1990` = c(22, 18, 15), `1995` = c(18, 22, 20), `2000` = c(15, 24, 23), check.names = FALSE )
提供两种常用实现方式,可根据自己的工作流选择:
方式1:tidyverse(dplyr+tidyr)写法
适合日常用tidyverse生态处理数据的场景,逻辑可读性更强:
library(dplyr) library(tidyr) df <- df %>% # 宽表转长表,拆分出年份和占比值 pivot_longer(cols = -unit_id, names_to = "year", values_to = "ratio") %>% mutate(year = as.numeric(year)) %>% # 按分析单元分组计算 group_by(unit_id) %>% mutate( max_ratio = max(ratio), match_year = year[which.max(ratio)], new_col = ifelse(max_ratio > 25, match_year, 2005) ) %>% # 转回原表宽表结构 pivot_wider(names_from = year, values_from = ratio) %>% # 移除计算过程的中间列 select(-max_ratio, -match_year) %>% ungroup()
方式2:基础R写法
无需安装加载第三方包,运行效率更高,适合大表场景:
# 指定占比列范围:此处默认排除第一列ID列,可根据实际表结构调整列选择逻辑 ratio_col_names <- colnames(df)[-1] ratio_matrix <- as.matrix(df[, ratio_col_names]) # 逐行定位最大值对应的列位置 max_col_pos <- max.col(ratio_matrix, ties.method = "first") # 提取对应年份 match_year <- as.numeric(ratio_col_names[max_col_pos]) # 逐行计算占比最大值 row_max_ratio <- apply(ratio_matrix, 1, max) # 按规则生成新列 df$new_col <- ifelse(row_max_ratio > 25, match_year, 2005)
代码调整提示:如果你的占比列不是从第二列开始,只需要修改
ratio_col_names的取值,传入所有占比字段的列名向量即可;如果需要取并列最大值的最后一个对应年份,把max.col的ties.method参数改为"last"即可。
内容的提问来源于stack exchange,提问作者José Carlos Rojas
相关产品推荐
相关产品推荐

