首页 文章

tidyverse:根据其他行中的值从数据框中删除行

提问于
浏览
1

我有一小部分调查数据 . 每一行代表一次对“受访者”的访谈 . 一些受访者接受过一次访谈;其他人多次接受采访 . 我想从这个小组中选择每个受访者的最后一次面试 .

这是一个最小的例子:

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,如果有的话 .

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

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 函数实现此解决方案 .

1 回答

  • 2

    如果所有以前受访的ID都列在第3列和第4列,则可以使用 dplyr::anti_join 对数据框执行左侧anti_join,此处分别匹配 DATEPRIDPREVYYYYMMID ,仅 tempYYYYMMID 将保留没有匹配项:

    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
    

相关问题