使用lapply处理日期时间对象时返回数据框并为特定案例时间戳加一分钟
解决方法
我来帮你搞定这个需求,先梳理下你代码里的小问题,再一步步实现目标:
1. 确认示例数据
你的基础数据是没问题的,先再明确一遍:
timestamp <- seq( from = as.POSIXct("12/05/2017 9:00", format = "%m/%d/%Y %H:%M"), by = 60, to = as.POSIXct("12/05/2017 9:02", format = "%m/%d/%Y %H:%M")) ID <- seq(from = 101, by = 1, to = 115) df <- data.frame(ID, timestamp) vars <- list(101, 102, 103)
2. 修正并定义处理函数
你原来的函数里有两个变量名错误:df$encounter应该是df$timestamp(你的数据框里没有encounter列),dat$ID应该是df$ID(数据框名是df)。另外,为了让lapply处理后能直接组合成data frame,函数需要返回包含ID和修改后timestamp的data frame行:
foo <- function(x) { # 筛选当前ID对应的行 target_row <- df[df$ID == x, ] # 给timestamp增加60秒(即1分钟) target_row$timestamp <- target_row$timestamp + 60 # 返回处理后的行(保持data frame格式) return(target_row) }
3. 用lapply处理并合并成data frame
lapply会返回一个包含多个小data frame的列表,我们用do.call(rbind, ...)把这些小data frame合并成一个完整的结果:
# 执行批量处理 processed_list <- lapply(vars, foo) # 合并为最终的data frame result_df <- do.call(rbind, processed_list) # 查看结果 print(result_df)
运行后会得到符合预期的输出:
ID timestamp 1 101 2017-12-05 09:01:00 2 102 2017-12-05 09:02:00 3 103 2017-12-05 09:03:00
另一种更简洁的tidyverse写法
如果你习惯用tidyverse工具链,代码会更直观:
library(dplyr) result_df <- lapply(vars, function(x) { df %>% filter(ID == x) %>% mutate(timestamp = timestamp + 60) }) %>% bind_rows()
这样同样能得到目标data frame,可读性也更强。
内容的提问来源于stack exchange,提问作者votmoyd




