[英]tidyverse: removing rows from data frame on basis of values in other rows
我有一些調查數據。 每行代表對“受訪者”的采訪。 一些受訪者接受了一次采訪。 其他人被多次采訪。 我想從這個小標題中選擇每個受訪者的最后一次采訪。
這是一個最小的示例:
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(如果有的話)。
上面的小標題中有九行。 但是一位受訪者接受了三次采訪,另一位受訪者被了兩次采訪。 我只希望每位受訪者進行最后一次面試,所以我只希望排成六列。 這段代碼完成了這項工作:
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
函數實現此解決方案。
如果所有先前訪問的ID都列在第3列和第4列,則可以使用dplyr::anti_join
自身進行數據框的左anti_join ,在這里,您分別將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
運行代碼后:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.