平均值相对于时间

时间:2017-09-08 13:07:40

标签: r datetime

我有以下数据集,包含日期时间和相应的值。时间间隔是每10分钟。我需要生成15分钟间隔的新行。

例如,对于15:40,值为599,对于15:50,值为594,因此需要在两者之间生成新行,即15:45,平均值为599& 594是596.5

即,我需要产生10到10之间的平均值。 20得到16:15的价值;和40& 50得到16:45的价值。 00,30的值保持不变

Date...Time       RA.CO2
6/15/2017 15:40   599
6/15/2017 15:50   594
6/15/2017 16:00   606
6/15/2017 16:10   594
6/15/2017 16:20   594
6/15/2017 16:30   594
6/15/2017 16:40   594
6/15/2017 16:50   594
6/16/2017 0:00    496.25
6/16/2017 0:10    500
6/16/2017 0:20    496.25
6/16/2017 0:30    496.25
6/16/2017 0:40    600
6/16/2017 0:50    650
6/16/2017 1:00    700 

str(df)
'data.frame':   6092 obs. of  2 variables:
 $ Date...Time: chr  "6/15/2017 15:40" "6/15/2017 15:50" "6/15/2017 16:00" 
 "6/15/2017 16:10" ...
$ RA.CO2     : num  599 594 606 594 594 594 594 594 594 594 ...

输出

 Date...Time          RA.CO2
 6/15/2017 15:45      596.5
 6/15/2017 16:00      606
 6/15/2017 16:15      594
 6/15/2017 16:30      594
 6/15/2017 16:45      594
 6/16/2017 0:00       496.25
 6/16/2017 0:15       498.125
 6/16/2017 0:30       496.25
 6/16/2017 0:45       625
 6/16/2017 1:00       700

4 个答案:

答案 0 :(得分:3)

我们可以使用tidyr展开数据框,使用imputeTS通过线性插值来估算缺失值。

library(dplyr)
library(tidyr)
library(lubridate)
library(imputeTS)

dt2 <- dt %>%
  mutate(Date...Time = mdy_hm(Date...Time)) %>%
  mutate(Date = as.Date(Date...Time)) %>%
  group_by(Date) %>%
  complete(Date...Time = seq(min(Date...Time), max(Date...Time), by = "5 min")) %>%
  mutate(RA.CO2 = na.interpolation(RA.CO2)) %>%
  ungroup() %>%
  select(Date...Time, RA.CO2)
dt2
# A tibble: 22 x 2
           Date...Time RA.CO2
                <dttm>  <dbl>
 1 2017-06-15 15:40:00  599.0
 2 2017-06-15 15:45:00  596.5
 3 2017-06-15 15:50:00  594.0
 4 2017-06-15 15:55:00  600.0
 5 2017-06-15 16:00:00  606.0
 6 2017-06-15 16:05:00  600.0
 7 2017-06-15 16:10:00  594.0
 8 2017-06-15 16:15:00  594.0
 9 2017-06-15 16:20:00  594.0
10 2017-06-15 16:25:00  594.0
# ... with 12 more rows

我的输出与您想要的输出不完全相同。这是因为:

  1. 目前尚不清楚如何获得6/16/2017 0:10中的值。
  2. 为什么有时间隔为5分钟,但有时为10分钟?
  3. 为什么要包含最后三行?填写最后三行的值的规则也不清楚。
  4. 尽管如此,我认为我的解决方案为您提供了实现此任务的可能方法。您可能需要自己调整代码以适应那些不明确的规则。

    数据

    dt <- read.table(text = "Date...Time       RA.CO2
    '6/15/2017 15:40'   599
                     '6/15/2017 15:50'   594
                     '6/15/2017 16:00'   606
                     '6/15/2017 16:10'   594
                     '6/15/2017 16:20'   594
                     '6/15/2017 16:30'   594
                     '6/15/2017 16:40'   594
                     '6/15/2017 16:50'   594
                     '6/16/2017 0:00'    496.25
                     '6/16/2017 0:10'    496.25
                     '6/16/2017 0:20'    496.25
                     '6/16/2017 0:30'    496.25",
                     header = TRUE, stringsAsFactors = FALSE)
    

答案 1 :(得分:2)

以下是一些解决方案。我已经重新阅读了这个问题,并假设新的中间时间只能在小时后20或50分钟之前插入,并且在两种情况下,紧接在前的时间(在插入中间时间之前)必须是10分钟之前。如果那不是问题的意图,那么it,中间时间的向量将需要从显示的内容改变。

1)zoo df与中间时间为it的数据框合并,然后在{{1}上的动物园包中运行na.approx }列填写RA值:

NA

,并提供:

library(zoo)

it <- with(df, DT[c(FALSE, diff(DT) == 10) & as.POSIXlt(DT)$min %in% c(20, 50)] - 5 * 60)
M <- merge(df, data.frame(DT = it), all = TRUE)
transform(M, RA = na.approx(RA))

1a)请注意,如果将 DT RA 1 2017-06-15 15:40:00 599.00 2 2017-06-15 15:45:00 596.50 3 2017-06-15 15:50:00 594.00 4 2017-06-15 16:00:00 606.00 5 2017-06-15 16:10:00 594.00 6 2017-06-15 16:15:00 594.00 7 2017-06-15 16:20:00 594.00 8 2017-06-15 16:30:00 594.00 9 2017-06-15 16:40:00 594.00 10 2017-06-15 16:45:00 594.00 11 2017-06-15 16:50:00 594.00 12 2017-06-16 00:00:00 496.25 13 2017-06-16 00:10:00 496.25 14 2017-06-16 00:15:00 496.25 15 2017-06-16 00:20:00 496.25 16 2017-06-16 00:30:00 496.25 转换为动物园,即df,则可以将其写为动态对象结果:

