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

在R的dplyr中基于多分组实现批量逐行平均的方案问询

批量计算Likert量表分组逐行均值的解决方案

场景与现有代码

我有一个包含Likert量表回答的随机数据框df,所有列是以q1、q2…q6命名的问题。另有一个数据框df2定义了问题的分组,例如q1、q2、q3属于A组,q4属于B组,q5、q6属于C组。我需要计算每组的逐行均值,例如结果数据框中需有列A存储q1、q2、q3的逐行均值。

已编写的手动指定分组的代码:

likert_levels <- c(1,2,3,4,5)
set.seed(42)
library(dplyr)
df <-
  tibble(
    "q1" = sample(likert_levels, 150, replace = TRUE),
    "q2" = sample(likert_levels, 150, replace = TRUE, prob = 5:1),
    "q3" = sample(likert_levels, 150, replace = TRUE, prob = 1:5),
    "q4" = sample(likert_levels, 150, replace = TRUE, prob = 1:5),
    "q5" = sample(c(likert_levels, NA), 150, replace = TRUE),
    "q6" = sample(likert_levels, 150, replace = TRUE, prob = c(1, 0, 1, 1, 0))
  ) %>%
  mutate(across(everything(), ~ factor(.x, levels = likert_levels)))

df
df2 = tibble(categories = c("A","A","A","B","C","C"),
             questions = c("q1","q2","q3","q4","q5","q6"))

df2
df%>%
  mutate(id = row_number())%>%
  tidyr::pivot_longer(!id,names_to = "questions",values_to = "responses")%>%
  left_join(.,df2,by="questions")

df_cor=df%>%
  mutate_if(is.factor,as.double)%>%
  rowwise() %>%
  mutate(QA = mean(c(q1, q2, q3),na.rm=TRUE),
         QB = mean(c(q4),na.rm=TRUE),
         QC = mean(c(q5, q6),na.rm=TRUE))%>%
  select(QA,QB,QC)
df_cor

问题

实际数据集包含100个问题和20余个分组,如何避免手动编写rowwise均值的mutate语句,实现自动批量处理?


解决方案

方法一:长格式转宽格式批量计算

利用tidyr的重塑函数,通过长格式处理自动关联分组并计算均值,无需手动指定分组:

library(dplyr)
library(tidyr)

# 转换因子为数值并添加行标识
df_processed <- df %>%
  mutate(across(everything(), as.double),
         id = row_number()) %>%
  # 转为长格式关联分组信息
  pivot_longer(-id, names_to = "questions", values_to = "responses") %>%
  left_join(df2, by = "questions") %>%
  # 按行和分组计算均值
  group_by(id, categories) %>%
  summarise(mean_value = mean(responses, na.rm = TRUE), .groups = "drop") %>%
  # 转回宽格式生成分组均值列
  pivot_wider(names_from = categories, values_from = mean_value, names_prefix = "Q")

# 输出最终结果(去掉id列)
df_processed %>% select(-id)

方法二:宽格式下动态生成均值列

从df2中提取分组与问题的映射关系,循环生成每个分组的均值计算逻辑:

library(dplyr)

# 转换因子为数值
df_numeric <- df %>% mutate(across(everything(), as.double))

# 提取每个分组对应的问题列表
group_questions <- df2 %>%
  group_by(categories) %>%
  summarise(questions = list(questions), .groups = "drop")

# 批量生成分组均值列
df_result <- df_numeric
for (row in 1:nrow(group_questions)) {
  group_name <- group_questions$categories[row]
  q_list <- group_questions$questions[row][[1]]
  df_result <- df_result %>%
    mutate(!!paste0("Q", group_name) := rowMeans(across(all_of(q_list)), na.rm = TRUE))
}

# 只保留分组均值列
df_result %>% select(starts_with("Q"))

两种方法均可自动适配任意数量的分组与问题,无需手动修改核心逻辑。方法一符合tidyverse风格,可读性更强;方法二直接在宽格式下操作,适合习惯宽格式数据的场景。

内容的提问来源于stack exchange,提问作者Homer Jay Simpson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:56:00