【问题标题】:Averaging daily data into weekly data将每日数据平均为每周数据
【发布时间】:2013-02-27 00:55:07
【问题描述】:

我想知道是否有办法将每日数据平均为每周数据。我称之为 CADaily 的数据框如下所示:

      > CADaily[1:10, ]
          Climate_Division       Date      Rain
      885                1 1948-07-01 0.8750000
      892                1 1948-07-02 2.9166667
      894                1 1948-07-03 0.7916667
      895                1 1948-07-04 0.4305556
      898                1 1948-07-05 0.8262061
      901                1 1948-07-06 0.5972222
      904                1 1948-07-17 0.04166667
      905                1 1948-07-18 0.08333333
      907                1 1948-07-20 0.04166667
      909                1 1948-07-22 0.12500000
      910                1 1948-07-21 NA

我的目标类似于聚合函数,根据日期(当然)和气候分区(范围从 1 到 7)将每日降雨的平均值转换为每周降雨值。我在网上搜索时发现了一个可以使用但与我的目标不太相符的代码:

      apply.weekly(xts(CADaily[,-2], order.by= CADaily[,2]), FUN = mean)

这符合我的要求,但我的专栏 Climate_Division 也是平均的。我只想对 Rain 进行平均,然后根据 Climate_Division 和 Date 对其进行排序。有没有办法我可以这样做:

      aggregate(CADaily, by =list(CADaily$Climate_Division, CADaily$Date), FUN = mean, na.rm = TRUE)

日期在哪里以某种形式的周?还是有别的办法?


编辑:

亲爱的,

感谢您的帮助。也许使用聚合并不是我最初认为的最好的方法。在输出方面,我想获得数据(1948 - 1995 年)所有年份的每周平均降雨量。换句话说,我想获得一种很好的格式,我可以将它输入到具有周末日期形式的时间序列中。我正在寻找的输出(请记住,可能存在 NA 值)是:

      Climate_Division     Date          Rain
      1                    1948-07-03    1.527778
      1                    1948-07-10    0.6179946
      1                    1948-07-17    0.04166667
      1                    1948-07-24    0.08333333
      ...
      1                    1995-12-23    0.24513245
      1                    1995-12-30    0.12450545

或者有没有更好的方法来表达由日期表示的每周数据?

感谢您的帮助。

