【问题标题】:R Sum rows by hourly rateR 按小时计算行数
【发布时间】:2018-05-11 10:31:52
【问题描述】:

我刚开始使用 R,所以请多多包涵

例如,我有这个data.table(或data.frame)对象:

Time               Station      count_starts    count_ends
01/01/2015 00:30       A            2               3
01/01/2015 00:40       A            2               1
01/01/2015 00:55       B            1               1
01/01/2015 01:17       A            3               1
01/01/2015 01:37       A            1               1

我的最终目标是将“时间”列分组为每小时,并根据每小时的时间和站点对count_startscount_ends 求和:

Time               Station      sum(count_starts)   sum(count_ends)
01/01/2015 01:00       A            4                      4
01/01/2015 01:00       B            1                      1
01/01/2015 02:00       A            4                      2

我做了一些研究,发现我应该使用xts 库。

谢谢你帮助我

更新:

我将transactions$Time的类型转换为POSIXct,所以xts包应该可以直接使用timeseries了。

【问题讨论】:

标签: r dataframe time-series


【解决方案1】:

使用基数 R,我们仍然可以执行上述操作。只是他们所有人的时间会少一小时:

 dat=read.table(text = "Time               Station      count_starts    count_ends
 '01/01/2015 00:30'       A            2               3
 '01/01/2015 00:40'       A            2               1
 '01/01/2015 00:55'       B            1               1
 '01/01/2015 01:17'       A            3               1
 '01/01/2015 01:37'       A            1               1",
             header = TRUE, stringsAsFactors = FALSE)

 dat$Time=cut(strptime(dat$Time,"%m/%d/%Y %H:%M"),"hour")
 aggregate(.~Time+Station,dat,sum)
                  Time Station count_starts count_ends
 1 2015-01-01 00:00:00       A            4          4
 2 2015-01-01 01:00:00       A            4          2
 3 2015-01-01 00:00:00       B            1          1

您可以使用order 函数重新排列表格,甚至可以使用sort.POSIXlt 函数:

 m=aggregate(.~Time+Station,dat,sum)
 m[order(m[,1]),]
                  Time Station count_starts count_ends
 1 2015-01-01 00:00:00       A            4          4
 3 2015-01-01 00:00:00       B            1          1
 2 2015-01-01 01:00:00       A            4          2

【讨论】:

  • 谢谢。我尝试了您的解决方案,但 cut 方法返回错误: seq.int(0, to0 - from, by) 中的错误:'to' 必须是有限数。我仍在解决这个错误。
  • 哦,你需要小心。在替换 dat$Time 之前,请确保您的 dat 与最初给出的相同。只需再次运行dat 然后运行我给出的两个代码
  • 我现在已经给出了数据。运行数据然后代码
  • 非常感谢您的帮助。我在做时间序列分析,会有“少一小时”的差异吗?即 00:00:00 将在 00:00:00 到 01:00:00 之间求和
  • 没有区别。 00:00:00 将在 00:00:00 到 01:00:00 之间求和,01:00:00 将在 01:00:00 到 02:00:00 之间求和,依此类推..
【解决方案2】:

使用dplyrlubridate 的解决方案。关键是使用ceiling_date将日期时间列转换为小时时间步长,然后对数据进行分组汇总。

library(dplyr)
library(lubridate)

dt2 <- dt %>%
  mutate(Time = mdy_hm(Time)) %>%
  mutate(Time = ceiling_date(Time, unit = "hour")) %>%
  group_by(Time, Station) %>%
  summarise(`sum(count_starts)` = sum(count_starts),
            `sum(count_ends)` = sum(count_ends)) %>%
  ungroup()
dt2
# # A tibble: 3 x 4
#                  Time Station `sum(count_starts)` `sum(count_ends)`
#                <dttm>   <chr>               <int>             <int>
# 1 2015-01-01 01:00:00       A                   4                 4
# 2 2015-01-01 01:00:00       B                   1                 1
# 3 2015-01-01 02:00:00       A                   4                 2

数据

dt <- read.table(text = "Time               Station      count_starts    count_ends
'01/01/2015 00:30'       A            2               3
'01/01/2015 00:40'       A            2               1
'01/01/2015 00:55'       B            1               1
'01/01/2015 01:17'       A            3               1
'01/01/2015 01:37'       A            1               1",
                 header = TRUE, stringsAsFactors = FALSE)

说明

mdy_hm 是将字符串转换为date-time 类的函数。它的意思是“月-日-年-时-分”,这取决于字符串的结构。 ceiling_date 根据指定的单位对日期时间对象进行四舍五入。 group_by 是对变量进行分组。 summarise是进行汇总操作。

【讨论】:

  • 感谢您的帮助。我会尝试你的解决方案,但我不明白代码。是否可以改用data.tablexts 库来解决这个问题?
  • @BlazeTama 我不熟悉xts 包。也许其他人可以帮助你。
  • @BlazeTama 我在代码中添加了一些解释。
  • 感谢您的解释,我会尝试它作为替代方案。一个小问题,我的字符串格式是%d/%m/%H,可以用pattern读吗?
  • @Blaze Tama。你有一个错误的原因是因为你在一个因素上使用as.Date 而不是一个字符。尝试做as.Date(as.character(...))
【解决方案3】:

基本上需要两件事: 1)将时间循环到最近的 1 小时窗口:

library(data.table)

library(lubridate)

data=data.table(Time=c('01/01/2015 00:30','01/01/2015 00:40','01/01/2015 00:55','01/01/2015 01:17','01/01/2015 01:37'),Station=c('A','A','B','A','A'),count_starts=c(2,2,1,3,1),count_ends=c(3,1,1,1,1))

data[,Time_conv:=as.POSIXct(strptime(Time,'%d/%m/%Y %H:%M'))]

data[,Time_round:=floor_date(Time_conv,unit="1 hour")]

2)列出上面得到的数据表,得到想要的结果:

New_data=data[,list(count_starts_sum=sum(count_starts),count_ends_sum=sum(count_ends)),by='Time_round']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-14
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多