【问题标题】:Calculate average daily value from large data set with R standard format date/times?使用 R 标准格式日期/时间从大型数据集中计算平均每日价值?
【发布时间】:2017-12-02 12:33:46
【问题描述】:

我有一个大约 570 天的大约 1000 万行数据框。使用 striptime 转换日期和时间后,数据如下:

          date          X1   
1 2004-01-01 07:43:00 1.2587 
2 2004-01-01 07:47:52 1.2585
3 2004-01-01 17:46:14 1.2586 
4 2004-01-01 17:56:08 1.2585
5 2004-01-01 17:56:15 1.2585 

我想计算每一天的平均值(如一年中的几天,而不是一周中的几天),然后绘制它们。例如。获取日期为“2004-01-01”的所有行,计算平均价格,然后对“2004-01-2”执行相同的操作,依此类推。

同样,我有兴趣找到平均每月价值或每小时价格,但我想一旦我知道如何获得平均每日价格,我就可以计算出来。

我最大的困难是自动从日期变量中提取一年中的哪一天。如何循环遍历所有 365 天并计算每天的平均值,并将其存储在列表中?

我能够使用 weekdays() 函数找到星期几的平均值,但我找不到类似的东西。

【问题讨论】:

  • 第一部分你试过df %>% dplyr::group_by(date) %>% summarise(mean(X1))吗?这应该给你每天的平均值。您可以使用 lubridate 包来获得做类似事情的月份。

标签: r datetime dataframe time average


【解决方案1】:

lubridate 是一年中的哪一天

yday,如

lubridate::yday(Sys.time())

因为数据量很大,我推荐使用 data.table 方法

library(lubridate)
library(data.table)
df$ydate=yday(df$date)
df=data.table(df)
df[,mean(X1),ydate]

如果您想要不同年份的不同日子,例如 1Jan2004 和 1Jan2005

library(lubridate)
library(data.table)
df$ydate=ymd(df$date)
df=data.table(df)
df[,mean(X1),ydate]

注意 - 除了使用 striptime 来转换日期,你可以使用 lubridate 中的 ymd_hms 函数

【讨论】:

    【解决方案2】:

    这是使用dplyrlubridate 的解决方案。首先,通过使用floor_date 将日期向下舍入到最接近的日单位来简化日期(参见下面thelatemail 的评论),然后使用group_by 日期并使用summarize 计算平均值:

    library(dplyr)
    library(lubridate)
    
    df %>%
      mutate(date = floor_date(date)) %>%
      group_by(date) %>%
      summarize(mean_X1 = mean(X1))
    

    使用lubridate 包,您可以使用类似的方法获取月、周或小时的平均值。例如,按月计算平均值:

    df %>%
      mutate(date = month(date)) %>%
      group_by(date) %>%
      summarize(mean_X1 = mean(X1))
    

    按小时计算:

    df %>%
      mutate(date = hour(date)) %>%
      group_by(date) %>%
      summarize(mean_X1 = mean(X1))
    

    【讨论】:

    • 另请参阅this answer 以使用aggregatedata.tablexts 计算按日期的平均值
    • 非常感谢,这正是我所追求的(您的答案和您链接的答案)。干杯!
    • 小心建议as.Date(datetime) - as.Date 使用“UTC”时区进行来自 POSIXct 的转换,而日期时间可能存储在用户的时区中。这可能导致将期间开始或结束的日期归因于错误的特征。例如。 - as.Date(as.POSIXct("2011-01-01",tz="Australia/Sydney"))
    • 感谢您指出这一点,thelatemail。我编辑了答案以改用floor_date,我相信它会保留现有的时区。
    • @Thelatemail 啊,这是有道理的,我想知道为什么我从原来的状态中恢复了 1 天。必须与时区相关。
    猜你喜欢
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    • 2023-03-18
    • 2019-05-23
    • 2021-03-30
    • 2020-08-22
    • 2018-10-25
    • 2021-02-05
    相关资源
    最近更新 更多