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

在R数据框中计算增长率:新增Val1、Val2的增长百分比列

解决R数据框的增长率计算问题

我来帮你搞定这个需求!首先咱们得先处理这个有点“不规则”的原始数据——它是按月度块排列的,每个月度汇总行下面跟着A-E的明细行,而且Feb和Jan里的A-E顺序还不一样,直接计算肯定会出错。咱们分步骤来:

步骤1:构造原始数据

先把你给的数据转换成R能识别的数据框:

df <- data.frame(
  Month = c("Feb-17", "A", "B", "C", "D", "E", "Jan-17", "A", "B", "C", "D", "E"),
  Val1 = c(250, 25, 25, 100, 10, 40, 200, 20, 40, 100, 20, 20),
  Val2 = c(10000, 2000, 2000, 2000, 2000, 2000, 8000, 1000, 1600, 1600, 1600, 2200),
  Part1 = c(25, 5, 5, 5, 5, 5, 50, 10, 10, 10, 10, 10),
  Part2 = c(100, 20, 20, 20, 20, 20, 100, 20, 20, 20, 20, 20),
  stringsAsFactors = FALSE
)

步骤2:给数据打分组标签

咱们需要识别出每个月度块(Feb-17和Jan-17),给每一行打上所属月份的标签,这样后续才能准确匹配A-E的对应数据:

# 识别月度汇总行(格式是"XXX-XX"),生成分组ID
df$group <- cumsum(grepl("^[A-Za-z]{3}-\\d{2}$", df$Month))
# 提取每个分组对应的月份名称
month_labels <- df$Month[grepl("^[A-Za-z]{3}-\\d{2}$", df$Month)]
# 给每一行分配所属月份
df$month <- rep(month_labels, each = 6)  # 每个月度块有6行:1行汇总+5行明细

步骤3:拆分明细并计算增长率

因为A-E的顺序在两个月份里不一样,所以咱们要按**类别(A-E)**来匹配数据,而不是按行顺序。这里用dplyr和tidyr来处理:

library(dplyr)
library(tidyr)

# 提取明细行(排除汇总行)
detail_df <- df[!grepl("^[A-Za-z]{3}-\\d{2}$", df$Month), ]

# 把数据转成宽格式,让同一个类别的Feb和Jan数据在同一行
wide_detail <- detail_df %>%
  pivot_wider(
    id_cols = Month,  # Month列这里是A-E类别
    names_from = month,
    values_from = c(Val1, Val2)
  )

# 计算增长率,公式:(Feb值 - Jan值)/Jan值 * 100,保留2位小数
wide_detail <- wide_detail %>%
  mutate(
    Per_1 = round(((Val1_Feb-17 - Val1_Jan-17)/Val1_Jan-17)*100, 2),
    Per_2 = round(((Val2_Feb-17 - Val2_Jan-17)/Val2_Jan-17)*100, 2)
  )

步骤4:把增长率合并回原始数据

现在把计算好的明细增长率匹配回原始数据,同时计算汇总行的整体增长率:

# 匹配明细行的增长率
result_df <- df %>%
  left_join(wide_detail %>% select(Month, Per_1, Per_2), by = "Month")

# 计算汇总行的整体增长率
summary_rows <- result_df[grepl("^[A-Za-z]{3}-\\d{2}$", result_df$Month), ]
summary_rows <- summary_rows %>%
  mutate(
    Per_1 = round(((Val1 - Val1[month == "Jan-17"])/Val1[month == "Jan-17"])*100, 2),
    Per_2 = round(((Val2 - Val2[month == "Jan-17"])/Val2[month == "Jan-17"])*100, 2)
  )

# 替换原始数据中的汇总行增长率
result_df[grepl("^[A-Za-z]{3}-\\d{2}$", result_df$Month), c("Per_1", "Per_2")] <- summary_rows[, c("Per_1", "Per_2")]

最终结果

运行完上面的代码后,result_df就是你要的最终数据框,它在Val1后新增了Per_1列,Val2后新增了Per_2列,包含了Feb-17相对Jan-17的增长率(正数是增长,负数是下降)。你可以用print(result_df)查看完整结果:

print(result_df)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:42:28