如何基于DataFrame的起止范围为整数生成布尔标记?
R语言:判断整数是否属于任意Start-End区间并生成标记
假设我们有如下区间数据:
Start <- c(1,6) End <- c(3,9)
需要给整数序列Integers <- c(1,2,3,4,5,6,7,8,9,10)生成对应的标记列Flag,规则是:整数落在任意一组Start-End闭区间内时标记为1,否则为0,最终预期结果为:
Flag <- c(1,1,1,0,0,1,1,1,1,0)
以下是几种实用的实现方法:
方法1:基础R原生实现
利用outer()生成整数与区间的匹配矩阵,再通过行统计判断是否存在匹配:
# 定义原始数据 Start <- c(1,6) End <- c(3,9) Integers <- c(1,2,3,4,5,6,7,8,9,10) # 生成标记列 Flag <- as.integer(rowSums(outer(Integers, seq_along(Start), function(x, i) x >= Start[i] & x <= End[i])) > 0) # 输出结果 data.frame(Integers, Flag)
逻辑说明:outer()会逐个检查每个整数是否符合每个区间的条件,生成一个逻辑矩阵;rowSums()统计每行的TRUE数量,只要数量大于0就说明该整数落在至少一个区间内,最后转成整数1/0。
方法2:tidyverse工具链实现(适合DataFrame场景)
如果区间数据以DataFrame形式存储,用dplyr+purrr的组合更符合tidy数据操作习惯:
library(dplyr) library(purrr) # 构造区间和整数的DataFrame intervals <- tibble(Start = c(1,6), End = c(3,9)) int_df <- tibble(Integers = c(1,2,3,4,5,6,7,8,9,10)) # 生成标记列 int_df <- int_df %>% mutate(Flag = as.integer(map_lgl(Integers, ~any(.x >= intervals$Start & .x <= intervals$End)))) # 输出结果 int_df
逻辑说明:map_lgl()遍历每个整数,检查它是否满足任意一个区间的条件,返回逻辑值后转成整数1/0。
方法3:data.table实现(大数据场景高效处理)
如果数据量较大,data.table的非等连接能提供远优于逐行判断的性能:
library(data.table) # 构造数据 intervals <- data.table(Start = c(1,6), End = c(3,9)) int_dt <- data.table(Integers = c(1,2,3,4,5,6,7,8,9,10)) # 非等连接并生成标记 int_dt[, Flag := 0] int_dt[intervals, Flag := 1, on = .(Integers >= Start, Integers <= End)] # 输出结果 int_dt
逻辑说明:通过非等连接on = .(Integers >= Start, Integers <= End)直接定位所有落在区间内的整数,将它们的Flag设为1,其余保持初始值0,适合处理百万级以上的数据集。
内容的提问来源于stack exchange,提问作者JimmyBuffet_Express
相关产品推荐
相关产品推荐

