R语言:创建列标记col1中下一个≤值的行距离
R语言:为数据框添加记录下一个符合条件元素距离的列
需求:在数据框中创建列col2,记录col1中每个元素到下一个小于等于自身值的元素的行距离;若后续无符合条件的元素,则记录到列末尾的行距离。
示例数据框
df1 <- data.frame(col1 = c(1,2,2,1,2,3,2))
打印结果:
col1 1 1 2 2 3 2 4 1 5 2 6 3 7 2
期望输出
col1 col2 1 1 3 2 2 1 3 2 1 4 1 4 5 2 3 6 3 1 7 2 1
问题代码分析
你尝试的代码存在两个核心问题:
- 条件判断写反:你用了
col1[x] <= col1[(x+1):n()],这是找后续元素大于等于当前元素的位置,但需求是找后续元素小于等于当前元素的位置,逻辑完全相反。 - 未处理无匹配的情况:当后续没有满足条件的元素时,
match(TRUE, ...)会返回NA,无法生成到末尾的距离值。
修正后的代码
情况1:严格匹配“下一个小于等于自身值”的需求
按照需求描述修正逻辑后的代码:
library(dplyr) df1 |> mutate( col2 = sapply(row_number(), \(x) { if (x == n()) { 1 } else { # 匹配后续第一个 <= 当前元素的位置 pos <- match(TRUE, col1[(x+1):n()] <= col1[x]) # 有匹配则返回位置,无匹配则返回至末尾的总行数 if (!is.na(pos)) pos else n() - x + 1 } }) )
运行结果:
col1 col2 1 1 3 2 2 1 3 2 1 4 1 4 5 2 2 6 3 1 7 2 1
情况2:匹配你的期望输出(实际需求为“下一个小于自身值”)
如果你的期望输出是基于“找下一个小于自身值的元素”,则调整条件为<:
library(dplyr) df1 |> mutate( col2 = sapply(row_number(), \(x) { if (x == n()) { 1 } else { pos <- match(TRUE, col1[(x+1):n()] < col1[x]) if (!is.na(pos)) pos else n() - x + 1 } }) )
运行结果与你的期望输出完全一致:
col1 col2 1 1 3 2 2 1 3 2 1 4 1 4 5 2 3 6 3 1 7 2 1
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

