【问题标题】:Filter rows with a time value that falls within several ranges过滤时间值在多个范围内的行
【发布时间】:2021-07-18 01:37:19
【问题描述】:

我想知道是否有人可以帮我解决这个问题。

我的一个朋友正在处理当时间值落入多个范围时需要过滤的生态数据。假设我们有一个包含 3 列的数据框:

ID TIME SPECIES
01 22:45:43 sp1
02 22:46:22 sp2
03 23:21:11 sp3
04 23:32:31 sp1
05 00:11:37 sp2
06 01:48:56 sp4
07 02:36:22 sp1

我们只想选择时间值在另一个数据框中指定的几个时间范围内的那些行:

ID START TIME END TIME
01 22:00:00 23:00:00
02 00:00:00 01:00:00

在上面的示例中,这将导致行 ID 为 1,2 和 5。

有没有办法在不手动指定范围的情况下做到这一点?

提前非常感谢! 抢

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以使用fuzzy_inner_join 获取范围内的行。我们将时间值转换为 POSIXct 类型,以便我们可以比较时间。

    library(dplyr)
    library(fuzzyjoin)
    
    df1 %>%
      mutate(TIME = as.POSIXct(TIME, format = '%T', tz = 'UTC')) %>%
      fuzzy_inner_join(df2 %>%
      mutate(across(c(START.TIME, END.TIME), 
              as.POSIXct, format = '%T', tz = 'UTC')), 
      by = c('TIME' = 'START.TIME', 'TIME' = 'END.TIME'), 
      match_fun = c(`>=`, `<=`)) %>%
      select(ID = ID.x, everything(), -ID.y) %>%
      mutate(across(ends_with('TIME'), format, '%T'))
    
    #  ID     TIME SPECIES START.TIME END.TIME
    #1  1 22:45:43     sp1   22:00:00 23:00:00
    #2  2 22:46:22     sp2   22:00:00 23:00:00
    #3  5 00:11:37     sp2   00:00:00 01:00:00
    

    数据

    df1 <- structure(list(ID = 1:7, TIME = c("22:45:43", "22:46:22", "23:21:11", 
    "23:32:31", "00:11:37", "01:48:56", "02:36:22"), SPECIES = c("sp1", 
    "sp2", "sp3", "sp1", "sp2", "sp4", "sp1")), row.names = c(NA, 
    -7L), class = "data.frame")
    
    df2 <- structure(list(ID = 1:2, START.TIME = c("22:00:00", "00:00:00"
    ), END.TIME = c("23:00:00", "01:00:00")), row.names = c(NA, -2L
    ), class = "data.frame")
    

    【讨论】:

      【解决方案2】:

      这可以使用%inrange% 运算符解决:

      library(data.table)
      setDT(df1)[as.ITime(TIME) %inrange% lapply(setDT(df2)[, -1], as.ITime)]
      
         ID     TIME SPECIES
      1:  1 22:45:43     sp1
      2:  2 22:46:22     sp2
      3:  5 00:11:37     sp2
      

      请注意,时间戳被as.ITime() 强制转换为 的整数时间类。

      数据

      df1 <- readr::read_table(
      "ID  TIME        SPECIES
      01  22:45:43    sp1
      02  22:46:22    sp2
      03  23:21:11    sp3
      04  23:32:31    sp1
      05  00:11:37    sp2
      06  01:48:56    sp4
      07  02:36:22    sp1")
      df2 <- readr::read_table(
      "ID START TIME  END TIME
      01  22:00:00    23:00:00
      02  00:00:00    01:00:00")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-07
        • 1970-01-01
        • 2020-08-24
        • 2017-10-30
        • 1970-01-01
        • 2015-04-10
        • 1970-01-01
        • 2019-03-29
        相关资源
        最近更新 更多