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

tidyverse: removing rows from data frame on basis of values in other rows

我有一堆调查数据。每行代表一次采访 "respondent." 一些受访者被采访过一次;其他人接受了多次采访。我想select,从这个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)

其中

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

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

如果所有之前采访过的 ID 都列在第 3 和第 4 列,您可以使用 dplyr::anti_join 对数据框进行 left anti_join ],在这里你将 DATEPRIDPREV 分别与 YYYYMMID 匹配,只有来自 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