【问题标题】:How to "grepl" conditional on a range of dates in R如何“grepl”以R中的日期范围为条件
【发布时间】:2022-10-04 22:26:47
【问题描述】:

假设我有两个数据框df1df2


df1 = structure(list(surname = c("Duisenberg", "Trichet", "Draghi"), 
    `start term` = structure(c(896659200, 1067644800, 1320105600
    ), class = c("POSIXct", "POSIXt"), tzone = "UTC"), `end term` = structure(c(1067558400, 
    1320019200, 1572480000), class = c("POSIXct", "POSIXt"), tzone = "UTC")), row.names = c(1L, 
9L, 15L), class = "data.frame") %>% data.frame(stringsAsFactors = F)

   surname start.term   end.term
1  Duisenberg 1998-06-01 2003-10-31
9     Trichet 2003-11-01 2011-10-31
15     Draghi 2011-11-01 2019-10-31


df2= data.frame(Date = c("2010-01-01","1997-01-01","2020-01-01","2004-01-01","2012-01-01","1999-01-01","2000-01-01","2020-01-01","2022-01-01","1996-01-01"), speaker = c("Mario Draghi","W.L. Duisenberg","Ciao","Jean-Claude Trichet","M. Draghi","W.L. Duisenberg","Jean-Claude Trichet","Bye","Ciao","Mario Draghi"), stringsAsFactors = F)

         Date             speaker
1  2010-01-01        Mario Draghi
2  1997-01-01     W.L. Duisenberg
3  2020-01-01                Ciao
4  2004-01-01 Jean-Claude Trichet
5  2012-01-01           M. Draghi
6  1999-01-01     W.L. Duisenberg
7  2000-01-01 Jean-Claude Trichet
8  2020-01-01                 Bye
9  2022-01-01                Ciao
10 1996-01-01        Mario Draghi

df1 中的名称出现在df2 中时,我可以很容易地找到:

which(grepl(paste0(df1$surname, collapse = "|"), df2$speaker, ignore.case = TRUE))

[1]  1  2  4  5  6  7 10

相反,更棘手的是:只有当df2 中的日期超出df1 的边界(start.termend.term)时,df1 中的名称才会出现在df2 中。

结果应该是:

[1] 1 2 10

我该怎么做?有人可以帮我弄这个吗?

谢谢!

【问题讨论】:

    标签: r dataframe for-loop if-statement


    【解决方案1】:

    我认为基本上你想在这里对匹配的名称进行连接操作。所以第一步是找出那些是什么:

    library(dplyr)
    
    surnames_regex <- paste0(df1$surname, collapse = "|")
    
    df2$matching_name <- strsplit(df2$speaker, split = "\s") |>
        lapply(
            (name) {
                matching_name <- grep(surnames_regex, name, v = T)
                matching_name <- ifelse(
                    length(matching_name) > 0,
                    matching_name[1],
                    NA_character_
                )
                matching_name
            }
        ) |>
        unlist()
    
    
    df2
    #          Date             speaker matching_name
    # 1  2010-01-01        Mario Draghi        Draghi
    # 2  1997-01-01     W.L. Duisenberg    Duisenberg
    # 3  2020-01-01                Ciao          <NA>
    # 4  2004-01-01 Jean-Claude Trichet       Trichet
    # 5  2012-01-01           M. Draghi        Draghi
    # 6  1999-01-01     W.L. Duisenberg    Duisenberg
    # 7  2000-01-01 Jean-Claude Trichet       Trichet
    # 8  2020-01-01                 Bye          <NA>
    # 9  2022-01-01                Ciao          <NA>
    # 10 1996-01-01        Mario Draghi        Draghi
    

    然后,这只是加入这些名称并根据您定义的条件进行过滤的情况:

    df2 |>
        inner_join(
            df1,
            by = c("matching_name" = "surname")
        ) |>
        filter(
            Date < start.term |
                Date > end.term
        )
    #         Date             speaker matching_name start.term   end.term
    # 1 2010-01-01        Mario Draghi        Draghi 2011-11-01 2019-10-31
    # 2 1997-01-01     W.L. Duisenberg    Duisenberg 1998-06-01 2003-10-31
    # 3 2000-01-01 Jean-Claude Trichet       Trichet 2003-11-01 2011-10-31
    # 4 1996-01-01        Mario Draghi        Draghi 2011-11-01 2019-10-31
    

    【讨论】:

      猜你喜欢
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-13
      • 2015-08-24
      相关资源
      最近更新 更多