【问题标题】:How to find duplicate records within the same timeperiod in R如何在R中查找同一时间​​段内的重复记录
【发布时间】:2020-09-25 09:05:16
【问题描述】:

我正在尝试在 R 中的行为数据数据框中查找重复记录。我需要根据多个列查找具有相同值且已在同一小时内记录的行。

例如:下面的第 1-2 行和第 3-4 行在 Date、Observer 和 FocalID 列中具有相同的值,并且是在同一小时内记录的。

    N  Date         Time        Observer   FocalID 
    1  20180520     07:05:00    VR         JK
    2  20180520     07:50:00    VR         JK
    3  20180521     07:50:00    JD         CJD
    4  20180521     08:25:00    JD         CJD

我已经尝试了以下代码,但它不起作用。一个原因是 find_duplicates(hablar 包)不接受间隔,而只接受数据框列。

Time <- as.POSIXct (df$Time, format="%H:%M:%S")
span60 <- (Time - minutes(60)) %--% (Time + minutes(60))
df %>% find_duplicates (Date, Observer, FocalID, Time %within% span60)

非常欢迎任何形式的帮助!谢谢!

【问题讨论】:

    标签: r time duplicates


    【解决方案1】:

    不确定您的预期输出是什么。这是一种为每个“重复项”提供唯一 ID 的方法。

    library(dplyr)
    
    df %>%
      tidyr::unite(DateTime, Date, Time, sep = " ") %>%
      mutate(DateTime = lubridate::ymd_hms(DateTime)) %>%
      group_by(Observer, FocalID) %>%
      mutate(grp = floor(difftime(DateTime, first(DateTime), units = 'hour'))) %>%
      group_by(grp, .add = TRUE) %>%
      mutate(ID = cur_group_id()) %>%
      ungroup() %>%
      select(-grp)
      
    # A tibble: 4 x 5
    #      N DateTime            Observer FocalID    ID
    #  <int> <dttm>              <chr>    <chr>   <int>
    #1     1 2018-05-20 07:05:00 VR       JK          2
    #2     2 2018-05-20 07:50:00 VR       JK          2
    #3     3 2018-05-21 07:50:00 JD       CJD         1
    #4     4 2018-05-21 08:25:00 JD       CJD         1
    

    具有相似 ID 的所有行都可以视为一个组的一部分。

    数据

    df <- structure(list(N = 1:4, Date = c(20180520L, 20180520L, 20180521L, 
    20180521L), Time = c("07:05:00", "07:50:00", "07:50:00", "08:25:00"
    ), Observer = c("VR", "VR", "JD", "JD"), FocalID = c("JK", "JK", 
    "CJD", "CJD")), class = "data.frame", row.names = c(NA, -4L))
    

    【讨论】:

    • 这有点骇人听闻,因为它完全依赖于第一个观察到的时间戳,而且我认为它仅适用于作为示例发布的有限行。此外,您在日期边界上很难切割,这是一个很难假设。我认为对于每一行,±60 分钟窗口内的 任何 其他行都可能是重复的候选...跨度>
    • 谢谢!我已经尝试过了,效果很好!看起来它适用于整个数据框,而不仅仅是作为示例发布的行。
    【解决方案2】:

    我理解您的问题是试图在 ObserverFocalID 中查找任何具有重复值的行,而这些行之间的时间间隔在 60 分钟内。
    以下解决方案适用于跨日期边界:

    library(dplyr)
    library(purrr)
    library(lubridate)
    
    df2 <- df %>%
      group_by(Observer, FocalID) %>%
      mutate(
        dt = as_datetime(paste(Date, Time), tz = "UTC"),
        dt_frame = interval(dt - minutes(60), dt + minutes(60), "UTC"),
        which_duplicates = map(dt_frame, ~N[which(dt %within% .x)], N = N, dt = dt),
        has_duplicates = map_lgl(which_duplicates, ~length(.x) > 1)
      )
    

    如果您不希望这将整个午夜的观察结果分组并将几天分开,只需将 Date 添加到 group_by 语句即可。

    【讨论】:

    • 谢谢!我试过这个,但它说它找不到“地图”功能。正如你所说,我已经加载了 dplyr 和 lubridate。
    • 哦,对不起,我忘记了地图需要purrr 库。我会在上面添加它。感谢您强调
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多