根据条件仅筛选重复的行

Filter only duplicated rows based on condition

提问人:Larissa Cury 提问时间:5/22/2023 最后编辑:Larissa Cury 更新时间:5/22/2023 访问量:34

问:

在下面的数据中,我想根据他们对 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”行?我敢肯定这很容易做到,但我正在努力。我真的需要一种方法。tidyversetidyverse

重要提示:

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"))
R 数据帧 筛选器 Tidyverse 切片

评论


答:

1赞 ulfelder 5/22/2023 #1

听起来你更喜欢答案,但这里有一个使用拆分-操作-重新组合方法的基本 R 解决方案。你拆分 ;在具有多行的子集中,选择 “Plan” in 的行;然后用于将剩余的行重新组合在一起。tidyverseIDQ40do.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'!