R语言合并两类数据筛选结果并取唯一行的简便实现方法
R取两个筛选结果唯一行的实现优化
初始数据与函数构建
初始构建的数据集与工具对象如下:
Table_1
构建代码:col1 <- c("1","2", "3", "4", "5") col1 <- sample(col1, 1000, replace=TRUE, prob=c(0.2, 0.2, 0.2, 0.2, 0.2)) col2 <- c("6","7", "8") col2 <- sample(col2, 1000, replace=TRUE, prob=c(0.2, 0.4, 0.4)) col3 <- c("9","10", "11", "12") col3 <- sample(col3, 1000, replace=TRUE, prob=c(0.1, 0.1, 0.4, 0.4)) col4 <- rexp( 1000, 0.5) col5 <- rexp( 1000, 0.5) id <- 1:1000 table_1 = data.frame(id, col1, col2, col3, col4, col5)sample_list
构建代码:f <- function(set) { n <- length(set) masks <- 2^(1:n-1) lapply( 1:2^n-1, function(u) set[ bitwAnd(u, masks) != 0 ] ) } sample_list = f(min(col1):max(col3))
基于sample_list筛选表行的自定义函数:
my_select <- function(index){ where<- which(apply(table_1[2:4], 1, \(x) all(x %in% sample_list[[index]])) |> t()) where }
现有实现逻辑
当前的筛选与去重流程:
- 随机选取
sample_list中的一个规则筛选行得到selection_1selection_1 = table_1[my_select(as.integer(runif(1, min = 1, max = 512))),] - 基于随机生成的数值范围筛选行得到
selection_2a = rexp( 1000, 0.5) b = rexp( 1000, 0.5) c = rexp( 1000, 0.5) d = rexp( 1000, 0.5) selection_2 = subset(table_1, col4 > a & col4 < b & col5 > c & col5 < d ) - 合并两个结果后去重得到最终结果
final_selection = rbind(selection_1, selection_2) final_selection = final_selection[!duplicated(final_selection), ]
更简便的实现方式
不需要先合并两个数据框再逐行判断重复,直接对两个筛选条件命中的行索引做去重,再一次性从原表取子集即可,逻辑更直接,内存开销和运行速度都更优,结果和原有写法完全一致:
# 分别获取两个筛选条件命中的行号 idx1 <- my_select(as.integer(runif(1, min = 1, max = 512))) idx2 <- which(with(table_1, col4 > a & col4 < b & col5 > c & col5 < d)) # 行号去重后直接取子集 final_selection <- table_1[unique(c(idx1, idx2)), ]
额外注意点
你当前生成a/b/c/d的写法是生成和原表等长的向量,比较时会逐行对齐,也就是每一行对应一套独立的随机阈值,如果你的需求是用4个固定阈值筛选全表,应该把生成逻辑改成各生成1个随机数:a <- rexp(1, 0.5),其余变量同理,可以根据实际需求调整。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

