【问题标题】:Loop through all entries in one dataframe to find matches based on date criteria in another dataframe in R循环遍历一个数据框中的所有条目,以根据 R 中另一个数据框中的日期条件查找匹配项
【发布时间】:2020-06-16 15:51:16
【问题描述】:

所以我有一个名为 df1 的数据框:

df1 <- structure(list(startTime = structure(c(1519903920, 1519905060, 
1519913740, 1519919880), class = c("POSIXct", "POSIXt"), tzone = "America/New_York"), 
    endTime = structure(c(1519904880, 1519912200, 1519913940, 
    1522142880), class = c("POSIXct", "POSIXt"), tzone = "America/New_York"), 
    impact = c(92.17, 616.43, 63.69, 14.69), impactPercent = c(184.15, 
    1495.17, 138.69, 19.97), impactSpeedDiff = c(3587.72, 25726.22, 
    2616.01, 474.11), maxQueueLength = c(5.76053, 5.76053, 4.829511, 
    2.447619), tmcs = list(c("110N04623", "110-04623", "110N04624", 
    "110-04624", "110N04625", "110-04625", "110N04626", "110-04626", 
    "110N04627"), c("110N04623", "110-04623", "110N04624", "110-04624", 
    "110N04625", "110-04625", "110N04626", "110-04626", "110N04627"
    ), c("110N04623", "110-04623", "110N04624", "110-04624", 
    "110N04625", "110-04625", "110N04626", "110-04626"), c("110N04623", 
    "110-04623", "110N04624", "110-04624", "110N04625")), early_startTime = structure(c(1519903620, 
    1519904760, 1519913740, 1522133400), class = c("POSIXct", 
    "POSIXt"), tzone = "America/New_York")), row.names = c(NA, 
4L), class = "data.frame")

鉴于此数据帧,我需要匹配以下数据帧 (df2)。

df2 <- structure(list(created_tstamp = structure(c(1519926899, 1519913840, 
1519913840, 1519927924, 1522141200, 1522152619, 1522152708, 1522152728, 
1519928416, 1519928785, 1519929080, 1519929306, 1519929964, 1519930050, 
1522154148, 1519930311, 1519930139, 1519930470, 1519930660, 1519929579
), class = c("POSIXct", "POSIXt"), tzone = "America/New_York"), 
    closed_tstamp = structure(c(1519929764, 1519926987, 1519927686, 
    1519928360, 1522152738, 1522152779, 1522154882, 1522152819, 
    1519928464, 1519928914, 1519929266, 1519929741, 1519939420, 
    1519930622, 1522155300, 1519930334, 1519931054, 1519951230, 
    1519930766, 1519930830), class = c("POSIXct", "POSIXt"), tzone = "America/New_York"), 
    code = c("110-04508", "110N04623", "110N04623", "110P05583", 
    "", "", "110N04485", "110N04357", "110-05066", "110-04421", 
    "110N04421", "110P04577", "110-04204", "110-04269", "110+04673", 
    "110-04445", "", "110P05797", "110N04269", "110+04520")), row.names = c(NA, 
20L), class = "data.frame")

匹配由两个条件共同表示:

  1. df2 中的 created_tstamp 介于 df1 中的 early_startTimeendTime 之间
  2. df2 中的 code 存在于 df1 中的同一 tmcs 单元格中

需要同时满足这两个条件才能被视为匹配。最终,我想创建一个标识符以将 df2 的每一行与其在 df1 中的对应匹配项匹配。这可能是通过某种循环完成的,但我不确定如何编写它。注意:这是数据的子集。

如果 df2 中的数据点与 df1 中的数据点不匹配,则它在标识符列中应为 NA。最后两个 df 都应该得到一个 ID 列。

【问题讨论】:

    标签: r loops datetime for-loop dplyr


    【解决方案1】:

    我相信这应该可行。很难说,因为它没有返回与提供的数据匹配的内容。这是因为没有一个created_tstamp 早于您的endTime

    编辑:现在我们已经与更新的问题匹配,我们可以按如下方式处理输出

    test <- apply(df2,1, function(x) which(
        x[1] > df1$early_startTime & 
        x[1] < df1$endTime &
        grepl(x[3], df1$tmcs) &
        x[3] != ""
        ))
    
    
    IDlist <- lapply(test,paste0,collapse=";")
    df2$ID <- unlist(ifelse(lengths(test) > 0,IDlist, NA))
    

    输出:

    > df2
            created_tstamp       closed_tstamp      code   ID
    1  2018-03-01 12:54:59 2018-03-01 13:42:44 110-04508 <NA>
    2  2018-03-01 09:17:20 2018-03-01 12:56:27 110N04623    2
    3  2018-03-01 09:17:20 2018-03-01 13:08:06 110N04623    2
    4  2018-03-01 13:12:04 2018-03-01 13:19:20 110P05583 <NA>
    5  2018-03-27 05:00:00 2018-03-27 08:12:18           <NA>
    6  2018-03-27 08:10:19 2018-03-27 08:12:59           <NA>
    7  2018-03-27 08:11:48 2018-03-27 08:48:02 110N04485 <NA>
    8  2018-03-27 08:12:08 2018-03-27 08:13:39 110N04357 <NA>
    9  2018-03-01 13:20:16 2018-03-01 13:21:04 110-05066 <NA>
    10 2018-03-01 13:26:25 2018-03-01 13:28:34 110-04421 <NA>
    11 2018-03-01 13:31:20 2018-03-01 13:34:26 110N04421 <NA>
    12 2018-03-01 13:35:06 2018-03-01 13:42:21 110P04577 <NA>
    13 2018-03-01 13:46:04 2018-03-01 16:23:40 110-04204 <NA>
    14 2018-03-01 13:47:30 2018-03-01 13:57:02 110-04269 <NA>
    15 2018-03-27 08:35:48 2018-03-27 08:55:00 110+04673 <NA>
    16 2018-03-01 13:51:51 2018-03-01 13:52:14 110-04445 <NA>
    17 2018-03-01 13:48:59 2018-03-01 14:04:14           <NA>
    18 2018-03-01 13:54:30 2018-03-01 19:40:30 110P05797 <NA>
    19 2018-03-01 13:57:40 2018-03-01 13:59:26 110N04269 <NA>
    20 2018-03-01 13:39:39 2018-03-01 14:00:30 110+04520 <NA>
    

    【讨论】:

    • 添加了一个编辑,所以实际上有一个匹配。这并不完全有效。我需要创建一个名为“ID”的新列,其中 df1 中的每一行都有一个 ID,然后将一个 ID 列添加到 df2,这是 df1 匹配时的匹配 ID,没有匹配时为 NA
    • 这样更近了!但是当扩展到实际数据时它不起作用,我认为这是因为你如何生成 ID。 ID 基本上是行号,因此我们得到一个错误。相反,它可以为每一行 (ID001) 创建一个字符 ID 并使用它来编写 df2$ID 吗?错误:$&lt;-.data.frame(*tmp*, ID, value = c(NA, NA, NA, NA, NA, 135L, 中的错误:替换有 10732 行,数据有 10728
    • 如果一行的匹配数超过 1,我的代码可能会遇到麻烦。如果是这样的话,你需要在unlist-ing之前决定如何处理
    • 是的,重复是真正的可能性。因此,如果 df2 中的多行与 df1 中的同一行匹配,则它们在 df2 中的 ID 列中应具有相同的 ID。
    猜你喜欢
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多