计算过去3个非假日工作日的平均值

时间:2016-09-05 08:41:13

标签: r

我有一个数据框,其中包含各种类别的日期时间,星期,工作日的个人资料匹配数。

有关样本数据,请参阅下文(输入数据)。我正在寻找的是输出一个数据帧,其中包括所有类别中从周日到周六的非假日周的平均最后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

5 个答案:

答案 0 :(得分:4)

我们可以使用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))]

答案 1 :(得分:2)

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

答案 2 :(得分:2)

这是dplyr的解决方案:

library(dplyr)

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

它会删除所有假日,然后每隔一天就会删除一次。然后它会记录每个日期的最后三个日期,最后总结点击次数并除以那些天数,给出平均值。

请注意您的日期&#39;一周都不是大写的。

答案 3 :(得分:2)

基础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

答案 4 :(得分:0)

非假日和假日的平均按天分割

Library(data.table)

data <- Input data

setDT(data)[, mean(Hits), by = .(DAY, Holiday) ]

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

只是没有假期:

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