如何确定rollapply滚动窗口线性回归中所使用的数据点?
问题描述
我正在使用rollapply函数,基于3天的滚动窗口计算不同日期荧光数据的斜率估计值(以寻找最大斜率)。以下是我使用的代码:
ls <- cumulative_df %>% group_by(id) %>% filter(n() >= 3) %>% filter(id!="Blank") %>% group_split() z_out <- data.frame(intercept = NA, mu = NA, rsqr = NA, id = NA) k <- moving_window_point_number for (i in seq_along(ls)) { z <- ls[[i]] %>% select(day, lRFU) tmp_df1 <- rollapply(z, width = k, function(x) coef(lm(lRFU ~ day, data = as.data.frame(x))), by.column = FALSE, align = "right") tmp_df2 <- rollapply(z, width = k, function(x) summary(lm(lRFU ~ day, data = as.data.frame(x)))$r.squared, by.column = FALSE, align = "right") tmps <- data.frame(intercept = tmp_df1[,1], mu = tmp_df1[,2], rsqr = tmp_df2) %>% arrange(-mu) z_out[i,1:3] <- as.numeric(c(tmps[1,1], tmps[1,2], tmps[1,3])) z_out[i,4] <- as.character(unique(ls[[i]]$id)) tmp_df1 <- NULL tmp_df2 <- NULL tmps <- NULL z <- NULL } write_xlsx(z_out, paste0(output_dir, cond_new, "gr_estimates_k", k, ".xlsx"))
我不确定该如何着手确定滚动窗口线性回归中所使用的数据点。
解决方法
要确定滚动窗口线性回归用到的数据点,你可以从这几个方向入手:
1. 自定义函数记录窗口数据范围
修改rollapply的调用逻辑,用自定义函数一次性返回回归参数、R²和窗口内的日期信息,避免重复计算:
custom_roll_fun <- function(x) { df <- as.data.frame(x) lm_fit <- lm(lRFU ~ day, data = df) # 记录窗口的起始、结束日期,以及所有参与的日期值 start_day <- min(df$day) end_day <- max(df$day) included_days <- paste(df$day, collapse = ", ") # 返回所有需要的信息 c(intercept = coef(lm_fit)[1], mu = coef(lm_fit)[2], rsqr = summary(lm_fit)$r.squared, start_day = start_day, end_day = end_day, included_days = included_days) }
替换原代码中两个rollapply的调用,用这个函数一次性生成结果:
z <- ls[[i]] %>% select(day, lRFU) tmp_df <- rollapply(z, width = k, custom_roll_fun, by.column = FALSE, align = "right") tmp_df <- as.data.frame(tmp_df)
后续筛选最大斜率时,就能直接看到对应窗口用到的具体日期。
2. 明确窗口对齐逻辑
你的代码使用align = "right",这意味着每个窗口的右端点对应当前数据行的位置:
- 若
k=3,第3行数据对应的窗口是第1-3行的day值 - 第4行数据对应的窗口是第2-4行的day值
以此类推。可以通过计算输出行数验证:nrow(tmp_df)应该等于nrow(z) - k + 1,对应每个右对齐的窗口数量。
3. 绑定原始数据索引
如果数据的day不是连续值,或者需要精准定位原始数据行,可以给子集添加行号,再在自定义函数中返回索引范围:
z <- ls[[i]] %>% select(day, lRFU) %>% mutate(row_idx = row_number()) custom_roll_fun <- function(x) { df <- as.data.frame(x) lm_fit <- lm(lRFU ~ day, data = df) start_idx <- min(df$row_idx) end_idx <- max(df$row_idx) included_idx <- paste(df$row_idx, collapse = ", ") c(intercept = coef(lm_fit)[1], mu = coef(lm_fit)[2], rsqr = summary(lm_fit)$r.squared, start_idx = start_idx, end_idx = end_idx, included_idx = included_idx) }
通过这些索引,你可以直接从原始cumulative_df中提取对应数据点进行验证。
4. 可视化验证窗口数据
对于需要直观确认的情况,可针对单个ID,将最大斜率对应的窗口数据高亮展示:
# 找到当前ID下斜率最大的窗口 max_slope_row <- tmp_df %>% arrange(-mu) %>% slice(1) # 提取窗口对应的原始数据 window_data <- z %>% filter(day >= max_slope_row$start_day, day <= max_slope_row$end_day) # 绘图展示 library(ggplot2) ggplot(z, aes(x = day, y = lRFU)) + geom_point(color = "gray") + geom_line(data = window_data, aes(x = day, y = lRFU), color = "red", linewidth = 1.2) + geom_abline(intercept = max_slope_row$intercept, slope = max_slope_row$mu, color = "blue", linetype = "dashed") + ggtitle(paste("ID:", unique(ls[[i]]$id), "最大斜率窗口数据"))
这样就能直观看到哪些数据点被用来计算这个最大斜率。
内容的提问来源于stack exchange,提问作者Shravan Ram
相关产品推荐
相关产品推荐

