dplyr按工作日汇总日期

时间:2016-05-20 19:44:11

标签: r dplyr

我在不同的日期有不同人的多次观察,例如

# Sample matrix
set.seed(23)
n <- 1000
mat <- matrix(sample(0:10,n*n,replace=T),ncol=n,nrow=n)
colnames(mat) <- paste0("C",1:n)
rownames(mat) <- paste0("R",1:n)

# Old function
downsampled<-function(data,samplerate=0.8) {
    data.test<-apply(data,2,function(q){
    names(q)<-rownames(data)
    samplepool<-character()
    for (i in names(q)) {
      samplepool=append(samplepool,rep(i,times=q[i]))  
    }
    sampled=sample(samplepool,size=samplerate*length(samplepool),replace = F)
    tab=table(sampled)
    mat=match(names(tab),names(q))
    toret=numeric(length = length(q))
    names(toret)<-names(q)
    toret[mat]<-tab
    return(toret)
  })
return(data.test)
}

# New function
downsampled2 <- function(mat, samplerate=0.8) {
    new <- matrix(0, nrow(mat), ncol(mat))
    colnames(new) <- colnames(mat)
    rownames(new) <- rownames(mat)
    for (i in 1:nrow(mat)) {
        for (j in 1:ncol(mat)) {
            new[i,j] <- sum(runif(mat[i,j], 0, 1) < samplerate)
        }
    }
    return(new)
}

# Compare times
system.time(downsampled(mat,0.8))
##    user  system elapsed 
##  26.840   3.249  29.902 
system.time(downsampled2(mat,0.8))
##    user  system elapsed 
##   4.704   0.247   4.918 

这里我们有3个人(id),每个人都有不同的观察量。

我现在想要计算每个人的星期一,星期二等等。

这应该使用df <- data.frame(id= c(rep(1,5), rep(2,8), rep(3,7)), dates = seq.Date(as.Date("2015-01-01"), by="month", length=20)) dplyr来完成,因为我的真实数据集中有更多列,我用不同的统计信息进行汇总。

应该是这样的事情:

summarize

如何实现这一目标?

3 个答案:

答案 0 :(得分:4)

我会做以下事情:

summa <- count(df, id, day = weekdays(dates))

# or:
#    summa <- df %>% 
#      mutate(day = weekdays(dates)) %>% 
#      count(id, day)

head(summa)
#Source: local data frame [6 x 3]
#Groups: id [2]
#
#     id        day     n
#  (dbl)      (chr) (int)
#1     1 Donnerstag     1
#2     1    Freitag     1
#3     1   Mittwoch     1
#4     1    Sonntag     2
#5     2   Dienstag     2
#6     2 Donnerstag     1

但您也可以重塑为宽幅格式:

library(tidyr)
spread(summa, day, n, fill=0)
#Source: local data frame [3 x 8]
#Groups: id [3]
#
#     id Dienstag Donnerstag Freitag Mittwoch Montag Samstag Sonntag
#  (dbl)    (dbl)      (dbl)   (dbl)    (dbl)  (dbl)   (dbl)   (dbl)
#1     1        0          1       1        1      0       0       2
#2     2        2          1       1        1      1       1       1
#3     3        1          0       2        1      2       0       1

我的结果是德语,但你的语言当然是用你自己的语言。列名是德国工作日。

如果您想明确使用summarize,可以使用以下方法实现与上述相同:

summa <- df %>% 
  group_by(id, day = weekdays(dates)) %>% 
  summarize(n = n())  # or do something with summarise_each() for many columns

答案 1 :(得分:3)

您可以使用lubridate包:

library(lubridate)

summa <- df %>% group_by(id) %>%
    summarize(mondays = sum(wday(dates) == 2),
    ....

答案 2 :(得分:1)

基准日期功能:

'g'