提问人:Larissa Cury 提问时间:5/22/2023 最后编辑:Larissa Cury 更新时间:5/22/2023 访问量:34
根据条件仅筛选重复的行
Filter only duplicated rows based on condition
问:
在下面的数据中,我想根据他们对 Q40 的回答过滤重复的参与者(Ana、Paul)。参与者应该只回答“无计划”或“计划”,但有时他们同时回答了两者。我只想保留每个重复参与者回答“计划”的行
- 数据为:
ID Q40
<chr> <chr>
1 Maria Plan
2 Joseph Plan
3 Cyntia NoPlan
4 Ana NoPlan ## first noPlan
5 Paul Plan ## first Plan
6 Ana Plan ## then, Plan
7 Paul NoPlan ## then, noPlan
- 期望输出:
ID Q40
<chr> <chr>
1 Maria Plan
2 Joseph Plan
3 Cyntia NoPlan
5 Paul Plan
6 Ana Plan
- 我是手动完成的,就像这样:
df %>%
filter(Q40 %in% c('noPlan', 'Plan')) %>%
ungroup() %>%
distinct()
then I was removing manually the duplicated ones with (slice()) and their corresponding position.
问题
1:我怎样才能只删除 ID 中重复参与者(同时回答“noPlan”和“plan”)的行,只保留他们的“Plan”行?我敢肯定这很容易做到,但我正在努力。我真的需要一种方法。tidyverse
tidyverse
重要提示:
1 我不想过滤所有“NoPlan”行,我只想过滤同时回答了 NoPlan 和 Plan 的参与者的“Plan”行。只有重复的,而不是整个样本。
2 我不想只保留第一行,例如 ,我希望能够自己设置条件(在这种情况下,从重复的参与者中过滤“NoPlan”distinc()
3 我不能使用,因为这会从所有参与者中删除“NoPlan”,我只需要过滤重复的参与者distinct(starwars, pick(contains("color")))
- 数据:
structure(list(ID = c("Joseph", "Cyntia", "Paul", "Ana", "Paul",
"Maria", "Ana"), Q40 = c("Plan", "NoPlan", "Plan", "Plan", "NoPlan",
"Plan", "NoPlan")), row.names = c(NA, -7L), class = c("tbl_df",
"tbl", "data.frame"))
答:
1赞
ulfelder
5/22/2023
#1
听起来你更喜欢答案,但这里有一个使用拆分-操作-重新组合方法的基本 R 解决方案。你拆分 ;在具有多行的子集中,选择 “Plan” in 的行;然后用于将剩余的行重新组合在一起。tidyverse
ID
Q40
do.call("rbind", ...)
dat <- structure(list(ID = c("Joseph", "Cyntia", "Paul", "Ana", "Paul",
"Maria", "Ana"), Q40 = c("Plan", "NoPlan", "Plan", "Plan", "NoPlan",
"Plan", "NoPlan")), row.names = c(NA, -7L), class = c("tbl_df",
"tbl", "data.frame"))
do.call("rbind", lapply(split(dat, dat$ID), function(x) {
if(nrow(x) > 1) {
x[x$Q40 == "Plan",]
} else {
x
}
}))
这是由此产生的:
ID Q40
* <chr> <chr>
1 Ana Plan
2 Cyntia NoPlan
3 Joseph Plan
4 Maria Plan
5 Paul Plan
评论
0赞
Larissa Cury
5/22/2023
谢谢你,@ulfelder!是的,我真的需要一种方法来处理更大的数据集,你有什么想法吗?tidyverse
2赞
IRTFM
5/22/2023
没有理由让 tidyverse 解决方案比基于大数据做得更好。
2赞
thelatemail
5/22/2023
#2
?duplicated
应该在这里帮助你:
dat %>%
filter(!((duplicated(ID) | duplicated(ID, fromLast=TRUE)) & Q40 == "NoPlan"))
或者用基本的 R 说话:
dat[with(dat, !((duplicated(ID) | duplicated(ID, fromLast=TRUE)) & Q40 == "NoPlan")),]
评论
0赞
Larissa Cury
5/22/2023
谢谢你,@thelatemail!你能解释一下里面的逻辑吗?顺便说一句,我收到此警告:由 : 中的警告引起!较长的对象长度不是较短对象长度的倍数filter()
(duplicated(ID) | duplicated(ID, fromLast = TRUE)) & Q40 == "semPlanejamento"
0赞
thelatemail
5/22/2023
逻辑是:使用两个语句查找所有重复的记录,以便标记所有具有重复的记录,而不仅仅是第一条记录。然后还要寻找那些记录。最后删除这些记录。该警告不应发生。它与你提供的示例数据不符,并表明你可能会在实际数据集中得到错误的结果。我会仔细检查你是否引用了正确的变量。duplicated
'Noplan'
!
评论