【问题标题】:Matching values conditioned on overlapping Intervals and ID以重叠间隔和 ID 为条件的匹配值
【发布时间】:2018-03-30 20:17:38
【问题描述】:

我在操作以下数据结构时遇到困难:

属性数据框:

ID  Begin_A      End_A        Interval                         Value
5   2017-03-01   2017-03-10   2017-03-01 UTC--2017-03-10 UTC   Cat1
10  2017-12-01   2017-12-02   2017-12-01 UTC--2017-12-02 UTC   Cat2
5   2017-03-01   2017-03-03   2017-03-01 UTC--2017-03-03 UTC   Cat3
10  2017-12-05   2017-12-10   2017-12-05 UTC--2017-12-10 UTC   Cat4

预订数据框:

ID  Begin_A      End_A        Interval 
5   2017-03-03   2017-03-05   2017-03-03 UTC--2017-03-05 UTC
6   2017-05-03   2017-05-05   2017-05-03 UTC--2017-05-05 UTC
8   2017-03-03   2017-03-05   2017-03-03 UTC--2017-03-05 UTC
10  2017-12-05   2017-12-06   2017-12-05 UTC--2017-12-06 UTC

期望的结果框架(预订):

ID  Begin_A      End_A        Interval                        Attribute_value
5   2017-03-03   2017-03-05   2017-03-03 UTC--2017-03-05 UTC  Cat1,Cat3
6   2017-05-03   2017-05-05   2017-05-03 UTC--2017-05-05 UTC  NA
8   2017-03-03   2017-03-05   2017-03-03 UTC--2017-03-05 UTC  NA
10  2017-12-05   2017-12-06   2017-12-05 UTC--2017-12-06 UTC  Cat4

数据框代码:

library(lubridate)
# Attributes data frame:
date1 <- as.Date(c('2017-3-1','2017-12-1','2017-3-1','2017-12-5'))
date2 <- as.Date(c('2017-3-10','2017-12-2','2017-3-3','2017-12-10'))
attributes <- data.frame(matrix(NA,nrow=4, ncol = 5)) 
names(attributes) <- c("ID","Begin_A", "End_A", "Interval", "Value")
attributes$ID <- as.numeric(c(5,10,5,10))
attributes$Begin_A <-date1
attributes$End_A <-date2
attributes$Interval <-attributes$Begin_A %--% attributes$End_A
attributes$Value<- as.character(c("Cat1","Cat2","Cat3","Cat4"))

### Bookings data frame:

date1 <- as.Date(c('2017-3-3','2017-5-3','2017-3-3','2017-12-5'))
date2 <- as.Date(c('2017-3-5','2017-5-5','2017-3-5','2017-12-6'))
bookings <- data.frame(matrix(NA,nrow=4, ncol = 4)) 
names(bookings) <- c("ID","Begin_A", "End_A", "Interval")
bookings$ID <- as.numeric(c(5,6,8,10))
bookings$Begin_A <-date1
bookings$End_A <-date2
bookings$Interval <-bookings$Begin_A %--% bookings$End_A

达到我的结果框架的程序应该如下: 从预订中获取 ID,过滤属性 ID 与预订 ID 匹配的属性数据框的所有行。检查哪些具有匹配属性 ID 的行也具有重叠的时间间隔(来自 lubridate 的 int_overlaps)。然后从 Value 列中获取相应的值,并在 Attribute_value 列中打印它们中的每一个。

【问题讨论】:

    标签: r dataframe lubridate


    【解决方案1】:

    来自tidyverse的解决方案。

    library(tidyverse)
    
    attributes2 <- attributes %>%
      select(-Interval) %>%
      gather(Type, Date, ends_with("_A")) %>%
      select(-Type) %>%
      group_by(Value) %>%
      complete(Date = full_seq(Date, period = 1), ID) %>%
      ungroup()
    
    bookings2 <- bookings %>%
      select(-Interval) %>%
      gather(Type, Date, ends_with("_A")) %>%
      select(-Type) %>%
      group_by(ID) %>%
      complete(Date = full_seq(Date, period = 1)) %>%
      ungroup()
    
    bookings3 <- bookings2 %>%
      left_join(attributes2, by = c("ID", "Date")) %>%
      group_by(ID) %>%
      summarise(Attribute_value = toString(sort(unique(Value)))) %>%
      mutate(Attribute_value = ifelse(Attribute_value %in% "", NA, Attribute_value))
    
    bookings4 <- bookings %>% left_join(bookings3, by = "ID")
    bookings4
      ID    Begin_A      End_A                       Interval Attribute_value
    1  5 2017-03-03 2017-03-05 2017-03-03 UTC--2017-03-05 UTC      Cat1, Cat3
    2  6 2017-05-03 2017-05-05 2017-05-03 UTC--2017-05-05 UTC            <NA>
    3  8 2017-03-03 2017-03-05 2017-03-03 UTC--2017-03-05 UTC            <NA>
    4 10 2017-12-05 2017-12-06 2017-12-05 UTC--2017-12-06 UTC            Cat4
    

    【讨论】:

    • 非常感谢您的回答。在我的实际数据中,我在属性数据框中有很长的时间框架,这导致 R 似乎正在努力处理的非常大的数据框架。我拆分了我的数据框,但数据框仍然很大。如何修改“完成(日期 = full_seq(日期,周期 = 1),ID)%>%”,以便跳跃以月为单位而不是以天为单位?这可能有助于使我的数据框更小。
    • @JoshuaZecha 好问题。我现在没有答案,因为您提供的示例将间隔限制在同一个月,并且很难试验哪种方法可以实现一个月的跳跃。您可能想通过几个月的示例提出一个新问题。
    • 我听从了你的建议,在这里发布了一个新问题:stackoverflow.com/questions/46839455/…
    猜你喜欢
    • 2021-02-18
    • 2018-03-22
    • 2019-09-14
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 2017-06-09
    相关资源
    最近更新 更多