【问题标题】:Grouped tibbletime and using collapse_index, getting weird results分组 tibbletime 并使用 collapse_index,得到奇怪的结果
【发布时间】:2018-04-05 20:35:40
【问题描述】:

我有一个文件(大约 9K 条记录),我想先根据组进行聚合,然后再根据彼此相隔 7 天内的日期进行聚合。但是,我不明白为什么结果看起来像他们一样。我意识到还有其他方法可以通过这个特定的示例获得相同的结果,但它会变得更加复杂,并且还有其他原因我对使用 tibbletime 感兴趣。这是一个可重现的示例:

library(tidyverse)
library(lubridate)  
library(tibbletime) #devtools::install_github("business-science/tibbletime")

TEST_ROLL <- as_tibble(list(
CITY_ID = c("1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "2", 
"2", "2", "2"),
CAFE_ID = c("1001", "1001", "1001", "1001", "2002", "2002", "2002", "2002", 
"3003", "3003", "3003", "3003", "4004", "4004", "4005", "4005"),
HEALTH_REPORT_ID = c("1425", "1532", "1666", "1989", "2166", "2457", "2776", 
"2999", "3409", "3497", "3595", "3786", "4105", "4511", "4567", "4580"),
REPORT_SUBMIT_DATE = ymd( c( "2013-05-26", "2013-05-27", "2013-05-31", 
"2013-05-31", "2016-05-26", "2016-05-27", "2016-05-31", "2016-05-31", "2018- 
05-26", "2018-05-27", "2018-05-31", "2018-05-31", "2017-01-01", "2017-01- 
05", "2017-02-04", "2017-02-10"))))

我想要做的是,从每家咖啡馆的第一份报告开始,将彼此间隔 7 天内提交的健康报告计为一份报告,这样就不会被多计。

首先我尝试使用“7 天”作为期间:

TEST_ROLL %>% 
  group_by(CAFE_ID) %>% 
  as_tbl_time(REPORT_SUBMIT_DATE) %>% 
  mutate(ROLL_DATE = collapse_index(REPORT_SUBMIT_DATE, "7 day"))

# A time tibble: 16 x 5
# Index:  REPORT_SUBMIT_DATE
# Groups: CAFE_ID [5]
CITY_ID CAFE_ID HEALTH_REPORT_ID REPORT_SUBMIT_DATE ROLL_DATE 
<chr>   <chr>   <chr>            <date>             <date>    
 1 1       1001    1425             2013-05-26         2013-05-27
 2 1       1001    1532             2013-05-27         2013-05-27
 3 1       1001    1666             2013-05-31         2013-05-31
 4 1       1001    1989             2013-05-31         2013-05-31
 5 1       2002    2166             2016-05-26         2016-05-27
 6 1       2002    2457             2016-05-27         2016-05-27
 7 1       2002    2776             2016-05-31         2016-05-31
 8 1       2002    2999             2016-05-31         2016-05-31
 9 1       3003    3409             2018-05-26         2018-05-27
10 1       3003    3497             2018-05-27         2018-05-27
11 1       3003    3595             2018-05-31         2018-05-31
12 1       3003    3786             2018-05-31         2018-05-31
13 2       4004    4105             2017-01-01         2017-01-05
14 2       4004    4511             2017-01-05         2017-01-05
15 2       4005    4567             2017-02-04         2017-02-04
16 2       4005    4580             2017-02-10         2017-02-10

这不是我想要的。如果有效,cafe 1001 的所有四个报告将具有相同的滚动日期,因为它们都在 7 天内。那么为什么要在结果列中拆分成两个日期呢?

只是玩弄它,我尝试使用“每周”而不是“7天”,然后我得到了这个结果:

TEST_ROLL %>% 
  group_by(CAFE_ID) %>% 
  as_tbl_time(REPORT_SUBMIT_DATE) %>%
  mutate(ROLL_DATE = collapse_index(REPORT_SUBMIT_DATE, "weekly"))

# A time tibble: 16 x 5
# Index:  REPORT_SUBMIT_DATE
# Groups: CAFE_ID [5]
   CITY_ID CAFE_ID HEALTH_REPORT_ID REPORT_SUBMIT_DATE ROLL_DATE 
   <chr>   <chr>   <chr>            <date>             <date>    
 1 1       1001    1425             2013-05-26         2013-05-31
 2 1       1001    1532             2013-05-27         2013-05-31
 3 1       1001    1666             2013-05-31         2013-05-31
 4 1       1001    1989             2013-05-31         2013-05-31
 5 1       2002    2166             2016-05-26         2016-05-27
 6 1       2002    2457             2016-05-27         2016-05-27
 7 1       2002    2776             2016-05-31         2016-05-31
 8 1       2002    2999             2016-05-31         2016-05-31
 9 1       3003    3409             2018-05-26         2018-05-26
10 1       3003    3497             2018-05-27         2018-05-31
11 1       3003    3595             2018-05-31         2018-05-31
12 1       3003    3786             2018-05-31         2018-05-31
13 2       4004    4105             2017-01-01         2017-01-05
14 2       4004    4511             2017-01-05         2017-01-05
15 2       4005    4567             2017-02-04         2017-02-04
16 2       4005    4580             2017-02-10         2017-02-10

Cafe 1001 正是我想要的,但是 cafe 2002 和 3003 的日期相同(不同的年份),但结果却不同。

cafe 4004 是我想要的组合,但是cafe 4005 之间只有 6 天,所以这些也应该组合在一起。 (稍后我会总结/计数)

任何想法为什么会发生这种情况? 谢谢!!

【问题讨论】:

  • collapse_index(REPORT_SUBMIT_DATE, "weekly") 折叠属于从星期日开始的同一周的日期。恕我直言,不过,接受collapse_index 的默认行为比你想要实现的要容易得多。
  • 是的,我已经意识到为什么“每周”会这样,但有趣的是,使用“7 天”仍然没有得到我想要的结果。我实际上尝试了 8 天,这似乎适用于我更大的数据集,尽管我仍在检查案例。
  • 如果有帮助,请查看我的答案,@Knachman
  • 7 天很重要,我根本不在乎日历周。这是分析的第一步,然后我必须按日期分组并确定那些在第一个报告日期后 45 天内的报告,然后在报告日期之后作为结果,在报告日期之前作为之前的历史记录。
  • 我想知道这是否是因为 collapse_index 使用“开始日期”的方式,如果它是根据索引中的第一个日期计算每 7 天的时间段,这可能不适用于我我正在努力。

标签: r tidyverse lubridate tibble tibbletime


【解决方案1】:

我不知道你想要完成的事情是否是一个明智的选择。我认为使用collapse_index(REPORT_SUBMIT_DATE, "weekly") 的默认行为是明智的做法。

但是,如果您仍想继续尝试做的事情,这是一种方法。我认为您需要首先很好地了解哪些日子在 7 天内。

Date <- TEST_ROLL$REPORT_SUBMIT_DATE
truth_mat <- abs(sapply(Date, 'difftime', Date, unit = 'day')) < 7
indices <- which(truth_mat, arr.ind = TRUE)
as_tibble(indices) %>% group_by(row) %>%
  summarise_at(vars(col), paste, collapse = ', ')

# # A tibble: 16 x 2
#      row col          
#    <int> <chr>        
#  1     1 1, 2, 3, 4   
#  2     2 1, 2, 3, 4   
#  3     3 1, 2, 3, 4   
#  4     4 1, 2, 3, 4   
#  5     5 5, 6, 7, 8   
#  6     6 5, 6, 7, 8   
#  7     7 5, 6, 7, 8   
#  8     8 5, 6, 7, 8   
#  9     9 9, 10, 11, 12
# 10    10 9, 10, 11, 12
# 11    11 9, 10, 11, 12
# 12    12 9, 10, 11, 12
# 13    13 13, 14       
# 14    14 13, 14       
# 15    15 15, 16       
# 16    16 15, 16 

我们可以看到{1,2,3,4}{5,6,7,8}{9,10,11,12}{13,14}{15,16} 正在形成集群。让我们看看hclust 是否可以检测到这些集群。

hc <- hclust(dist(Date))
plot(hc)

在这里,我们可以看到我们可以将树分成五个分支,并且我们得到了所需的分组。我们看到树状图表明了我们迄今为止观察到的情况。走hclust 路线的好处是我们可以轻松地指定这些分组。

TEST_ROLL$Group <- cutree(hc, 5)

TEST_ROLL
# # A tibble: 16 x 5
#    CITY_ID CAFE_ID HEALTH_REPORT_ID REPORT_SUBMIT_DATE  Date
#    <chr>   <chr>   <chr>            <date>             <int>
#  1 1       1001    1425             2013-05-26             1
#  2 1       1001    1532             2013-05-27             1
#  3 1       1001    1666             2013-05-31             1
#  4 1       1001    1989             2013-05-31             1
#  5 1       2002    2166             2016-05-26             2
#  6 1       2002    2457             2016-05-27             2
#  7 1       2002    2776             2016-05-31             2
#  8 1       2002    2999             2016-05-31             2
#  9 1       3003    3409             2018-05-26             3
# 10 1       3003    3497             2018-05-27             3
# 11 1       3003    3595             2018-05-31             3
# 12 1       3003    3786             2018-05-31             3
# 13 2       4004    4105             2017-01-01             4
# 14 2       4004    4511             2017-01-05             4
# 15 2       4005    4567             2017-02-04             5
# 16 2       4005    4580             2017-02-10             5

注意hclust 使用method = 'complete' 作为默认欧几里得距离。您可以根据需要尝试其他方法。详情请查看?hclust

编辑

我刚刚意识到,您也可以通过这种方式直接使用truth_matindices 中的分组。

groups <- as_tibble(indices) %>% group_by(row) %>%
  summarise_at(vars(col), paste, collapse = ', ') 
TEST_ROLL$group <- groups$col

然后你可以group_bygroup 列而不需要hclust

【讨论】:

  • 是的,这就是问题所在——这是一个小例子,但我们经常对包含数十万条记录的文件执行此操作,所以我真正想要的是一个简单的(最好是整洁的)做这个日期滚动的方法。不过,我将使用 hclust 进行检查,看看是否可以使其正常工作。
  • 我刚刚意识到你可以使用上面truth_matindices找到的分组而不使用hclust
猜你喜欢
  • 2022-08-17
  • 1970-01-01
  • 2022-01-25
  • 2020-10-08
  • 1970-01-01
  • 2013-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多