【问题标题】:Find Unique Counts By Two Groups按两组查找唯一计数
【发布时间】:2016-12-13 04:14:04
【问题描述】:

这是一个两部分的问题:

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

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) )

【问题讨论】:

  • 我不确定所需结果中的数字来自哪里,但我怀疑它类似于library(dplyr); df %&gt;% mutate_at(vars(contains('Date')), funs(as.Date(as.character(.), format = '%m/%d/%Y'))) %&gt;% count(User, Queue.Entry.Date)
  • 您的输出令人困惑? user4 的记录在哪里消失了?
  • @joel.wilson 是的,已经更新了
  • 您能解释一下您在 o/p 中的日期和计数列吗?是哪一天?我想如果你能帮助解释日期的 3 列,那么我可以更好地理解它。谢谢
  • 第一步:请注意 R 具有日期和日期时间格式,并在将日期时间作为字符串或因素发布之前使用它们(除非这是您主要困惑的问题......在这种情况下,这个问题应该是短得多)。

标签: r for-loop dplyr apply plyr


【解决方案1】:

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

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

请注意,这不与您的示例输出匹配,但您的示例输出与您发布的数据不匹配。所以,我不确定那里发生了什么。如果你想找回 0 类,可以使用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))

如果您不想包含范围内的所有日期,只需使用 Date 而不是 full_seq 函数。

【讨论】:

  • 非常感谢您的回答。你能告诉我“。”是怎么回事吗? in (funs(mdy_hm(.)) 有效吗?
  • . 代表感兴趣的列(由任何分组变量分隔)。在查看对您的帮助时,我被提醒 mutate_each 已被弃用,因此将更新为使用 mutate_at。 ?arrange 将向您展示函数 desc 进行降序排序(默认为升序),尽管 - 通常也可以正常工作,但似乎没有记录在案,因此应该避免使用。
  • 较新的版本似乎不起作用。它返回“UseMethod中的错误(“tbl_vars”):没有适用于“函数”类对象的“tbl_vars”方法”
  • df 是否有您的实际数据,还是因为您还没有将数据加载到 df 中而再次成为本机函数 df?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-20
  • 2022-11-15
  • 1970-01-01
  • 2015-03-07
  • 2022-07-20
相关资源
最近更新 更多