基于现有类别组合扩展DataFrame并计算均值的实现方法
解决方法
expand.grid其实不太适合做这件事——它主要用来生成笛卡尔积(比如重复配对的情况),反而你之前尝试的combn才是生成类别组合的正确工具,只是需要调整用法来匹配你的需求。下面是具体的R代码实现,完美贴合你的示例场景:
步骤1:构造示例数据
df <- data.frame( Class = c("A", "B", "C"), Value = c(1, 2, 3), Treatment = c(1, 1, 1) )
步骤2:生成所有非空类别组合
覆盖从单个类别到全部类别的所有组合:
# 获取唯一类别 unique_classes <- unique(df$Class) # 生成1个、2个、3个类别的所有组合,拼接成字符串 all_combs <- unlist(lapply(1:length(unique_classes), function(k) { combn(unique_classes, k, FUN = paste0, collapse = "") }), use.names = FALSE)
步骤3:计算每个组合的均值并保留其他列
遍历每个组合,筛选对应数据计算均值,同时保留Treatment列(假设同Treatment组内的类别共享相同Treatment值):
# 批量处理每个组合 comb_results <- lapply(all_combs, function(comb) { # 拆分组合字符串得到单个类别 sub_classes <- strsplit(comb, "")[[1]] # 筛选对应数据行 sub_data <- df[df$Class %in% sub_classes, ] # 计算均值 mean_val <- mean(sub_data$Value) # 提取Treatment值(取唯一值即可) treatment_val <- unique(sub_data$Treatment) data.frame(Class = comb, Mean = mean_val, Treatment = treatment_val) }) # 合并所有组合结果 final_df <- do.call(rbind, comb_results)
最终结果
运行后final_df就是你要的格式:
| Class | Mean | Treatment |
|---|---|---|
| A | 1 | 1 |
| B | 2 | 1 |
| C | 3 | 1 |
| AB | 1.5 | 1 |
| AC | 2 | 1 |
| BC | 2.5 | 1 |
| ABC | 2 | 1 |
(注:你的示例里ABC的均值写的是3,应该是笔误,实际均值是(1+2+3)/3=2)
多Treatment组的扩展
如果你的数据集有多个Treatment组,只需按Treatment分组处理即可,比如用dplyr:
library(dplyr) df_multi <- data.frame( Class = rep(c("A", "B", "C"), 2), Value = c(1,2,3,4,5,6), Treatment = rep(c(1,2), each=3) ) final_multi <- df_multi %>% group_by(Treatment) %>% group_map(function(sub_df, key) { unique_classes <- unique(sub_df$Class) all_combs <- unlist(lapply(1:length(unique_classes), function(k) { combn(unique_classes, k, FUN = paste0, collapse = "") }), use.names = FALSE) lapply(all_combs, function(comb) { sub_classes <- strsplit(comb, "")[[1]] sub_data <- sub_df[sub_df$Class %in% sub_classes, ] mean_val <- mean(sub_data$Value) data.frame(Class = comb, Mean = mean_val, Treatment = key$Treatment) }) %>% do.call(rbind, .) }) %>% do.call(rbind, .)
内容的提问来源于stack exchange,提问作者janosch
相关产品推荐
相关产品推荐

