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

如何使用dplyr计算data.frame各时间点A/B类数值的比值

问题背景

现有data.frame格式数据集,需按Type分类分组计算衍生变量,示例数据构造代码:

df = data.frame(time = rep(seq(10),each=2),Type=rep(c("A","B"),times=10),value = runif(20))

目标是生成新的data.frame,输出每个time时间点下,Type=A的value与Type=B的value的比值。
之前尝试用如下代码实现:

df2 <- df |> group_by(time) |> mutate(new_value= value[Type=="A"] / value[Type=="B"],.keep="none")

运行后每个时间点返回2条重复的new_value记录,不符合预期。

问题原因

这是dplyr包中mutate()函数的默认行为导致的:mutate()不会改变输入数据的行数,按time分组后每组固定有2行(分别对应A、B两个类型),即使你计算出的A/B比值是长度为1的单值,mutate()也会自动把这个值循环填充到组内所有行,自然就出现了每个时间点两条重复值的情况。

修正方案

如果需要每个时间点仅输出1条比值记录,把mutate()替换为summarise()即可,该函数会把每个分组的计算结果折叠为单行:

library(dplyr)
df2 <- df |> 
  group_by(time) |> 
  summarise(
    new_value = value[Type == "A"] / value[Type == "B"],
    .groups = "drop"
  )

如果需要保留原始数据集的所有行,同时在每行附上同时间点的A/B比值,原来的mutate()写法本身没有错误,重复值是符合逻辑的正常输出——同一个时间点下,无论是A类行还是B类行,对应的同组A/B比值本来就是同一个值。如果不需要重复记录,在计算后加一层筛选即可:

df2 <- df |> 
  group_by(time) |> 
  mutate(new_value = value[Type=="A"] / value[Type=="B"]) |>
  # 筛选A类或B类行都可以,同组比值完全一致
  filter(Type == "A") |>
  select(time, new_value)

以上写法的生效前提是:每个time分组下有且仅有1条A类记录、1条B类记录。如果存在某类记录缺失、某类对应多条记录的情况,会出现计算长度不匹配的报错,计算前建议先校验分组内的类型分布。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:21:26