【问题标题】:Calculate average of last 3 non holiday weekdays计算最近 3 个非假日工作日的平均值
【发布时间】:2016-09-05 19:40:34
【问题描述】:

我有一个数据框,用于显示不同类别的日期时间、星期、工作日的个人资料点击次数。

有关示例数据,请参阅下文(输入数据)。我正在寻找的是在所有类别中输出一个数据框,其中包含从周日到周六非假日周的最后 3 个工作日的平均值。

正如您在以下所需输出中所见,没有考虑假期周的任何数据。有没有不使用循环的简单方法来实现这一点?如果是,我们该怎么做?

所需输出:

CAT  Day  Avg
A    SUN  =(1 + 3+99) /3
A    MON  =(6+67+ 45) /3
A    TUE  = (2+ 53+ 68)/3
A    WED
A    THU
A    FRI
A    SAT

输入数据:

CAT  DATE       WEEJ    DAY  Hits   Holiday Week
A   9/3/2016    2016-35 SAT  58     No
A   9/2/2016    2016-35 FRI  9      No
A   9/1/2016    2016-35 THU  20     No
A   8/31/2016   2016-35 WED  92     No
A   8/30/2016   2016-35 TUE  2      No
A   8/29/2016   2016-35 MON  6      No
A   8/28/2016   2016-35 SUN  1      No
A   8/27/2016   2016-34 SAT  58     Yes
A   8/26/2016   2016-34 FRI  56     Yes
A   8/25/2016   2016-34 THU  40     Yes
A   8/24/2016   2016-34 WED  42     Yes
A   8/23/2016   2016-34 TUE  59     Yes
A   8/22/2016   2016-34 MON  21     Yes
A   8/21/2016   2016-34 SUN  98     Yes
A   8/20/2016   2016-33 Sat  2      No
A   8/19/2016   2016-33 FRI  85     No
A   8/18/2016   2016-33 THU  29     No
A   8/17/2016   2016-33 WED  37     No
A   8/16/2016   2016-33 TUE  53     No
A   8/15/2016   2016-33 MON  67     No
A   8/14/2016   2016-33 SUN  3      No
A   8/13/2016   2016-32 SAT  35     No
A   8/12/2016   2016-32 FRI  24     No
A   8/11/2016   2016-32 THU  94     No
A   8/10/2016   2016-32 WED  81     No
A   8/9/2016    2016-32 TUE  68     No
A   8/8/2016    2016-32 MON  45     No
A   8/7/2016    2016-32 SUN  99     No

【问题讨论】:

  • 请在我的帖子中检查所需的输出。这是预期的结果
  • 缺失数据(间隙,每组少于 3 行数据)的预期行为是什么?

标签: r


【解决方案1】:

我们可以使用data.table

library(data.table)
setDT(df1)[order(-as.IDate(DATE, "%m/%d/%Y"), toupper(DAY))
     ][HolidayWeek=="No",.(Ave = sum(Hits[1:3])/.N) , by = .(DAY=toupper(DAY))]
#  DAY      Ave
#1: SAT 31.66667
#2: FRI 39.33333
#3: THU 47.66667
#4: WED 70.00000
#5: TUE 41.00000
#6: MON 39.33333
#7: SUN 34.33333

如果是 3 次“Hits”的平均值

setDT(df1)[order(-as.IDate(DATE, "%m/%d/%Y"), toupper(DAY))
 ][HolidayWeek=="No",.(Ave = mean(Hits[1:3])) , by = .(DAY=toupper(DAY))]

【讨论】:

  • 我认为要求每组最后三个数据行的平均值。如果一个组的现有行超过三个,除以.N 可能会导致错误的平均值。 min(.N,3)?
  • @RYoda 在这种情况下,我们可以这样做(Ave = mean(Hits[1:3]))
【解决方案2】:

这是dplyr的解决方案:

library(dplyr)

answer <- x %>% filter(Holiday=="No") %>% group_by(Day)  %>% 
top_n(3,desc(Date))  %>% summarise(Avg = sum(Hits)/n())

它会删除所有假期,然后对于每个“DAY”,它会获取每一天的最后三个日期,最后汇总点击次数并除以这些天数,得出平均值。

请注意,一周中的“天”并非全部大写。

【讨论】:

    【解决方案3】:
    library(data.table)
    setDT(df)[Holiday_Week == 'No', .(Avg = sum(head(Hits, 3))/.N), by = .(CAT, DAY = tolower(DAY))]
    
    #   CAT DAY      Avg
    #1:   A sat 31.66667
    #2:   A fri 39.33333
    #3:   A thu 47.66667
    #4:   A wed 70.00000
    #5:   A tue 41.00000
    #6:   A mon 39.33333
    #7:   A sun 34.33333
    

    【讨论】:

    • 这似乎不是最后 3 个的平均值。
    • 您在哪一部分限制了平均周数?我只是看不到。
    • 是的,但是如果数据比问题中给出的长怎么办?
    • 我的意思是如果有 5 周,那么您的代码将取所有这 5 周的唯一天数的平均值,不是吗?
    • 嗨- 上面的代码只是取所有可用数据的平均值,它应该取过去 3 个工作日的平均值,不包括假期周。对于每个类别,我有超过 50 周的数据,并且有 100 多个类别(如 A、B、C ....)。我们如何才能获得每个类别最近 3 个工作日的平均值
    【解决方案4】:

    基础R 解决方案

    do.call("rbind",
            lapply(split(df,df[,c("Holiday","CAT","DAY")]),
                   function(x) if (x$Holiday[1]=="Yes") {
                     NULL
                   } else {
                     data.frame(CAT=x$CAT[1],
                                DAY=x$DAY[1],
                                MN=mean(tail(x[order(x$DATE),],3)$Hits))}))
    #         CAT DAY       MN
    #No.A.FRI   A FRI 39.33333
    #No.A.MON   A MON 39.33333
    #No.A.SAT   A SAT 31.66667
    #No.A.SUN   A SUN 34.33333
    #No.A.THU   A THU 47.66667
    #No.A.TUE   A TUE 41.00000
    #No.A.WED   A WED 70.00000
    

    【讨论】:

    • 顺便说一句:我已在您的示例数据中手动将 Sat 更改为 SAT,因为我认为这只是一个错字。
    【解决方案5】:

    非节假日和节假日的平均分日

    Library(data.table)
    
    data <- Input data
    
    setDT(data)[, mean(Hits), by = .(DAY, Holiday) ]
    

    也许使用tolower(DAY),因为您的数据存在一些命名差异。

    只是没有假期:

    setDT(data)[Holiday == "No", mean(Hits), by = tolower(DAY) ]
    

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 2014-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多