在R中查找当前行前序行里最接近的小于和大于当前值的数
查找当前行之前最接近的较大ID值
我们有一个包含id列的数据框,需要对每一行,仅从当前行之前的所有行中,找到最接近当前id的大于值(已实现小于值的查找,现需补充大于值逻辑)。示例数据中的max_close_bigger_prior列是预期输出结果:
df <- structure(list( row_id = 1:10, id = c(2, 11, 3, 5, 4, 6, 7, 10, 9, 1), min_closest_smaller_prior = c(NA, 2, 2, 3, 3, 5, 6, 7, 7, NA), max_close_bigger_prior = c(NA, NA, 11, 11, 5, 11, 11, 11, 10, 2) ), class = "data.frame", row.names = c(NA, -10L))
已实现的较小值查找代码:
df2 <- df %>% mutate(nearest = transform(., close_prev = id[apply(`diag<-`(m <- as.matrix(dist(id)), Inf) / upper.tri(m), 2, which.min)])) %>% as_tibble()
实现较大值查找的两种方法
方法一:逐行筛选+距离计算(直观易理解)
通过逐行提取当前行之前的id,筛选出大于当前id的部分,再从中找距离最近的那个值:
library(dplyr) library(purrr) df <- df %>% mutate( max_close_bigger_prior = pmap_dbl(seq_len(nrow(.)), function(i) { prior_ids <- .$id[1:(i-1)] # 筛选之前行中大于当前id的元素 bigger_candidates <- prior_ids[prior_ids > .$id[i]] if (length(bigger_candidates) == 0) { return(NA_real_) } # 计算每个候选值与当前id的距离,取最小距离对应的候选值 bigger_candidates[which.min(abs(bigger_candidates - .$id[i]))] }) )
方法二:维护排序向量+二分查找(高效适合大数据)
如果数据量较大,逐行循环效率偏低,可以维护一个动态排序的已处理id向量,用二分查找快速定位最接近的较大值:
library(dplyr) library(purrr) # 初始化空的排序向量,用于存储之前行的id sorted_prior_ids <- c() df <- df %>% mutate( max_close_bigger_prior = map_dbl(id, function(current_id) { # 用findInterval找到第一个大于当前id的位置 pos <- findInterval(current_id, sorted_prior_ids) + 1 # 判断是否存在大于当前id的元素 res <- if (pos > length(sorted_prior_ids)) NA_real_ else sorted_prior_ids[pos] # 将当前id加入排序向量并重新排序 sorted_prior_ids <<- sort(c(sorted_prior_ids, current_id)) res }) )
两种方法都能得到示例中的max_close_bigger_prior列结果,方法二更适合处理行数较多的数据集。
内容的提问来源于stack exchange,提问作者jsimpsno
相关产品推荐
相关产品推荐

