如何在R语言中判断含重复值的向量是否为另一向量的子集?
检查向量元素可无重复匹配存在于另一向量的R实现
问题背景
我们需要判断:一个向量的所有元素是否都能在另一个向量中找到,且每个元素的匹配次数不能超过目标向量中的出现次数。举个实际例子:
U <- c("a","a","a","b","u") V <- c("a","a","u") W <- c("a","b","b")
- V可以匹配U:U有3个"a",取2个就能覆盖V的需求,加上U里的1个"u",完全匹配
- W无法匹配U:W需要2个"b",但U里只有1个,满足不了
注意:R内置的%in%只会检查元素是否存在,不考虑重复次数,没法解决这个问题。
解决方案
自定义运算符方案(你的临时实现优化版)
你自己写的临时方案已经很实用,这里做一点小优化,处理目标向量中不存在待检查元素的情况(避免NA导致判断错误):
`%w%` <- \(x, y){ tx <- table(x) ty <- table(y)[names(tx)] # 把NA替换为0,确保不存在的元素频次为0 ty[is.na(ty)] <- 0 all(ty >= tx) }
测试验证:
> V %w% U [1] TRUE > W %w% U [1] FALSE
通用函数方案
如果需要更直观的逻辑,也可以封装成普通函数,用数据框合并来处理频次比对:
is_multisubset <- function(x, target) { # 统计两个向量的元素频次 tab_x <- as.data.frame(table(x), stringsAsFactors = FALSE) tab_target <- as.data.frame(table(target), stringsAsFactors = FALSE) # 统一列名方便合并 colnames(tab_x) <- c("element", "count_x") colnames(tab_target) <- c("element", "count_target") # 合并后补全缺失元素的频次为0 merged_tabs <- merge(tab_x, tab_target, by = "element", all.x = TRUE) merged_tabs$count_target[is.na(merged_tabs$count_target)] <- 0 # 检查所有元素的频次是否满足要求 all(merged_tabs$count_target >= merged_tabs$count_x) }
测试结果:
> is_multisubset(V, U) [1] TRUE > is_multisubset(W, U) [1] FALSE
核心思路
两种方案的核心都是基于元素频次的比对:先统计两个向量中每个元素的出现次数,再确保待检查向量中每个元素的次数都不超过目标向量中的对应次数。
内容的提问来源于stack exchange,提问作者user24504409
相关产品推荐
相关产品推荐

