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

如何基于饮品类型对drink_vol列行求和并生成对应新列?

问题

目标

针对每种饮品类型(1、2、3),根据drink_type_1和drink_type_2标记的类型,创建包含drink_vol_1和drink_vol_2行求和结果的新列。

样本数据

study_id <- c(1,2,3,4,5,6)
drink_type_1 <-c(1,2,3,1,2,3)
drink_vol_1 <- c(100,500,1000,100,500,750)
drink_type_2 <-c(NA,3,2,1,NA,3)
drink_vol_2 <- c(NA,125,300,200,NA,500)

drink_df  <- data.frame(study_id,drink_type_1,drink_vol_1,drink_type_2,drink_vol_2) 

drink_df <- drink_df %>% mutate_at(c('drink_type_1','drink_type_2'), as.factor) 

尝试及困惑

我一开始觉得需要转换数据框格式,试了这段代码:

drink_pivot <- drink_df %>% pivot_longer(cols = c('drink_type_1','drink_type_2'), names_to = "drink", values_to = "drink_type") 

但之后不知道怎么继续,求后续实现方法。

期望输出

study_id <- c(1,2,3,4,5,6)
a <- c(100,0,0,300,0,0)
b <- c(0,500,300,0,500,0)
c <- c(0,125,1000,0,0,1250)

DF  <- data.frame(study_id,a,b,c)

解决方案

你已经用pivot_longer找对了方向,接下来需要把体积列和类型列对应起来处理,再通过分组求和、转回宽格式得到目标结果。这里提供两种实现方式:

方式一:手动匹配类型与体积列

library(tidyverse)

# 1. 转换类型列为长格式,同时匹配对应体积列
drink_long <- drink_df %>%
  pivot_longer(
    cols = starts_with("drink_type_"),
    names_to = "type_col",
    values_to = "drink_type",
    values_drop_na = TRUE
  ) %>%
  # 替换列名中的type为vol,得到对应体积列的名称
  mutate(vol_col = str_replace(type_col, "type", "vol")) %>%
  # 提取对应体积值
  rowwise() %>%
  mutate(drink_vol = get(vol_col)) %>%
  ungroup() %>%
  select(study_id, drink_type, drink_vol)

# 2. 分组求和后转回宽格式
result <- drink_long %>%
  group_by(study_id, drink_type) %>%
  summarise(total_vol = sum(drink_vol), .groups = "drop") %>%
  pivot_wider(
    names_from = drink_type,
    values_from = total_vol,
    values_fill = 0
  ) %>%
  # 重命名列匹配期望输出
  rename(a = `1`, b = `2`, c = `3`)

# 3. 合并回原数据的study_id,确保无遗漏
final_df <- drink_df %>%
  select(study_id) %>%
  left_join(result, by = "study_id")

print(final_df)

方式二:用正则拆分列名(更简洁)

利用pivot_longer的names_pattern参数,直接拆分类型和体积列的前缀与分组,自动对应匹配:

library(tidyverse)

final_df <- drink_df %>%
  pivot_longer(
    cols = -study_id,
    # 正则拆分列名:提取type/vol和数字分组
    names_pattern = "drink_(type|vol)_(\\d)",
    names_to = c(".value", "group"),
    values_drop_na = TRUE
  ) %>%
  group_by(study_id, type) %>%
  summarise(vol = sum(vol), .groups = "drop") %>%
  pivot_wider(
    names_from = type,
    values_from = vol,
    values_fill = 0
  ) %>%
  rename(a = `1`, b = `2`, c = `3`) %>%
  right_join(drink_df %>% select(study_id), by = "study_id") %>%
  arrange(study_id)

print(final_df)

两种方式运行后都会得到与期望输出一致的结果:

study_id   a   b    c
1        1 100   0    0
2        2   0 500  125
3        3   0 300 1000
4        4 300   0    0
5        5   0 500    0
6        6   0   0 1250

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 18:42:47