在tidyverse中识别二元变量的成对组合
批量识别二元变量对同时为1的组合解决方案
需求说明
现有包含多个二元0/1变量的DataFrame(示例含7个变量,实际为23个),需要批量识别所有变量对同时为1的情况,忽略其他变量的取值,标记出对应的变量对名称(如V1_V2)。
解决方案
方法一:Tidyverse 直观实现(适合新手)
利用combn生成所有不重复的变量对,再结合dplyr批量创建标记列或合并所有满足的组合到一列。
步骤1:生成变量对组合
library(tidyverse) # 生成所有不重复的变量对(如c("V1","V2"), c("V1","V3")...) var_pairs <- combn(names(df), 2, simplify = FALSE)
步骤2:批量创建变量对标记列
为每个变量对单独创建一列,标记该行是否满足该对同时为1:
df_pair_flags <- df %>% mutate( across( all_of(var_pairs), ~ ifelse(!!sym(.x[[1]]) == 1 & !!sym(.x[[2]]) == 1, paste(.x, collapse = "_"), NA), .names = "{paste(.x, collapse = '_')}" ) )
步骤3:合并所有满足的组合到单一列
如果希望每行所有满足的变量对合并为一个字符串(逗号分隔):
df_combined <- df %>% rowwise() %>% mutate( combo_ids = list( var_pairs %>% map_chr(~ ifelse(all(c_across(all_of(.x)) == 1), paste(.x, collapse = "_"), NA)) %>% na.omit() ) ) %>% ungroup() %>% # 把列表转为逗号分隔的字符串 mutate(combo_ids = ifelse(lengths(combo_ids) > 0, paste(combo_ids, collapse = ", "), NA))
方法二:矩阵运算高效实现(适合变量较多场景)
当变量数量较多(如23个,共253个变量对)时,矩阵运算的速度远快于循环/行处理:
# 将DataFrame转为矩阵 mat <- as.matrix(df) # 逐行计算所有同时为1的变量对 combo_list <- apply(mat, 1, function(row) { # 计算行向量的外积,找到上三角中值为1的位置(避免重复对) pair_indices <- which(row %*% t(row) == 1 & upper.tri(row %*% t(row)), arr.ind = TRUE) if (nrow(pair_indices) > 0) { paste(colnames(mat)[pair_indices[,1]], colnames(mat)[pair_indices[,2]], sep = "_") } else { NA_character_ } }) # 将结果合并回原DataFrame df$combo_ids <- combo_list
示例输出说明
以生成的示例数据为例,某行若V1=1且V2=1、V1=1且V3=1,则combo_ids列会显示V1_V2, V1_V3。
内容的提问来源于stack exchange,提问作者JFerret
相关产品推荐
相关产品推荐

