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

R语言计算矩阵标签交集 构建元素匹配指示矩阵

问题说明

需要构造N*N的指示值矩阵:当两个样本的标签存在共有元素时,矩阵对应位置取值为1,最终得到记录两两样本标签是否匹配的数据集。原有代码运行失败,无法输出预期结果,原代码如下:

N <- 100
combinations <- c(outer(letters[1:5], letters[1:5], paste0))

set.seed(1)
data <- data.frame(
  c_1 = sample(x=combinations,size = N,replace = T),
  c_2 = sample(x=c(rep(NA,N/4),combinations),size = N,replace = T),
  c_3 = sample(x=c(rep(NA,N/2),combinations),size = N,replace = T),
  c_4 = sample(x=c(rep(NA,N/1),combinations),size = N,replace = T)) %>% 
  rowwise() %>% 
  mutate(c_all=list(c(c_1,c_2,c_3,c_4)[!is.na(c(c_1,c_2,c_3,c_4))]))

match_function <- function(x,y){
  result <- ifelse(length(intersect(x,y)),1,0)
  return(result)
}

outer(data$c_all, unlist(data$c_all)), match_function)
原代码问题点
  • 最后一行outer调用存在语法错误,多写了一个右括号,无法正常执行。
  • outer函数默认要求传入的运算函数支持向量化处理,原自定义函数只能接收单个列表元素做交集运算,直接传入会导致运算逻辑不符合预期。
  • outer第二个参数传入unlist(data$c_all)是错误的,该操作会把所有标签集合拆成独立的字符串向量,长度和第一个参数不匹配,无法生成N*N的矩阵。
  • 生成c_all列后没有取消rowwise分组,容易导致后续运算出现意外结果。
修正后实现方案

保留原有代码的逻辑框架,仅修正错误点即可得到预期结果:

library(dplyr)

N <- 100
combinations <- c(outer(letters[1:5], letters[1:5], paste0))

set.seed(1)
data <- data.frame(
  c_1 = sample(x=combinations,size = N,replace = T),
  c_2 = sample(x=c(rep(NA,N/4),combinations),size = N,replace = T),
  c_3 = sample(x=c(rep(NA,N/2),combinations),size = N,replace = T),
  c_4 = sample(x=c(rep(NA,N/1),combinations),size = N,replace = T)) %>% 
  rowwise() %>% 
  mutate(c_all=list(c(c_1,c_2,c_3,c_4)[!is.na(c(c_1,c_2,c_3,c_4))])) %>%
  ungroup() # 取消行分组,避免后续运算异常

match_function <- function(x,y){
  as.integer(length(intersect(x,y)) > 0)
}

# 用Vectorize包装自定义函数,使其支持向量化运算,适配outer要求
match_matrix <- outer(
  X = data$c_all,
  Y = data$c_all,
  FUN = Vectorize(match_function)
)
  • 最终生成的match_matrix为100*100的指示矩阵,第i行第j列值为1代表第i个样本和第j个样本存在共有标签,值为0代表无共有标签。
  • 若某行所有列均为NA,对应c_all为空列表,它和所有样本的匹配值均为0,符合交集为空的逻辑。

如果需要将矩阵转换为更易分析的长表格式数据集,可以追加如下代码:

library(tidyr)
match_dataset <- match_matrix %>%
  as.data.frame() %>%
  mutate(sample_a = 1:n()) %>%
  pivot_longer(cols = -sample_a, names_to = "sample_b", values_to = "has_common_tag") %>%
  mutate(sample_b = as.integer(gsub("V", "", sample_b)))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:45:36