【问题标题】:Convert Daily Data into Weekly in R Week Starts on Saturday在 R 中将每日数据转换为每周数据 从星期六开始
【发布时间】:2015-05-16 08:57:33
【问题描述】:

我无法使用一周的平均值将每日数据转换为每周数据。

我的数据如下所示:

> str(daily_FWIH)
'data.frame':   4371 obs. of  6 variables:
 $ Date     : Date, format: "2013-03-01" "2013-03-02" "2013-03-04" "2013-03-05" ...
 $ CST.OUC  : Factor w/ 6 levels "BVG11","BVG12",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ CST.NAME : Factor w/ 6 levels "Central Scotland",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ SOM_patch: Factor w/ 6 levels "BVG11_Highlands & Islands",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ Row_Desc : Factor w/ 1 level "FSFluidWIH": 1 1 1 1 1 1 1 1 1 1 ...
 $ Value    : num  1.16 1.99 1.47 1.15 1.16 1.28 1.27 2.07 1.26 1.19 ...

> head(daily_FWIH)
        Date CST.OUC            CST.NAME                 SOM_patch   Row_Desc Value
1 2013-03-01   BVG11 Highlands & Islands BVG11_Highlands & Islands FSFluidWIH  1.16
2 2013-03-02   BVG11 Highlands & Islands BVG11_Highlands & Islands FSFluidWIH  1.99
3 2013-03-04   BVG11 Highlands & Islands BVG11_Highlands & Islands FSFluidWIH  1.47
4 2013-03-05   BVG11 Highlands & Islands BVG11_Highlands & Islands FSFluidWIH  1.15
5 2013-03-06   BVG11 Highlands & Islands BVG11_Highlands & Islands FSFluidWIH  1.16
6 2013-03-07   BVG11 Highlands & Islands BVG11_Highlands & Islands FSFluidWIH  1.28

这是我尝试将其转换为 xts 对象的方法,如图所示 here

这是我尝试过的:

daily_FWIH$Date = as.Date(as.character(daily_FWIH$Date), "%d/%m/%Y")
library(xts)

temp.x = xts(daily_FWIH[-1], order.by=daily_FWIH$Date)
apply.weekly(temp.x, colMeans(temp.x$Value))

我有两个问题。我的一周在 “星期六” 开始和结束,我收到以下错误:

> apply.weekly(temp.x, colMeans(temp.x$Value))
Error in colMeans(temp.x$Value) : 'x' must be numeric

更新基于 Sam 的 cmets:

这就是我所做的:

daily_FWIH$Date <- ymd(daily_FWIH$Date) # convert to POSIX format
daily_FWIH$fakeDate <- daily_FWIH$Date + days(2)
daily_FWIH$week <- week(daily_FWIH$fakeDate) # extract week value
daily_FWIH$year <- year(daily_FWIH$fakeDate)

    > daily_FWIH %>%
+ group_by(year,week) %>%
+ mutate(weeklyAvg = mean(Value), weekStartsOn = min(Date)) %>% # create the average variable
+ slice(which(Date == weekStartsOn)) %>% # select just the first record of the week - other vars will come from this
+ select(-Value,-fakeDate,-week,-year,-Date, -CST.OUC,-CST.NAME) # drop unneeded variables
Source: local data frame [631 x 6]
Groups: year, week

   year week                   SOM_patch   Row_Desc weeklyAvg weekStartsOn
1  2013    9   BVG11_Highlands & Islands FSFluidWIH  1.048333   2013-03-01
2  2013    9   BVG12_North East Scotland FSFluidWIH  1.048333   2013-03-01
3  2013    9      BVG13_Central Scotland FSFluidWIH  1.048333   2013-03-01
4  2013    9   BVG14_South East Scotland FSFluidWIH  1.048333   2013-03-01
5  2013    9 BVG15_West Central Scotland FSFluidWIH  1.048333   2013-03-01
6  2013    9   BVG16_South West Scotland FSFluidWIH  1.048333   2013-03-01
7  2013   10   BVG11_Highlands & Islands FSFluidWIH  1.520500   2013-03-02
8  2013   10   BVG12_North East Scotland FSFluidWIH  1.520500   2013-03-02
9  2013   10      BVG13_Central Scotland FSFluidWIH  1.520500   2013-03-02
10 2013   10   BVG14_South East Scotland FSFluidWIH  1.520500   2013-03-02
..  ...  ...                         ...        ...       ...          ...

这是不正确的......

想要的输出是:

> head(desired)
        Date BVG11.Highlands_I_.A_pct BVG12.North.East.ScotlandA_pct BVG13.Central.ScotlandA_pct
1 01/03/2013                     1.16                           1.13                        1.08
2 08/03/2013                     1.41                           2.37                        1.80
3 15/03/2013                     1.33                           3.31                        1.34
4 22/03/2013                     1.39                           2.49                        1.62
5 29/03/2013                     5.06                           3.42                        1.42
6                                  NA                             NA                          NA
  BVG14.South.East.ScotlandA_pct BVG15.West.Central.ScotlandA_pct BVG16.South.West.ScotlandA_pct
1                           1.05                             0.98                           0.89
2                           1.51                             1.21                           1.07
3                           1.13                             2.13                           2.01
4                           2.14                             1.24                           1.37
5                           1.62                             1.46                           1.95
6                             NA                               NA                             NA

