dplyr 中是否有“unfilter”来将更改与原始数据集合并?

Par*_*gue 6 r dplyr

假设我有两个 data.frame,如下所示:

bad_ids = read.table(text="id n
123 3", header = T)

dat <- read.table(text="id n partner_id
123 3 555
123 3 345
123 3 092
245 1 438
888 1 333", header=T)
Run Code Online (Sandbox Code Playgroud)

我想确定dat与 id 列匹配的所有行bad_ids. 然后我想创建一个“标志”变量,该变量对于除第一个匹配项之外的所有项都设置为 1。结果 data.frame 看起来像:

dat <- read.table(text="id n partner_id flag 
123 3 555 0
123 3 345 1
123 3 092 1
245 1 438 0
888 1 333 0", header=T)
Run Code Online (Sandbox Code Playgroud)

请注意,第一行的123标志为0。我想标记除第一场比赛之外的所有比赛。

我模仿这种行为的策略如下:

# Flag the Duplicate Rows
dat %>% 
  filter(id %in% bad_ids$id) %>%
  slice(-1) %>% # delete the first row
  mutate(flag = 1) #create the id on all but the first match %>%
  unfilter() # this is the function I want to go back to the original, unfiltered dataset
Run Code Online (Sandbox Code Playgroud)

我想知道是否有一些等效的“unfilter”可以让我与原始数据集重新合并?

akr*_*run 3

一种选择是通过比较“bad_ids”“id”列来创建“标志”作为逻辑向量%in%,然后按“id”分组,通过创建另一个条件来更改“标志”row_number()

library(dplyr)
dat %>% 
   mutate(flag = id %in% bad_ids$id) %>% 
   group_by(id) %>% 
   mutate(flag = +(row_number() > 1 & flag))
   #or use `duplicated`
   # mutate(flag = +(duplicated(flag) & flag))
# A tibble: 5 x 4
# Groups:   id [3]
#     id     n partner_id  flag
#  <int> <int>      <int> <int>
#1   123     3        555     0
#2   123     3        345     1
#3   123     3         92     1
#4   245     1        438     0
#5   888     1        333     0
Run Code Online (Sandbox Code Playgroud)

另外,如果我们使用OP代码中的方法,一个选项是加入然后NA用0替换

dat %>% 
  filter(id %in% bad_ids$id) %>%
  slice(-1) %>%
  mutate(flag = 1) %>% 
  right_join(dat) %>% 
  mutate(flag = replace_na(flag, 0))
Run Code Online (Sandbox Code Playgroud)