R语言mutate实现:获取当前行上方首个更小值
R语言生成close_prev列的解决方案
需求说明
为仅含count列的数据框生成新列close_prev,规则如下:
- 第一行的
close_prev为NA - 后续行的
close_prev是当前行上方所有行中,小于当前count值的最大数值(若没有符合条件的数值,同样返回NA)
示例输入
| count |
|---|
| 24 |
| 33 |
| 33 |
| 34 |
| 35 |
| 33 |
| 33 |
| 34 |
| 35 |
期望输出
| count | close_prev |
|---|---|
| 24 | NA |
| 33 | 24 |
| 33 | 24 |
| 34 | 33 |
| 35 | 34 |
| 33 | 24 |
| 33 | 24 |
| 34 | 33 |
| 35 | 34 |
问题分析
你提供的代码无法运行,原因有两点:
closest并非R的内置函数,也不属于tidyverse等常用包,R会提示“找不到该函数”- 即便
closest存在,它的逻辑是寻找最接近的数值,而非筛选出小于当前值的最大数值,不符合需求
解决方案
方法1:使用tidyverse工具链
先加载tidyverse包,通过mutate结合purrr::map_dbl实现需求:
library(tidyverse) # 构造示例数据 df <- tibble( count = c(24, 33, 33, 34, 35, 33, 33, 34, 35) ) # 生成close_prev列 df <- df %>% mutate( close_prev = map_dbl(row_number(), function(i) { if (i == 1) { NA_real_ } else { # 提取当前行上方的所有数值 prev_values <- count[1:(i-1)] # 筛选出小于当前count的数值 smaller_values <- prev_values[prev_values < count[i]] # 无符合条件的值返回NA,否则返回最大值 if (length(smaller_values) == 0) NA_real_ else max(smaller_values) } }) )
方法2:高效版(data.table)
如果数据量较大,data.table的实现效率更高:
library(data.table) setDT(df) df[, close_prev := sapply(1:.N, function(i) { if (i == 1) NA_real_ else { smaller_values <- count[1:(i-1)][count[1:(i-1)] < count[i]] if (length(smaller_values) == 0) NA_real_ else max(smaller_values) } })]
特殊调整
如果你的真实需求是“当前行上方第一个出现的小于当前值的数值”(而非最大的),只需将代码中的max(smaller_values)替换为dplyr::first(smaller_values)即可。
内容的提问来源于stack exchange,提问作者Ana Castanheira
相关产品推荐
相关产品推荐