> str(desired)
'data.frame':   11 obs. of  7 variables:
 $ Date                            : Factor w/ 6 levels "01/03/2013",..: 2 3 4 5 6 1 1 1 1 1 ...
 $ BVG11.Highlands_I_.A_pct        : num  1.16 1.41 1.33 1.39 5.06  ...
 $ BVG12.North.East.ScotlandA_pct  : num  1.13 2.37 3.31 2.49 3.42  ...
 $ BVG13.Central.ScotlandA_pct     : num  1.08 1.8 1.34 1.62 1.42  ...
 $ BVG14.South.East.ScotlandA_pct  : num  1.05 1.51 1.13 2.14 1.62  ...
 $ BVG15.West.Central.ScotlandA_pct: num  0.98 1.21 2.13 1.24 1.46 ...
 $ BVG16.South.West.ScotlandA_pct  : num  0.89 1.07 2.01 1.37 1.95 ...

【问题讨论】:

  • re:从星期六开始结束 - 你的意思是星期六到星期日,然后在下星期六重新开始?

标签: r dataframe time-series weekend


【解决方案1】:

在您的数据中找到第一个星期六,然后根据该日期为您的数据集中的所有日期分配一个星期 ID:

library(lubridate) # for the wday() and ymd() functions
daily_FWIH$Date <- ymd(daily_FWIH$Date)
saturdays <- daily_FWIH[wday(daily_FWIH$Date) == 7, ] # filter for Saturdays
startDate <- min(saturdays$Date) # select first Saturday
daily_FWIH$week <- floor(as.numeric(difftime(daily_FWIH$Date, startDate, units = "weeks")))

一旦你有了一个 weekID-starting-on-Saturday 变量,这就是一个标准的 R 问题。您可以使用您为calculating means within a subgroup 选择的方法计算每周平均值。我喜欢dplyr

library(dplyr)
daily_FWIH %>%
  group_by(week, SOM_patch) %>% # use your grouping variables in addition to week
  summarise(weeklyAvg = mean(Value), weekBeginDate = min(Date)) %>%
  mutate(firstDayOfWeek = wday(weekBeginDate, label=TRUE)) # confirm correct week cuts

Source: local data frame [2 x 5]
Groups: week

  week                 SOM_patch weeklyAvg weekBeginDate firstDayOfWeek
1   -1 BVG11_Highlands & Islands      1.16    2013-03-01            Fri
2    0 BVG11_Highlands & Islands      1.41    2013-03-02            Sat

根据以下 cmets 更新:

如果您想查看数据集中的其他值,您需要决定当一周内的每日值发生冲突时如何选择或计算每周值。在您的示例数据中,它们在所有行中都是相同的,所以我只是从包含一周第一天的行中绘制它们。

library(dplyr)
daily_FWIH %>%
  group_by(week, SOM_patch) %>% # use your grouping variables
  mutate(weeklyAvg = mean(Value), weekBeginDate = min(Date)) %>%
  slice(which(Date == weekBeginDate)) %>% # select just the first record of the week - other vars will come from this 
  select(-Value, -Date) # drop unneeded variables

Source: local data frame [2 x 7]
Groups: week, SOM_patch

  CST.OUC            CST.NAME                 SOM_patch   Row_Desc week weeklyAvg weekBeginDate
1   BVG11 Highlands & Islands BVG11_Highlands & Islands FSFluidWIH   -1      1.16    2013-03-01
2   BVG11 Highlands & Islands BVG11_Highlands & Islands FSFluidWIH    0      1.41    2013-03-02

【讨论】:

  • 谢谢@Sam Firke,但我也想看看日期。例如我的第一个观察结果将是 2013-03-02 BVG11 Highlands &amp; Islands BVG11_Highlands &amp; Islands FSFluidWIH 1.99 这将具有相同的值,随后的日期将是 2013-03-09, 2013-03-16 等。这些将具有 04 to 2013-03-08 之间的平均值
  • @Shery 这行得通吗?它现在显示一周的最早日期及其日期(如果不需要,请删除最后一行代码)
  • 我不知道平均值是否正确...例如:2013-03-01 上的平均值应该是 1.16,这很好,但如果我在 2013-03-012013-03-02 之间手动计算,即 @987654332 @ 这不是您的答案,也无法在我的数据集中找到其他列,即 CST.OUC, CST.NAME, SOM_patch, Row_Desc 如何显示这些列,我将接受它作为答案。再次感谢
  • 查看更新后的答案。 2013 年 3 月 1 日是星期五,所以它本身算作一周(因为你的星期从星期六开始)。因此 1.16 是每周平均值。然后接下来的 5 条记录在下周(周六、周一、周二、周三、周四),因此它们被平均在一起:mean(c(1.99,1.47,1.15,1.16,1.28)) = 1.41。我看不出你什么时候会平均你命名的值,从 2013-03-01 和 2013-03-02,因为它们在不同的周。并且回复:选择其他变量,现在很容易,因为它们都是一样的——但总是这样吗?如果您创建所需的结果表可能会有所帮助。
  • 我改用了一种更简洁的方法来按周分组,并为未来的读者整理了答案。已解决从星期六开始的星期分组;在这一点上,任何关于其他方面的后续问题都最好作为他们自己的问题。我发布了另一个关于子组手段的问题的链接,因为这似乎是你现在被困的地方。下次我建议发布一个更丰富的样本数据集,其中包含您想要分组的不同组以及您想要的结果的任何其他方面(您无法使用您提供的数据产生您想要的结果)。
猜你喜欢
  • 1970-01-01
  • 2020-06-13
  • 2021-04-28
  • 2013-05-02
  • 2020-07-06
  • 2016-01-29
  • 1970-01-01
  • 2014-02-05
  • 1970-01-01
相关资源
最近更新 更多