dplyr mutate条件判断引用自身历史值报错:如何实现趋势延续?
解决dplyr::mutate中引用正在创建列滞后值的问题
你遇到的问题核心是:dplyr的mutate是按列批量计算的,无法在同一mutate调用中直接引用正在创建的列的滞后值——因为新列还没完全生成,自然找不到对应的对象。
针对你要实现的「上升标记1、下降标记-1,无变化时沿用上次判定结果」的需求,推荐用迭代累积的方式实现,比如使用purrr::accumulate或dplyr::accumulate(dplyr 1.0.0+已支持)。
方法一:借助中间列+accumulate函数
library(dplyr) library(purrr) df <- data.frame(Val = c(1:5,5,5,5:1,1,1,1,6,1,1,5:1)) df_result <- df %>% mutate( # 先标记每一行的直接变化方向:上升=1,下降=-1,无变化=NA temp_dir = case_when( # 第一行默认按上升处理(匹配你的期望结果) row_number() == 1 ~ 1, Val > lag(Val) ~ 1, Val < lag(Val) ~ -1, TRUE ~ NA_real_ ), # 迭代累积:无变化时沿用前一个方向值 ValDirection = accumulate(temp_dir, ~ ifelse(is.na(.y), .x, .y)) ) %>% select(-temp_dir) # 移除中间列 # 验证结果 print(df_result)
方法二:用accumulate2直接处理(无需中间列)
accumulate2可以同时处理两个向量,直接对比当前值与前一个值,同时保留前一次的判定结果:
library(dplyr) library(purrr) df <- data.frame(Val = c(1:5,5,5,5:1,1,1,1,6,1,1,5:1)) df_result <- df %>% mutate( ValDirection = accumulate2( .x = Val[-1], # 从第二行开始的Val值 .y = Val[-nrow(.)], # 从第一行到倒数第二行的Val值 .init = 1, # 第一行的初始方向(匹配你的期望结果) ~ case_when( ..2 > ..3 ~ 1, # 当前值>前一个值:标记1 ..2 < ..3 ~ -1, # 当前值<前一个值:标记-1 TRUE ~ ..1 # 无变化:沿用前一次的方向 ) ) %>% unlist() ) # 验证结果 print(df_result)
两种方法都能生成你期望的ValDirection列,解决了原代码中无法引用正在创建列的问题。
内容的提问来源于stack exchange,提问作者Camilo
相关产品推荐
相关产品推荐

