通过两组找到独特的计数

时间:2016-12-13 04:14:05

标签: r for-loop dplyr apply plyr

这是一个两部分问题:

首先,我有一组处理请求的用户。

User    Voucher Number  System Entry Date   Queue Entry Date    Queue Exit Date
user1   100004  8/11/2016 10:40 8/11/2016 10:40 8/11/2016 14:48
user2   100004  8/11/2016 10:40 8/11/2016 14:48 8/12/2016 16:11
user1   100004  8/11/2016 10:40 8/12/2016 16:11 8/18/2016 16:09
user3   100004  8/11/2016 10:40 8/18/2016 16:09 8/18/2016 16:11
user1   100004  8/11/2016 10:40 8/18/2016 16:11 10/12/2016 10:07
user2   100004  8/11/2016 10:40 10/12/2016 10:07    10/13/2016 13:34
user3   100004  8/11/2016 10:40 10/13/2016 14:57    10/13/2016 14:57
user4   1030003 8/18/2016 9:45  8/22/2016 16:02 8/24/2016 11:41
user2   1030003 8/18/2016 9:45  8/24/2016 11:41 8/29/2016 18:40
user1   1030003 8/18/2016 9:45  8/29/2016 18:40 8/29/2016 18:54
user1   1030003 8/18/2016 9:45  8/29/2016 18:54 8/29/2016 18:54

最终,我需要量化Queue Entry Date 每天处理的请求数量。问题是,有时请求被用户关闭并由同一用户重新打开。如最后两行所示。

如果"user""Queue Entry Date"与上一行相同,则第二个实例将被删除。

我开发了一个for循环来检查这个,但我有两个问题:

(1)循环非常慢,(2)说我有一个凭证,由同一个用户按顺序打开和关闭3次或更多次,我不完全确定程序如何处理这个。

最终我需要表格看起来像这样:

凭证数量将是根据“队列输入日期”处理的凭证数量

User    date    voucher count
user1   8/11/2016   3
user2   8/11/2016   2
user3   8/11/2016   2
user4   8/11/2016   0
user1   8/12/2016   1
user2   8/12/2016   1
user3   8/12/2016   0
user4   8/12/2016   1




df <- structure(list(User = structure(c(1L, 2L, 1L, 3L, 1L, 2L, 3L, 
4L, 2L, 1L, 1L), .Label = c("    user1", "    user2", "    user3", 
"    user4"), class = "factor"), Voucher.Number = c(100004L, 
100004L, 100004L, 100004L, 100004L, 100004L, 100004L, 1030003L, 
1030003L, 1030003L, 1030003L), System.Entry.Date = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), .Label = c("8/11/2016 10:40", 
"8/18/2016 9:45"), class = "factor"), Queue.Entry.Date = structure(c(3L, 
4L, 5L, 6L, 7L, 1L, 2L, 8L, 9L, 10L, 11L), .Label = c("10/12/2016 10:07", 
"10/13/2016 14:57", "8/11/2016 10:40", "8/11/2016 14:48", "8/12/2016 16:11", 
"8/18/2016 16:09", "8/18/2016 16:11", "8/22/2016 16:02", "8/24/2016 11:41", 
"8/29/2016 18:40", "8/29/2016 18:54"), class = "factor"), Queue.Exit.Date = structure(c(4L, 
5L, 6L, 7L, 1L, 2L, 3L, 8L, 9L, 10L, 10L), .Label = c("10/12/2016 10:07", 
"10/13/2016 13:34", "10/13/2016 14:57", "8/11/2016 14:48", "8/12/2016 16:11", 
"8/18/2016 16:09", "8/18/2016 16:11", "8/24/2016 11:41", "8/29/2016 18:40", 
"8/29/2016 18:54"), class = "factor")), .Names = c("User", "Voucher.Number", 
"System.Entry.Date", "Queue.Entry.Date", "Queue.Exit.Date"), class = "data.frame", row.names = c(NA, 
-11L))

这是我用于过滤的循环:

counter = 0
filtDf = data.frame()
for (elem in 1:nrow(df)){

  if (counter >0){
    curElementId <- df[counter,c(4,12)]
    prev <- df[elem,c(4,12)]
    if (curElementId[1,1] == prev[1,1] & curElementId[1,2] == prev[1,2]){
      filtDf <- rbind(filtDf,df[elem,])
    }
    else{
      filtDf <- rbind(filtDf,df[elem,])
    }
  }
  counter = counter + 1
}

然后使用以下内容创建频率表:

filtDf$date<- as.POSIXct(filtDf$Queue.Exit.Date,format="%d/%d/%Y %H:%M")
filtDf$date <- as.character( round(filtDf$date , "day" ) )

dd <- ddply( filtDf , .(Queue.Entry.Date,User) , summarise , Count = length(User) )

1 个答案:

答案 0 :(得分:1)

这应该有效。首先,它使用来自mdy_hm的{​​{1}}将所有日期列转换为实际的日期时间对象(我同意@ Frank上面的评论),然后按输入日期时间排序以确保它是为了。接下来,它使用lubrdidate来检查行是否与用户和条目日期的前一行匹配。请注意,它会为第一个条目提供lag,我们需要确保不排除该条目,因此我使用NA中的replace_na将第一个条目切换为{{ 1}}。然后,只保留未在过滤器中捕获的内容,并按日期tidyr保留。

FALSE

返回:

count

请注意,匹配您的示例输出,但您的示例输出与您发布的数据不匹配。所以,我不确定那里发生了什么。如果您想要取回0课程,可以使用df %>% mutate_at(vars(System.Entry.Date, Queue.Entry.Date, Queue.Exit.Date) , mdy_hm) %>% mutate(toFilt = (User == lag(User) & as.Date(Queue.Entry.Date) == lag(as.Date(Queue.Entry.Date)) ) ) %>% replace_na(replace = list(toFilt = FALSE)) %>% filter(!toFilt) %>% count(User, Date = as.Date(Queue.Entry.Date))

        User       Date     n
      <fctr>     <date> <int>
1      user1 2016-08-11     1
2      user1 2016-08-12     1
3      user1 2016-08-18     1
4      user1 2016-08-29     1
5      user2 2016-08-11     1
6      user2 2016-08-24     1
7      user2 2016-10-12     1
8      user3 2016-08-18     1
9      user3 2016-10-13     1
10     user4 2016-08-22     1

如果您不想包含您所在范围内的所有日期,请使用complete代替df %>% mutate_at(vars(System.Entry.Date, Queue.Entry.Date, Queue.Exit.Date) , mdy_hm) %>% arrange(Queue.Entry.Date) %>% mutate(toFilt = (User == lag(User) & as.Date(Queue.Entry.Date) == lag(as.Date(Queue.Entry.Date)) ) ) %>% replace_na(replace = list(toFilt = FALSE)) %>% filter(!toFilt) %>% count(User, Date = as.Date(Queue.Entry.Date)) %>% complete(User, Date = full_seq(Date, 1), fill = list(n = 0)) 功能。