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

如何在R中为价格差值计算添加百分比并保留原始值

问题

现有R数据集disk:

disk=structure(list(competitor_id = c(2L, 2L, 2L, 2L, 2L, 2L, 8L, 
8L, 8L, 8L, 8L, 8L), comp_article_id = c("7976DD6D-38BD-D902-F7A8-A015B37A7128", 
"7976DD6D-38BD-D902-F7A8-A015B37A7128", "7976DD6D-38BD-D902-F7A8-A015B37A7128", 
"5683D414-DED2-1B4C-FD03-200B56319104", "5683D414-DED2-1B4C-FD03-200B56319104", 
"5683D414-DED2-1B4C-FD03-200B56319104", "7976DD6D-38BD-D902-F7A8-A015B37A7128", 
"7976DD6D-38BD-D902-F7A8-A015B37A7128", "7976DD6D-38BD-D902-F7A8-A015B37A7128", 
"5683D414-DED2-1B4C-FD03-200B56319104", "5683D414-DED2-1B4C-FD03-200B56319104", 
"5683D414-DED2-1B4C-FD03-200B56319104"), MDM_Key = c(16L, 16L, 
16L, 49L, 49L, 49L, 16L, 16L, 16L, 49L, 49L, 49L), subgroup_id = c("04.01.2001", 
"04.01.2001", "04.01.2001", "04.01.2001", "04.01.2001", "04.01.2001", 
"04.01.2001", "04.01.2001", "04.01.2001", "04.01.2001", "04.01.2001", 
"04.01.2001"), month_id = c(202211L, 202211L, 202212L, 202003L, 
202004L, 202007L, 202211L, 202211L, 202212L, 202003L, 202004L, 
202007L), comp_disc_price = c(1207.06, 1207.06, 1207.06, 720.58, 
774.62, 774.62, 1207.06, 1207.06, 1207.06, 720.58, 774.62, 774.62
), iek_disc_price = c(553.83, 553.83, 537.7, 665.83, 665.83, 
665.83, 553.83, 553.83, 537.7, 665.83, 665.83, 665.83)), class = "data.frame", row.names = c(NA, 
-12L))

需求:

  • 按competitor_id和MDM_Key分组
  • 对comp_disc_price和iek_disc_price两个变量,计算月度(month_id)间的绝对差值(大月份值减小月份值)
  • 同时计算对应的百分比差值
  • 保留原始变量

现有代码仅能计算绝对差值,无法得到百分比差值:

disk %>%
  arrange(competitor_id, month_id) %>%
  group_by(competitor_id,MDM_Key) %>%
  mutate(across(c(comp_disc_price, iek_disc_price), ~ c(diff(.), NA))) %>%
  ungroup()

期望输出包含原始变量、绝对差值列(如abs_comp_disc、abs_iek_disk)和百分比差值列(如perc_comp_disk、perc_iek_disk),示例如下:

competitor_id                      comp_article_id MDM_Key
1             2 7976DD6D-38BD-D902-F7A8-A015B37A7128      16
2             2 7976DD6D-38BD-D902-F7A8-A015B37A7128      16
3             2 7976DD6D-38BD-D902-F7A8-A015B37A7128      16
4             2 5683D414-DED2-1B4C-FD03-200B56319104      49
5             2 5683D414-DED2-1B4C-FD03-200B56319104      49
  subgroup_id month_id comp_disc_price iek_disc_price abs_comp_disc
1  04.01.2001   202210         1207.06         553.83         92.94
2  04.01.2001   202211         1300.00         553.83        -50.00
3  04.01.2001   202212         1250.00         537.70            NA
4  04.01.2001   202003          720.58         665.83         54.04
5  04.01.2001   202004          774.62         665.83            NA
  abs_iek_disk perc_comp_disk perc_iek_disk
1         0.00     0.07699700    0.00000000
2       -16.13    -0.03846154   -0.02912446
3           NA             NA            NA
4         0.00     0.00000000    0.00000000
5           NA             NA            NA
解决方法

可以通过dplyr的mutate结合across,为每个价格变量分别生成绝对差值和百分比差值列,同时保证分组内按月份排序。

完整代码如下:

library(dplyr)

disk_result <- disk %>%
  # 按分组+月份排序,确保差值计算的时间顺序正确
  arrange(competitor_id, MDM_Key, month_id) %>%
  group_by(competitor_id, MDM_Key) %>%
  mutate(
    # 生成绝对差值列,格式为abs_原变量名
    across(c(comp_disc_price, iek_disc_price), 
           ~ c(diff(.), NA), 
           .names = "abs_{.col}"),
    # 生成百分比差值列,格式为perc_原变量名,公式为(当前值-上月值)/上月值
    across(c(comp_disc_price, iek_disc_price), 
           ~ c(diff(.)/lag(.), NA), 
           .names = "perc_{.col}")
  ) %>%
  # 重命名列名,匹配期望输出的格式
  rename(
    abs_comp_disc = abs_comp_disc_price,
    abs_iek_disk = abs_iek_disc_price,
    perc_comp_disk = perc_comp_disc_price,
    perc_iek_disk = perc_iek_disc_price
  ) %>%
  ungroup()

# 查看结果
print(disk_result)

代码说明

  1. 排序处理:先按competitor_id、MDM_Key和month_id排序,确保每个分组内的行按时间顺序排列,这样diff()和lag()能正确计算月度间的差值。
  2. 绝对差值计算:用diff()计算当前值与前一个值的差,最后一行补NA,通过.names参数自动生成带abs_前缀的列。
  3. 百分比差值计算:通过diff(.)/lag(.)计算相对变化率,同样最后一行补NA,生成带perc_前缀的列。
  4. 列名调整:将自动生成的列名重命名为期望的格式。

如果数据中存在同一分组同一月份的重复行(如示例数据中competitor_id=2、MDM_Key=16的202211月份有两行),可在排序后添加distinct(competitor_id, MDM_Key, month_id, .keep_all = TRUE)做去重处理,避免重复行的差值计算出现冗余。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 18:05:16