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

tidyverse中仅能用pivot_wider()实现特定行值的汇总计算吗?

问题与解决方案

我需要对整洁格式的测试结果数据汇总计算索引值,要求按group分组,对特定var值对应的result做加权求和(如b值/2 + d值/3)。习惯用group_by()和summarise()结合result[var=='A']的子集方式实现,但该方法无法正常运行,目前仅能通过pivot_wider()实现需求。

可复现代码

示例数据与错误尝试

library(tidyverse)
# 示例数据
df <- data.frame(group = c('foo', 'foo', 'foo', 'foo','bar', 'bar', 'bar', 'bar'), 
                 var = c('a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'), 
                 result = c(1, 6, 9, 3, 5, 0, 2, 9))

# 此方法无法运行,按错误提示改用reframe()也不行
index <- df %>% 
  group_by(group) %>% 
  summarise(var = 'index', 
            result = result[var=='b']/2 + result[var=='d']/3)
#> 警告:在dplyr 1.1.0版本中,summarise()每组返回多于(或少于)1行的用法已被弃用。
#> ℹ 请改用reframe()。
#> ℹ 从summarise()切换到reframe()时,请注意reframe()始终返回未分组的数据框,请相应调整。
#> 调用lifecycle::last_lifecycle_warnings()查看警告产生位置。
#> `summarise()`已按'group'分组输出,可使用`.groups`参数覆盖此设置。

可行的pivot_wider方法

# 使用pivot_wider可以实现,这是唯一的方法吗?
index <- df %>% 
  filter(var %in% c('b', 'd')) %>% 
  pivot_wider(names_from = var, values_from = result) %>% 
  mutate(index = b/2 + d/3) %>% 
  pivot_longer(cols = c('b', 'd', 'index'), 
               names_to = 'var', 
               values_to = 'result')

替代方法:无需pivot_wider的group_by+summarise写法

其实不用转宽表也能实现,核心是确保每组中提取的b和d对应的值是单个标量,避免返回多值。

方法1:先筛选目标var再加权求和

index <- df %>%
  filter(var %in% c("b", "d")) %>%
  group_by(group) %>%
  summarise(
    var = "index",
    result = sum(if_else(var == "b", result/2, result/3))
  )
# 如果需要保留原b、d的数据,再和原数据合并即可
final_df <- bind_rows(df, index)

方法2:直接提取每组的b和d值

因为每组中b和d各出现一次,所以可以用first()确保拿到单个值:

index <- df %>%
  group_by(group) %>%
  summarise(
    var = "index",
    result = first(result[var == "b"])/2 + first(result[var == "d"])/3
  )
# 合并原数据得到完整结果
final_df <- bind_rows(df, index)

这两种方法都能直接用group_by()+summarise()完成索引计算,不需要来回转置宽表/长表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:02:23