使用dplyr实现前向累计窗口:判断+5/-5谁先出现(无额外包)
解决方案
首先,先构造你的数据框:
df <- data.frame( ID = 1:13, Change = c(-2, -4, 3, -1, 5, 6, 2, -5, 3, -5, 2, 6, 1) )
你的原代码问题在于:myfunc接收的是整个lead(Change)的向量,而非每行对应的「从下一行到末尾」的Change切片,导致函数只计算了一次全局累计,无法生成每行对应的结果。
步骤1:编写判断函数
这个函数接收某一行后续的Change值,计算累计后判断首次达标情况:
calc_out <- function(changes) { # 没有后续数据(最后一行)直接返回NA if (length(changes) == 0) { return(NA) } cum_vals <- cumsum(changes) first_up <- which(cum_vals >= 5)[1] # 首次累计≥5的位置 first_down <- which(cum_vals <= -5)[1] # 首次累计≤-5的位置 # 两种情况都未出现 if (is.na(first_up) && is.na(first_down)) { return(NA) } # 只有下跌达标 if (is.na(first_up)) { return(0) } # 只有上涨达标 if (is.na(first_down)) { return(1) } # 比较哪个先出现 return(ifelse(first_up < first_down, 1, 0)) }
步骤2:用dplyr逐行处理
通过rowwise()实现逐行计算,对每行取row_number()+1到末尾的Change切片传入函数:
library(dplyr) result_df <- df %>% rowwise() %>% mutate( Out = calc_out(Change[(row_number() + 1):n()]) ) %>% ungroup()
验证结果
运行后得到的result_df与你预期的结果一致:
ID Change Out 1 1 -2 1 2 2 -4 1 3 3 3 1 4 4 -1 1 5 5 5 1 6 6 6 0 7 7 2 0 8 8 -5 1 9 9 3 0 10 10 -5 1 11 11 2 1 12 12 6 NA 13 13 1 NA
内容的提问来源于stack exchange,提问作者DataMonkey
相关产品推荐
相关产品推荐

