【问题标题】:Select rows based on multiple conditions from two independent database从两个独立的数据库中根据多个条件选择行
【发布时间】:2021-02-16 23:11:07
【问题描述】:

我有两个独立的两个数据集,一个包含事件日期。每个 ID 只有一个“Eventdate”。如下:

data1 <- data.frame("ID" = c(1,2,3,4,5,6), "Eventdate" = c("2019-01-01", "2019-02-01", "2019-03-01", "2019-04-01", "2019-05-01", "2019-06-01"))
data1
  ID  Eventdate
1  1 2019-01-01
2  2 2019-02-01
3  3 2019-03-01
4  4 2019-04-01
5  5 2019-05-01
6  6 2019-06-01

在另一个数据集中,一个 ID 有多个事件名称 (Eventcode) 及其事件日期 (Eventdate)。如下:

data2 <- data.frame("ID" = c(1,1,2,3,3,3,4,4,7), "Eventcode"=c(201,202,201,204,205,206,209,208,203),"Eventdate" = c("2019-01-01", "2019-01-01", "2019-02-11", "2019-02-15", "2019-03-01", "2019-03-15", "2019-03-10", "2019-03-20", "2019-06-02"))
data2
  ID Eventcode  Eventdate
1  1       201 2019-01-01
2  1       202 2019-01-01
3  2       201 2019-02-11
4  3       204 2019-02-15
5  3       205 2019-03-01
6  3       206 2019-03-15
7  4       209 2019-03-10
8  4       208 2019-03-20
9  7       203 2019-06-02

两个数据集通过 ID 链接。两个数据集的 ID 并不完全相同。 我想在data2中选择有条件的案例:

  1. 按 ID 匹配
  2. 数据 2 中的事件日期 >= 数据 1 中的事件日期。
  3. 如果一个ID在data2中有多个Eventdates,选择最早的一个。
  4. 如果一个ID在data2中的一个Eventdate有多个Eventcode,随机选择一个即可。

然后将选中的data2合并到data1中。

预期结果如下:

data1
  ID  Eventdate Eventdate.data2 Eventcode
1  1 2019-01-01      2019-01-01       201
2  2 2019-02-01      2019-02-11       201
3  3 2019-03-01      2019-03-01       205
4  4 2019-04-01                          
5  5 2019-05-01                          
6  6 2019-06-01 

data1
  ID  Eventdate Eventdate.data2 Eventcode
1  1 2019-01-01      2019-01-01       202
2  2 2019-02-01      2019-02-11       201
3  3 2019-03-01      2019-03-01       205
4  4 2019-04-01                          
5  5 2019-05-01                          
6  6 2019-06-01 

非常感谢!

【问题讨论】:

    标签: r date multiple-conditions


    【解决方案1】:

    你可以试试这个方法:

    library(dplyr)
    
    left_join(data1, data2, by = 'ID') %>%
      group_by(ID, Eventdate.x) %>%
      summarise(Eventdate = Eventdate.y[Eventdate.y >= Eventdate.x][1], 
                Eventcode = {
                  inds <- Eventdate.y >= Eventdate.x
                  val <- sum(inds, na.rm = TRUE)
                  if(val == 1) Eventcode[inds]
                  else if(val > 1) sample(Eventcode[inds], 1)
                  else NA_real_
                  })
    
    #    ID Eventdate.x Eventdate  Eventcode
    #  <dbl> <chr>       <chr>          <dbl>
    #1     1 2019-01-01  2019-01-01       201
    #2     2 2019-02-01  2019-02-11       201
    #3     3 2019-03-01  2019-03-01       205
    #4     4 2019-04-01  NA                NA
    #5     5 2019-05-01  NA                NA
    #6     6 2019-06-01  NA                NA
    

    Eventcode 数据中的复杂逻辑是为了随机性,如果您可以选择像Eventdate 这样的第一个值,您可以将其简化为:

    left_join(data1, data2, by = 'ID') %>%
      group_by(ID, Eventdate.x) %>%
      summarise(Eventdate = Eventdate.y[Eventdate.y >= Eventdate.x][1], 
                Eventcode = Eventcode[Eventdate.y >= Eventdate.x][1])
    

    【讨论】:

    • 非常感谢!你的方法很有帮助。我认为第二个对我来说已经足够了!
    【解决方案2】:

    这行得通吗:

    library(dplyr)
    data1 %>% rename(Eventdate_dat1 = Eventdate) %>% left_join(data2, by = 'ID') %>% 
    group_by(ID) %>% filter(Eventdate >= Eventdate_dat1) %>% 
    mutate(Eventdate = case_when(length(unique(Eventdate)) > 1 ~ min(Eventdate), TRUE ~ Eventdate),
    Eventcode = case_when(length(unique(Eventcode)) > 1 ~ min(Eventcode), TRUE ~ Eventcode)) %>% 
    distinct() %>% right_join(data1, by = 'ID') %>% select(ID, 'Eventdate' = Eventdate.y, 'Eventdate.data2' = Eventdate.x, Eventcode)
    # A tibble: 6 x 4
    # Groups:   ID [6]
         ID Eventdate  Eventdate.data2 Eventcode
      <dbl> <chr>      <chr>               <dbl>
    1     1 2019-01-01 2019-01-01            201
    2     2 2019-02-01 2019-02-11            201
    3     3 2019-03-01 2019-03-01            205
    4     4 2019-04-01 NA                     NA
    5     5 2019-05-01 NA                     NA
    6     6 2019-06-01 NA                     NA
    

    【讨论】:

    • 非常感谢!你的回答对我也有帮助!
    • @user13538376,如果您发现答案有用,您能否通过单击答案旁边的勾号来接受最有用的答案,或者为有用的答案投票。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    相关资源
    最近更新 更多