我有一个具有以下结构的数据集: 月|一天|小时|分钟| Value1 | Value2 |值3
数据集的长度为525,600行。我需要的是每个值(value1,value2,value3)的平均值超过15分钟。输出应具有以下结构:
Month | Begin | End | MeanValues1 | MeanValues2 | MeanValues3
01 | 0:00 | 0:15 | 1.23 | 2.34 | 3.23
01 | 0:15 | 0:30 | 1.76 | 3.02 | 3.24
因此,输出数据集的长度应为35,040行。
任何人都可以帮助我并给我一个R的轻量级解决方案吗? 我不知道如何以非常有效的方式实现它。此外,我不清楚如何在输出数据集中构建Begin和End列。
我提前感谢您的任何意见。
最佳
答案 0 :(得分:0)
# Create some sample data
set.seed <- 8675309
Month <- rep(1, 30)
Day <- rep(1, 30)
Hour <- rep(1, 30)
Minute <- seq(1, 30, 1)
value1 <- runif(30, 0, 100)
value2 <- runif(30, 10, 20)
df <- data.frame(Month, Day, Hour, Minute, value1, value2)
# Break into bins
df$bin <- cut(df$Minute, breaks = c(0,15,30,45,60))
# Aggregate
df$Minute<- NULL
newdf <- aggregate(.~Month+Day+Hour+bin, df, mean)
答案 1 :(得分:0)
使用dplyr
和lubridate
,你可以将时间四舍五入到最接近的四分之一,按那些分组和计算方法。
我使用这些库
library(tibble)
library(lubridate)
library(dplyr)
第一个只是制作这个测试数据:
test_tbl <- tribble(
~Month, ~Day, ~Hour, ~Minute, ~Value1, ~Value2, ~Value3,
2, 15, 14, 11, 1, 1, 1,
2, 15, 14, 12, 1, 1, 1,
2, 15, 14, 16, 2, 2, 2,
2, 15, 14, 19, 2, 2, 2,
)
管道首先生成一个字符串,我可以使用lubridate来解析日期时间(我不知道是否有更明智的方法可以做到这一点;我还没有那么多使用过lubridate)。然后我计算所有时间的开始和结束季度,按那些计算,以及计算方法。
test_tbl %>%
mutate(time_str = paste0(2018, ":", Month, ":", Day, " ", Hour, ":", Minute),
time = ymd_hm(time_str),
quarter_start = floor_date(time, "15 min"),
quarter_end = ceiling_date(time, "15 min")) %>%
select(-(Day:Minute), -time_str, -time) %>% # don't need these any more
group_by(Month, quarter_start, quarter_end) %>%
summarise_all(mean)
我的输出如下:
# A tibble: 2 x 6
# Groups: Month, quarter_start [?]
Month quarter_start quarter_end Value1 Value2
<dbl> <dttm> <dttm> <dbl> <dbl>
1 2. 2018-02-15 14:00:00 2018-02-15 14:15:00 1. 1.
2 2. 2018-02-15 14:15:00 2018-02-15 14:30:00 2. 2.
# ... with 1 more variable: Value3 <dbl>
我想更改列名,可能是quarter_start
和quarter_end
列的格式,但除此之外,我认为它接近你想要的。
答案 2 :(得分:0)
这是data.table
和lubridate
方法(使用@pyll答案中的数据):
数据强>
set.seed <- 8675309
Month <- rep(1, 30)
Day <- rep(1, 30)
Hour <- rep(1, 30)
Minute <- seq(1, 30, 1)
value1 <- runif(30, 0, 100)
value2 <- runif(30, 10, 20)
df <- data.frame(Month, Day, Hour, Minute, value1, value2)
<强> CODE 强>
library(data.table)
library(lubridate)
dt <- as.data.table(df)
# Convert to R date-time (year is assumed to be 2018)
dt <- dt[, date := as.POSIXct(paste(Month, Day, Hour, Minute, sep = " "),
format = "%m %d %H %M", tz = "UTC")]
> head(dt)
Month Day Hour Minute value1 value2 date
1: 1 1 1 1 22.260566 16.86117 2018-01-01 01:01:00
2: 1 1 1 2 2.412274 18.53744 2018-01-01 01:02:00
3: 1 1 1 3 87.083359 15.65351 2018-01-01 01:03:00
4: 1 1 1 4 44.914115 15.00117 2018-01-01 01:04:00
5: 1 1 1 5 5.319505 14.06182 2018-01-01 01:05:00
6: 1 1 1 6 2.320090 19.11555 2018-01-01 01:06:00
> str(dt)
Classes ‘data.table’ and 'data.frame': 30 obs. of 7 variables:
$ Month : num 1 1 1 1 1 1 1 1 1 1 ...
$ Day : num 1 1 1 1 1 1 1 1 1 1 ...
$ Hour : num 1 1 1 1 1 1 1 1 1 1 ...
$ Minute: num 1 2 3 4 5 6 7 8 9 10 ...
$ value1: num 22.26 2.41 87.08 44.91 5.32 ...
$ value2: num 16.9 18.5 15.7 15 14.1 ...
$ date : POSIXct, format: "2018-01-01 01:01:00" "2018-01-01 01:02:00" "2018-01-01 01:03:00" ...
- attr(*, ".internal.selfref")=<externalptr>
<强>输出强>
> dt[, .(mean1 = mean(value1), mean2 = mean(value2)),
by = .(round_date(date, unit = "15 mins"))]
round_date mean1 mean2
1: 2018-01-01 01:00:00 27.42124 16.47126
2: 2018-01-01 01:15:00 38.20346 13.91443
3: 2018-01-01 01:30:00 44.70040 16.36477
我认为这是一种非常干净的方法,特别是如果你不得不对不规则的间隔(比如3分钟)执行自定义操作(mean
除外)。此外,由于data.table
通过引用执行操作,因此它非常快。希望这有帮助!