如何用apply函数遍历data.table的step组求xy列的交集?
嘿,我来帮你搞定这个批量求交集的需求!针对你的data.table分组求交集问题,其实用data.table原生的分组操作或者lapply都能轻松实现批量处理,不用一个个手动处理单个step。
先看模拟数据(贴合你的需求)
假设你的数据结构大概是这样的(用data.table模拟):
library(data.table) # 构造示例数据,对应你预期的输出结果 dt <- data.table( step = rep(c(1, 2), each = 8), revision = rep(c("rev_a", "rev_b"), each = 4, times = 2), xy = c("1_15", "3_15", "5_15", "7_15", # step1的rev_a "1_15", "3_15", "5_15", "7_15", # step1的rev_b(和rev_a完全一致,交集就是全部) "12_15", "14_15", "16_15", "18_15", # step2的rev_a "12_15", "14_15", "16_15", "18_15") # step2的rev_b(交集就是全部) )
方法1:用data.table原生分组(推荐,高效)
直接利用data.table的by参数分组,在每个step组内完成交集计算:
# 计算每个step组内不同revision的xy交集,结果存为列表列 intersect_result <- dt[, .(common_xy = list(Reduce(intersect, split(xy, revision)))), by = step] # 提取你要的列表形式输出 intersect_result$common_xy
运行后就能得到你预期的结果:
[[1]] [1] "1_15" "3_15" "5_15" "7_15" [[2]] [1] "12_15" "14_15" "16_15" "18_15"
代码解释:
by = step:告诉data.table按step分组处理split(xy, revision):把当前step组里的xy列按revision拆分成子列表,每个子元素对应一个revision的xy值Reduce(intersect, ...):对拆分后的列表依次执行交集操作,最终得到所有revision共有的xy值list(...):把交集结果包装成列表,这样每个step对应一个向量结果
方法2:用lapply遍历分组(符合你提到的apply类函数需求)
如果你更习惯用apply系列函数,可以先把数据按step拆分,再用lapply遍历每个组计算交集:
# 按step拆分数据为列表 step_groups <- split(dt, by = "step") # 遍历每个step组,计算不同revision的xy交集 result_list <- lapply(step_groups, function(group) { # 按revision拆分当前组的xy,再求交集 Reduce(intersect, split(group$xy, group$revision)) }) # 查看结果 result_list
这个方法得到的结果和上面完全一致,适合习惯用apply思维的场景。
小提示
如果你的revision数量不止2个,Reduce(intersect, ...)依然能正常工作——它会依次对所有revision的xy集合求交集,最终得到所有revision共有的值,非常灵活。
内容的提问来源于stack exchange,提问作者alaj
相关产品推荐
相关产品推荐