z <- read.zoo(df, tz = "")

2)约这个不使用包。 na.approx(merge(z, zoo(, it))) 来自上方。

it

,并提供:

with(df, data.frame(approx(DT, RA, xout = sort(c(DT, it)))))

注意:上面使用的输入是:

                     x      y
1  2017-06-15 15:40:00 599.00
2  2017-06-15 15:45:00 596.50
3  2017-06-15 15:50:00 594.00
4  2017-06-15 16:00:00 606.00
5  2017-06-15 16:10:00 594.00
6  2017-06-15 16:15:00 594.00
7  2017-06-15 16:20:00 594.00
8  2017-06-15 16:30:00 594.00
9  2017-06-15 16:40:00 594.00
10 2017-06-15 16:45:00 594.00
11 2017-06-15 16:50:00 594.00
12 2017-06-16 00:00:00 496.25
13 2017-06-16 00:10:00 496.25
14 2017-06-16 00:15:00 496.25
15 2017-06-16 00:20:00 496.25
16 2017-06-16 00:30:00 496.25

更新:修改了包含哪些中间时间的假设。

答案 2 :(得分:1)

这是使用dplyr的解决方案:

library(dplyr)

df %>%
  # calculate interpolated value between each row & next row
  mutate(DT.next = lead(DT),
         RA.next = lead(RA)) %>%
  mutate(diff = difftime(DT.next, DT)) %>%
  filter(as.numeric(diff) == 10) %>% #keep only 10 min intervals
  mutate(DT.interpolate = DT + diff/2,
         RA.interpolate = (RA + RA.next) / 2) %>%
  # bind to original dataframe & sort by date
  select(DT.interpolate, RA.interpolate) %>%
  rename(DT = DT.interpolate, RA = RA.interpolate) %>%
  rbind(df) %>%
  arrange(DT)

                    DT     RA
1  2017-06-15 15:40:00 599.00
2  2017-06-15 15:45:00 596.50
3  2017-06-15 15:50:00 594.00
4  2017-06-15 15:55:00 600.00
5  2017-06-15 16:00:00 606.00
6  2017-06-15 16:05:00 600.00
7  2017-06-15 16:10:00 594.00
8  2017-06-15 16:15:00 594.00
9  2017-06-15 16:20:00 594.00
10 2017-06-15 16:25:00 594.00
11 2017-06-15 16:30:00 594.00
12 2017-06-15 16:35:00 594.00
13 2017-06-15 16:40:00 594.00
14 2017-06-15 16:45:00 594.00
15 2017-06-15 16:50:00 594.00
16 2017-06-16 00:00:00 496.25
17 2017-06-16 00:05:00 496.25
18 2017-06-16 00:10:00 496.25
19 2017-06-16 00:15:00 496.25
20 2017-06-16 00:20:00 496.25
21 2017-06-16 00:25:00 496.25
22 2017-06-16 00:30:00 496.25

数据集:

df <- data.frame(
  DT = c(seq(from = as.POSIXct("2017-06-15 15:40"),
             to = as.POSIXct("2017-06-15 16:50"),
             by = "10 min"),
         seq(from = as.POSIXct("2017-06-16 00:00"),
             to = as.POSIXct("2017-06-16 00:30"),
             by = "10 min")),
  RA = c(599, 594, 606, rep(594, 5), rep(496.25, 4))
)

答案 3 :(得分:1)

使用zoo库,

这是一个不同的想法
library(zoo)

df1 <- df[rep(rownames(df), each = 2),]
df1$DateTime[c(FALSE, TRUE)] <- df1$DateTime[c(FALSE, TRUE)]+5*60
df1$RA.CO2[c(FALSE, TRUE)] <- rollapply(df$RA.CO2, 2, by = 2, mean)

给出,

               DateTime RA.CO2
1    2017-06-15 15:40:00 599.00
1.1  2017-06-15 15:45:00 596.50
2    2017-06-15 15:50:00 594.00
2.1  2017-06-15 15:55:00 600.00
3    2017-06-15 16:00:00 606.00
3.1  2017-06-15 16:05:00 594.00
4    2017-06-15 16:10:00 594.00
4.1  2017-06-15 16:15:00 594.00
5    2017-06-15 16:20:00 594.00
5.1  2017-06-15 16:25:00 496.25
6    2017-06-15 16:30:00 594.00
6.1  2017-06-15 16:35:00 496.25
7    2017-06-15 16:40:00 594.00
7.1  2017-06-15 16:45:00 596.50
8    2017-06-15 16:50:00 594.00
8.1  2017-06-15 16:55:00 600.00
9    2017-06-16 00:00:00 496.25
9.1  2017-06-16 00:05:00 594.00
10   2017-06-16 00:10:00 496.25
10.1 2017-06-16 00:15:00 594.00
11   2017-06-16 00:20:00 496.25
11.1 2017-06-16 00:25:00 496.25
12   2017-06-16 00:30:00 496.25
12.1 2017-06-16 00:35:00 496.25