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

如何使用dplyr根据第二个数据框更新第一个数据框?

用dplyr实现按年份规则更新数据框

问题说明

我们需要用second_df的数据更新first_df:first_df的t1/t2/t3/t4分别对应2024/2025/2026/2027年;更新规则为:second_df中每个ShortName对应的Year,需将first_df里该年份及之后的列值替换为对应的Value。

原始数据框代码

library(dplyr)

# 初始数据框
first_df <- data.frame(
  ShortName = c("A", "B", "C"),
  t1 = c(0, 0, 0 ),
  t2 = c(1, 1, 1),
  t3 = c(2, 2, 2),
  t4 = c(3, 3, 3)
)

# 更新规则数据框
second_df <- data.frame(
  ShortName = c("A", "B", "C"),
  Year = c(2024, 2025, 2026 ),
  Value=c(0, 5, 10)
)

解决方案代码

我们可以通过长格式转换-关联判断-宽格式还原的流程实现需求,需配合tidyr包的pivot_longer/pivot_wider函数:

library(tidyr)

# 建立t列与年份的映射关系
year_mapping <- c(t1 = 2024, t2 = 2025, t3 = 2026, t4 = 2027)

updated_result <- first_df %>%
  # 将t1-t4列转为长格式,方便统一处理
  pivot_longer(
    cols = starts_with("t"),
    names_to = "period",
    values_to = "original_val"
  ) %>%
  # 按ShortName关联更新规则数据
  left_join(second_df, by = "ShortName") %>%
  # 匹配当前period对应的年份
  mutate(current_year = year_mapping[period]) %>%
  # 应用更新规则:当前年份≥目标Year则替换为Value,否则保留原值
  mutate(final_val = ifelse(current_year >= Year, Value, original_val)) %>%
  # 转回宽格式,恢复原数据结构
  pivot_wider(
    id_cols = ShortName,
    names_from = "period",
    values_from = "final_val"
  ) %>%
  # 保持原数据的列顺序
  select(ShortName, t1, t2, t3, t4)

# 查看最终结果
print(updated_result)

运行结果

ShortName t1 t2 t3 t4
1         A  0  0  0  0
2         B  0  5  5  5
3         C  0  1 10 10

关键逻辑说明

  1. 长格式转换:把分散的年份列(t1-t4)转为统一的行记录,避免对每一列单独写更新逻辑;
  2. 年份匹配:通过预定义的映射关系,把t开头的列名转为对应的年份值,方便后续判断;
  3. 规则应用:用ifelse判断当前年份是否符合更新条件,批量替换数值;
  4. 宽格式还原:将处理后的长数据转回原有的宽格式结构,保持列顺序一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:53:25