【问题讨论】:

    标签: r dayofweek


    【解决方案1】:

    更新答案

    根据 OP 对请求的更新,我修改了代码以汇总每周定义的日期(星期六)的数据。这次我只使用 base R 中可用的函数。它忽略了 NA(如果给定的 End_of_Week-Climate_Division 只有 NA,你会得到 NaN,而不是数字)。

    # Data with another Climate division as example (same daily values and dates)
    CADaily <-
    structure(list(Climate_Division = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), Date = structure(c(1L, 2L, 
    3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 
    8L, 9L, 10L), .Label = c("01/07/1948", "02/07/1948", "03/07/1948", 
    "04/07/1948", "05/07/1948", "06/07/1948", "17/07/1948", "18/07/1948", 
    "20/07/1948", "22/07/1948"), class = "factor"), Rain = c(0.875, 
    2.9166667, 0.7916667, 0.4305556, 0.8262061, 0.5972222, 0.04166667, 
    0.08333333, 0.04166667, 0.125, 0.875, 2.9166667, 0.7916667, 0.4305556, 
    0.8262061, 0.5972222, 0.04166667, 0.08333333, 0.04166667, 0.125
    ), week = c(27, 27, 27, 27, 27, 27, 29, 29, 29, 30, 27, 27, 27, 
    27, 27, 27, 29, 29, 29, 30)), .Names = c("Climate_Division", 
    "Date", "Rain", "week"), row.names = c(NA, 20L), class = "data.frame")
    
    # Coerce to Date class
    CADaily$Date <- as.Date(x=CADaily$Date, format='%d/%m/%Y')
    
    # Extract day of the week (Saturday = 6)
    CADaily$Week_Day <- as.numeric(format(CADaily$Date, format='%w'))
    
    # Adjust end-of-week date (first saturday from the original Date)
    CADaily$End_of_Week <- CADaily$Date + (6 - CADaily$Week_Day)
    
    # Aggregate over week and climate division
    aggregate(Rain~End_of_Week+Climate_Division, FUN=mean, data=CADaily, na.rm=TRUE)
    
    # Output
    #   End_of_Week Climate_Division       Rain
    # 1  1948-07-03                1 1.52777780
    # 2  1948-07-10                1 0.61799463
    # 3  1948-07-17                1 0.04166667
    # 4  1948-07-24                1 0.08333333
    # 5  1948-07-03                2 1.52777780
    # 6  1948-07-10                2 0.61799463
    # 7  1948-07-17                2 0.04166667
    # 8  1948-07-24                2 0.08333333
    

    其他操作

    此外,使用此代码,您可以从其他聚合函数中获取结果,假设结果是每个周除对的相同长度的原子向量。

    # Aggregate over week and climate division, and show the total number of
    # observations per week, the number of observations which represent missing
    # values, the average, and the standard deviation.
    aggregate(Rain~End_of_Week+Climate_Division, data=CADaily,
              FUN=function(x) c(n=length(x),
                                NAs=sum(is.na(x)),
                                Average=mean(x, na.rm=TRUE),
                                SD=sd(x, na.rm=TRUE)))
    
    # Output. You get NA for the standard deviation if there is only one observation.
    #   End_of_Week Climate_Division     Rain.n   Rain.NAs Rain.Average    Rain.SD
    # 1  1948-07-03                1 3.00000000 0.00000000   1.52777780 1.20353454
    # 2  1948-07-10                1 3.00000000 0.00000000   0.61799463 0.19864151
    # 3  1948-07-17                1 1.00000000 0.00000000   0.04166667         NA
    # 4  1948-07-24                1 3.00000000 0.00000000   0.08333333 0.04166667
    # 5  1948-07-03                2 3.00000000 0.00000000   1.52777780 1.20353454
    # 6  1948-07-10                2 3.00000000 0.00000000   0.61799463 0.19864151
    # 7  1948-07-17                2 1.00000000 0.00000000   0.04166667         NA
    # 8  1948-07-24                2 3.00000000 0.00000000   0.08333333 0.04166667
    



    原答案

    尝试使用lubridate 包。加载它,然后聚合(作为原始答案的一部分保留记录,这反映了 OP 按周聚合的请求)。

    # Load lubridate package
    library(package=lubridate)
    
    # Set Weeks number. Date already of class `Date`
    CADaily$Week <- week(CADaily$Date)
    
    # Aggregate over week number and climate division
    aggregate(Rain~Week+Climate_Division, FUN=mean, data=CADaily, na.rm=TRUE)
    
    # Output
    #   Week Climate_Division       Rain
    # 1   27                1 1.07288622
    # 2   29                1 0.05555556
    # 3   30                1 0.12500000
    # 4   27                2 1.07288622
    # 5   29                2 0.05555556
    # 6   30                2 0.12500000
    

    【讨论】:

    • 亲爱的奥斯卡,感谢您的帮助。也许使用聚合并不是我最初认为的最好的方法。在输出方面,我想获得数据(1948 - 1995 年)所有年份的每周平均降雨量。换句话说,我想获得一种很好的格式,我可以将它输入到具有周末日期形式的时间序列中。例如:
    • 抱歉,由于上述评论中的所有内容都不适合,我将在主要问题上进行编辑。
    • 啊,用周末代替一年中的周数很容易,我们将放弃使用非基础包。基本上,您应该获取每个日期的工作日,并将该日期添加到该周星期六的剩余天数。稍后我上班时会更新答案。
    • 完美!做我想做的事。感谢您对奥斯卡的所有帮助。
    • @OscardeLeón,关于您的原始答案,我认为在CADaily$Week &lt;- Week(CADaily$Date) 中应该是week 而不是Week
    【解决方案2】:

    xts 非常适合此类操作。使用endpoints 对数据进行子集化,然后使用sapply 每周对其进行处理。

    CADaily <- read.table(text ='     Climate_Division       Date      Rain
          885                1 1948-07-01 0.8750000
          892                1 1948-07-02 2.9166667
          894                1 1948-07-03 0.7916667
          895                1 1948-07-04 0.4305556
          898                1 1948-07-05 0.8262061
          901                1 1948-07-06 0.5972222
          904                1 1948-07-17 0.04166667
          905                1 1948-07-18 0.08333333
          907                1 1948-07-20 0.04166667
          909                1 1948-07-22 0.12500000',head=T)
    dat.xts <- xts(CADaily[,-2], order.by= as.POSIXct(CADaily[,2]))
    INDEX <- endpoints(dat.xts, 'weeks')
    
    lapply(1:(length(INDEX) - 1), function(y) {
        y <- dat.xts[(INDEX[y] + 1):INDEX[y + 1]]
        data.frame(y$Climate_Division,mean(y$Rain))
    
      })
    

    我的结果是按周列出的:

    [[1]]
               Climate_Division mean.y.Rain.
    1948-07-01                1     1.168019
    1948-07-02                1     1.168019
    1948-07-03                1     1.168019
    1948-07-04                1     1.168019
    1948-07-05                1     1.168019
    
    [[2]]
               Climate_Division mean.y.Rain.
    1948-07-06                1    0.5972222
    
    [[3]]
               Climate_Division mean.y.Rain.
    1948-07-17                1       0.0625
    1948-07-18                1       0.0625
    
    [[4]]
               Climate_Division mean.y.Rain.
    1948-07-20                1   0.08333334
    1948-07-22                1   0.08333334
    

    【讨论】:

    • 这很好,但是,当我使用您的算法运行完整数据时,我遇到了许多警告:警告消息:1:在 data.row.names(row.names, rowsi, i) 中:一些 row.names 重复:2,3,4,5,6,7,9,12,13,15,16 --> row.names 不使用命令 tail(x),其中 x 是我设置的相等对于函数 lapply 返回的内容,我没有获得某个日期所有部门都存在的日期:
    • [[140]] Climate_Division mean.y.Mean..na.rm...TRUE。 1948-05-28 17:00:00 2 4.020833 1948-05-29 17:00:00 2 4.020833 [[141]] Climate_Division mean.y.Mean..na.rm...TRUE。 1948-05-31 17:00:00 2 0.02083333 1948-06-05 17:00:00 2 0.02083333
    • [[142]] Climate_Division mean.y.Mean..na.rm...TRUE。 1 1 0.486447 2 2 0.486447 3 3 0.486447 4 4 0.486447 5 5 0.486447 6 6 0.486447 7 7 0.486447 8 1 0.486447 9 2 0.486447 10 1 0.486447 11 1 0.486447 跨度>
    • @LucianoRodriguez 我迷路了!:)
    • @agstudy,很抱歉让你迷路了,我不太熟悉如何在评论中使文本变得漂亮。但我正在寻找的输出是在我的主要问题的编辑版本中。让我知道这是否仍然令人困惑:/
    【解决方案3】:

    我回溯了我之前的回答。我觉得这个简单多了。

    你只需要找出每一行即将到来的周末日期,然后聚合

    CADaily <- read.table(text = "Climate_Division       Date      Rain\n1 1948-07-01 0.8750000\n1 1948-07-02 2.9166667\n1 1948-07-03 0.7916667\n1 1948-07-04 0.4305556\n1 1948-07-05 0.8262061\n1 1948-07-06 0.5972222\n1 1948-07-17 0.04166667\n1 1948-07-18 0.08333333\n1 1948-07-20 0.04166667\n1 1948-07-22 0.12500000\n2 1948-07-01 0.8750000\n2 1948-07-02 2.9166667\n2 1948-07-03 0.7916667\n2 1948-07-04 0.4305556\n2 1948-07-05 0.8262061\n2 1948-07-06 0.5972222\n2 1948-07-17 0.04166667\n2 1948-07-18 0.08333333\n2 1948-07-20 0.04166667\n2 1948-07-22 0.12500000", 
        head = T)
    
    CADaily$weekend <- as.POSIXlt(CADaily$Date) + (7 - as.POSIXlt(CADaily$Date)$wday) * 24 * 60 * 60
    
    aggregate(Rain ~ weekend + Climate_Division, data = CADaily, FUN = mean)
    ##      weekend Climate_Division       Rain
    ## 1 1948-07-04                1 1.52777780
    ## 2 1948-07-11                1 0.61799463
    ## 3 1948-07-18                1 0.04166667
    ## 4 1948-07-25                1 0.08333333
    ## 5 1948-07-04                2 1.52777780
    ## 6 1948-07-11                2 0.61799463
    ## 7 1948-07-18                2 0.04166667
    ## 8 1948-07-25                2 0.08333333
    

    【讨论】:

    • 尊敬的 geektrader,感谢您的输入。但是,查看您的输出,结果按除法分隔,但它们不是每周值。例如,第一个输出是 1948-07-05,而第二个输出是第二天 1948-07-06。所以这不一定是每周一次。有没有办法在每周的星期六做平均?
    • @LucianoRodriguez 我已经编辑了我的答案,以更简单的方式直接使用 data.frame 本身
    • @geektrader 正如我之前建议的那样。尝试使用strptimeformat='%w'。这将为您提供工作日作为数字(星期六 = 6),而不会更改为基于秒的 POSIXlt。
    • @OscardeLeón from ?strptime strptime 将字符向量转换为“POSIXlt”类:其输入 x 首先由 as.character 转换。
    • @geektrader 你是对的。谢谢,对于误导性的评论,我们深表歉意。
    【解决方案4】:

    只是做:

    library(tidyverse)
    library(lubridate)
    
    df <- df %>% 
      group_by(week = week(Date)) %>% #make sure 'Date' is a Date.object
      mutate("rain_mean" = mean(Rain))
    

    【讨论】:

    • 请在您的回答中提供更多详细信息。正如目前所写的那样,很难理解您的解决方案。
    猜你喜欢
    • 2015-05-11
    • 2017-02-22
    • 1970-01-01
    • 2020-07-06
    • 2021-02-07
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多