为数据集添加含新增唯一分类变量的排列组合
问题描述
我有一个包含多分类变量和数值变量的数据集,分类变量存在若干唯一组合,但并非所有排列组合都存在(无对应值的组合无需保留)。需要为所有分类变量添加名为[no selection]的水平,生成包含以下两类组合的新数据集:
- 原数据中的所有有效组合
- 所有仅将某一个分类变量替换为
[no selection]的唯一组合(其余分类变量保持原有效组合的取值)
新组合中的数值变量值设为0(空值后续可自行替换)。
提供的R数据集结构如下:
structure(list(`Primary Outcome` = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), levels = c("Laboratory-Confirmed Influenza", "Influenza-Like Illness", "Complications from Influenza"), class = "factor"), `Virus (Sub)Type` = structure(c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L, 6L), levels = c("Influenza A and B", "Influenza A", "Influenza B", "A(H1N1)pdm09", "A(H3N2)", "B/Yamagata", "B/Victoria", "B/Wisconsin"), class = "factor"), Season = structure(c(1L, 1L, 1L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 3L), levels = c("All Seasons", "2019/20", "2011/12", "2014/15", "2018/19", "2017/18", "2013/14", "2012/13", "2015/16", "2016/17", "2012", "2013", "2018", "2014", "2019", "2016", "2017", "2010-2019", "2015"), class = "factor"), `Meta-Analysis Model` = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L), levels = c("Fixed Effect Model", "Random Effects Model" ), class = "factor"), k = c(398, 398, 126, 126, 212, 7, 2, 2, 10, 10, 2), Q = c(1236.50029339945, 1236.50029339945, 352.741540498925, 352.741540498925, 380.231921977758, 11.3144127452121, 2.68421098744275, 2.68421098744275, 5.75656937709005, 5.75656937709005, 1.74656825505281), p = c(5.89614495232528e-87, 5.89614495232528e-87, 1.38614414562279e-23, 1.38614414562279e-23, 8.10697738675785e-12, 0.0791317973899664, 0.101347413621071, 0.101347413621071, 0.764012962020228, 0.764012962020228, 0.186308732770133), `Vaccine Matching Status` = c("No Stratification", "No Stratification", "No Stratification", "No Stratification", "No Stratification", "No Stratification", "No Stratification", "No Stratification", "No Stratification", "No Stratification", "No Stratification" ), `Risk Group` = c("General Population (Aged 5-64)", "General Population (Aged 5-64)", "General Population (Aged 5-64)", "General Population (Aged 5-64)", "General Population (Aged 5-64)", "General Population (Aged 5-64)", "General Population (Aged 5-64)", "General Population (Aged 5-64)", "General Population (Aged 5-64)", "General Population (Aged 5-64)", "General Population (Aged 5-64)")), row.names = c(NA, -11L ), class = c("tbl_df", "tbl", "data.frame"))
注意:expand.grid无法满足需求,因为不需要现有变量的全排列,仅需保留原有效组合及含[no selection]的组合。
解决方案
核心思路是针对每个分类变量生成单独替换为[no selection]的组合,再与原数据合并去重,具体步骤如下:
步骤1:定义变量类型
先明确分类变量和数值变量的范围:
# 加载数据集 df <- structure(...) # 替换为你提供的数据集结构 # 分类变量列名 cat_vars <- c("Primary Outcome", "Virus (Sub)Type", "Season", "Meta-Analysis Model", "Vaccine Matching Status", "Risk Group") # 数值变量列名 num_vars <- c("k", "Q", "p")
步骤2:生成含新水平的组合
循环每个分类变量,生成仅该变量为[no selection]的新组合,数值变量设为0:
# 初始化结果列表,先加入原数据 result_list <- list(df) # 遍历每个分类变量生成新组合 for (var in cat_vars) { temp_df <- df # 替换当前分类变量为新水平 temp_df[[var]] <- "[no selection]" # 数值变量设为0 temp_df[num_vars] <- 0 # 加入结果列表 result_list <- c(result_list, list(temp_df)) }
步骤3:合并去重
将所有组合合并,去除重复行:
# 合并所有数据框 final_df <- dplyr::bind_rows(result_list) # 去重,保留唯一组合 final_df <- dplyr::distinct(final_df) # 可选:将分类变量重新转为因子(包含原水平+新水平) for (var in cat_vars) { final_df[[var]] <- factor(final_df[[var]], levels = c(levels(df[[var]]), "[no selection]")) }
代码说明
- 保留原数据的所有有效组合
- 对每个分类变量生成一组新组合:仅该变量取值为
[no selection],其余分类变量保持原组合取值,数值变量设为0 - 合并后去重,避免不同变量替换后出现重复组合
- 可选步骤将分类变量转为包含新水平的因子,保证因子类型的一致性
内容的提问来源于stack exchange,提问作者Hunter
相关产品推荐
相关产品推荐

