You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用split函数在R中划分30分钟时间间隔的数据表

问题描述

我有一份时长21天、每10秒采集一次的数据表,结构如下:

TimeStamp            ActivePower  CurrentL1  GeneratorRPM  RotorRPM  WindSpeed
2017-03-05 00:00:10  2183.650     1201.0     1673.90       NA        10.60
2017-03-05 00:00:20  2216.200     1224.0     1679.70       NA        11.00
2017-03-05 00:00:30  2176.500     1203.5     NA            16.05     11.90
---
2017-03-25 23:59:40  2024.20      1150.0     1687.00       16.15     10.35
2017-03-25 23:59:50  1959.05      1106.0     1661.15       15.90     8.65
2017-03-26 00:00:00  1820.55      1038.0     1665.70       15.80     9.20

需要将其划分为30分钟的时间块,同事告知因数据可能存在缺失时间戳,不应使用split函数,需手动生成30分钟间隔。目前已完成以下代码:

library(data.table)
library(dplyr)
library(tidyr)

datei <- file.choose() 
data_csv <- fread(datei)

datatable1 <- as.data.table(data_csv)
datatable1 <- datatable1[turbine=="UTHA02",]

datatable1[, TimeStamp:=as.POSIXct(get("_time"), tz="UTC")]
setkey(datatable1, TimeStamp)
startdate <- datatable1[1,TimeStamp]
enddate <- datatable1[nrow(datatable1), TimeStamp]
durationForInterval <- 30*60 #in seconds
curr <- startdate
datatable1[TimeStamp >= curr & TimeStamp < curr + durationForInterval]

上述代码仅能获取第一个30分钟间隔的数据,如下所示:

time                    ActivePower CurrentL1  GeneratorRPM   RotorRPM  WindSpeed           
  1:  2017-03-05 00:00:10     2183.65     1201.0     1673.90        NA        10.60 
  2:  2017-03-05 00:00:20     2216.20     1224.0     1679.70        NA        11.00 
  3:  2017-03-05 00:00:30     2176.50     1203.5          NA        16.05     11.90 
  4:  2017-03-05 00:00:40     2267.95     1256.5     1685.85        NA        10.60 
  5:  2017-03-05 00:00:50     2533.15     1408.0     1693.30        16.20     12.40 
 ---                                                                                                      
176:  2017-03-05 00:29:20     2750.35     1531.0     1694.40        16.20     11.45 
177:  2017-03-05 00:29:30     2930.40     1630.5     1668.25        NA        12.65 
178:  2017-03-05 00:29:40     2459.55     1367.0     1680.25        15.90     12.15 
179:  2017-03-05 00:29:50     2713.80     1508.5     1681.15        16.20     12.25 
180:  2017-03-05 00:30:00     2395.20     1333.0     1667.75        16.00     11.75 

不知道如何处理剩余的时间间隔,恳请提供解决方案或指出疏漏之处!

解决方案

核心思路

手动生成覆盖数据全时间范围的30分钟间隔序列,通过data.table的非等连接将原数据映射到对应时间块,或直接给原数据添加时间块标签,避免循环遍历的低效问题,同时适配缺失时间戳的场景。

完整代码(基于data.table)

library(data.table)

# 读取并过滤数据
datei <- file.choose() 
datatable1 <- fread(datei)
datatable1 <- datatable1[turbine == "UTHA02",]

# 转换时间戳(直接引用列名,简化逻辑)
datatable1[, TimeStamp := as.POSIXct(`_time`, tz = "UTC")]
setkey(datatable1, TimeStamp)

# 定义30分钟间隔参数
interval_sec <- 30 * 60
startdate <- datatable1[1, TimeStamp]
enddate <- datatable1[.N, TimeStamp]

# 生成所有30分钟间隔的起止时间序列
# 可选:将起始时间向上取整到最近的30分钟整点,保证块对齐
start_rounded <- as.POSIXct(floor(as.numeric(startdate)/interval_sec)*interval_sec, 
                            origin = "1970-01-01", tz = "UTC")
time_intervals <- seq(start_rounded, enddate + interval_sec, by = interval_sec)

# 构建时间块映射表
interval_table <- data.table(
  block_start = time_intervals[-length(time_intervals)],
  block_end = time_intervals[-1],
  block_id = seq_along(time_intervals[-length(time_intervals)])
)

# 非等连接匹配数据到对应时间块
datatable_with_blocks <- datatable1[interval_table, 
                                   on = .(TimeStamp >= block_start, TimeStamp < block_end),
                                   nomatch = 0]

# 示例:按时间块计算均值
block_summary <- datatable_with_blocks[, .(
  avg_ActivePower = mean(ActivePower, na.rm = TRUE),
  avg_CurrentL1 = mean(CurrentL1, na.rm = TRUE),
  avg_WindSpeed = mean(WindSpeed, na.rm = TRUE)
), by = block_id]

# 若需按块拆分数据为列表
block_list <- split(datatable_with_blocks, by = "block_id")

关键说明

  1. 时间序列完整性:生成time_intervals时添加enddate + interval_sec,确保所有末尾数据点都能被覆盖,即使enddate不在30分钟整点上。
  2. 非等连接优势:比循环遍历效率高数十倍,适合处理大样本量(21天10秒间隔约18万行数据),同时自动跳过无数据的时间块。
  3. 简化替代方案:若不需要单独的间隔表,可直接给原数据添加时间块标签:
datatable1[, block_id := floor(as.numeric(TimeStamp - start_rounded)/interval_sec) + 1]
# 后续直接按block_id分组处理即可

内容的提问来源于stack exchange,提问作者NoName

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 05:39:17