tidyverse:根据其他行

时间:2017-09-29 22:38:15

标签: r dplyr tidyverse purrr

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

这是一个最小的例子:

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 个答案:

答案 0 :(得分:2)

如果所有以前受访的ID都列在第3和第4列,您可以使用dplyr::anti_join自行执行左侧anti_join 数据框,在此处匹配{{1} }和DATEPR分别与IDPREVYYYYMM一起,ID只有tempYYYYMM没有匹配的行留下:

ID

运行代码后:

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