【问题标题】:tidyverse: removing rows from data frame on basis of values in other rowstidyverse:根据其他行中的值从数据框中删除行
【发布时间】:2018-03-11 21:17:35
【问题描述】:

我有一些调查数据。每行代表对“受访者”的采访。一些受访者接受了一次采访;其他人多次接受采访。我想从这个 tibble 中只选择每个受访者的最后一次采访。

这是一个最小的例子:

tmp <- tribble(
  ~YYYYMM, ~ID, ~DATEPR, ~IDPREV,
   198001,   1,      NA,      NA,
   198001,   2,      NA,      NA,
   198001,   3,      NA,      NA,
   198002,   1,      198001,   1,
   198002,   2,      NA,      NA,
   198002,   3,      NA,      NA,
   198003,   1,      198002,   1,
   198003,   2,      NA,      NA,
   198003,   3,      198002,   3)

在哪里

  • YYYYMM 是采访日期。

  • DATEPR 是受访者上次采访的日期(如果有的话)。

  • ID 仅在采访波中是唯一的。这意味着,例如,ID==2YYYMM==198001 的受访者不必是 ID==2YYYMM==198002 的受访者。

  • IDPREV 是受访者之前采访的 ID,如果有的话。

上面的小标题有九行。但一位受访者接受了 3 次采访,另一位受访者接受了两次采访。我只想要每个受访者的最后一次采访,所以我想要一个只有六行的小标题。这段代码完成了这项工作:

for (i in 1:nrow(tmp)) {
  if (!is.na(tmp$DATEPR[i])) {
    ind <- which(tmp$YYYYMM == tmp$DATEPR[i] & tmp$ID == tmp$IDPREV[i])
    tmp <- tmp[-ind, ]
  }
}

但它似乎有点难以解析。是否有更清晰的方法可以使用 tidyverse 功能达到相同的目的?我想到了一个两步功能:首先,获取要删除的所有行的索引;其次,删除行。但我无法使用mapdplyr 函数实现此解决方案。

【问题讨论】:

    标签: r dplyr tidyverse purrr


    【解决方案1】:

    如果之前采访的所有 ID 都列在第 3 列和第 4 列,您可以使用 dplyr::anti_join 对数据框进行 left anti_join,这里匹配 DATEPR 和 @987654323 @ 分别带有 YYYYMMID,只有来自 temp 且其 YYYYMMID 没有匹配的行将被留下:

    anti_join(tmp, tmp, by = c("YYYYMM" = "DATEPR", "ID" = "IDPREV")) %>% 
        arrange(YYYYMM, ID)
    
    # A tibble: 6 x 4
    #  YYYYMM    ID DATEPR IDPREV
    #   <dbl> <dbl>  <dbl>  <dbl>
    #1 198001     2     NA     NA
    #2 198001     3     NA     NA
    #3 198002     2     NA     NA
    #4 198003     1 198002      1
    #5 198003     2     NA     NA
    #6 198003     3 198002      3
    

    运行代码后:

    for (i in 1:nrow(tmp)) {
        if (!is.na(tmp$DATEPR[i])) {
            ind <- which(tmp$YYYYMM == tmp$DATEPR[i] & tmp$ID == tmp$IDPREV[i])
            tmp <- tmp[-ind, ]
        }
    }
    tmp %>% arrange(YYYYMM, ID)
    # A tibble: 6 x 4
    #  YYYYMM    ID DATEPR IDPREV
    #   <dbl> <dbl>  <dbl>  <dbl>
    #1 198001     2     NA     NA
    #2 198001     3     NA     NA
    #3 198002     2     NA     NA
    #4 198003     1 198002      1
    #5 198003     2     NA     NA
    #6 198003     3 198002      3
    

    【讨论】:

    • 谢谢。我没想过只用一个数据框使用anti_join
    猜你喜欢
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2021-08-09
    • 1970-01-01
    相关资源
    最近更新 更多