我有一小部分调查数据。每一行代表一次对“受访者”的访谈。一些受访者接受过一次访谈;其他人多次接受采访。我想从这个小组中选择每个受访者的最后一次面试。
这是一个最小的例子:
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==2
和YYYMM==198001
无需成为ID==2
和YYYMM==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功能相同的结束?我想到了一个两步功能:首先,获取要删除的所有行的索引;第二,删除行。但我无法使用map
或dplyr
函数实现此解决方案。
答案 0 :(得分:2)
如果所有以前受访的ID都列在第3和第4列,您可以使用dplyr::anti_join
自行执行左侧anti_join 数据框,在此处匹配{{1} }和DATEPR
分别与IDPREV
和YYYYMM
一起,ID
只有temp
和YYYYMM
没有匹配的行留下:
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