如何将跨多列的重复项转换为 R 中的 NA?

How can you convert duplicates across multiple columns to be NA in R?

我有一个数据集,我想将跨列的任何重复项转换为 NA。我找到了帮助仅在一列中查找重复项的答案,并且我找到了完全删除重复项的方法(例如,distinct())。相反,我有这个数据:

library(dpylr)
test <- tibble(job = c(1:6), 
               name = c("j", "j", "j", "c", "c", "c"),
               id = c(1, 1, 2, 1, 5, 1))

想要这样的结果:

library(dpylr)

answer <- tibble(job = c(1:6), 
                 id = c("j", NA, "j", "c", NA, "c"),
                  name = c(1, NA, 2, 1, NA, 5))

我已经尝试过使用 duplicated() 的解决方案,但它失败了:

#Attempted solution
library(dpylr)
test %>%
  mutate_at(vars(id, name), ~case_when(
    duplicated(id, name) ~ NA,
    TRUE ~ .
  ))

我更喜欢使用整洁的解决方案,但只要答案可以通过管道传输,我就可以灵活处理。

如果我们要转换为 NA,请创建一个列,其中包含具有 pasteunite 的所有列,然后创建包含 mutateacross 的列

library(dplyr)
library(tidyr)
test %>% 
  unite(full_nm, -job, remove = FALSE) %>% 
  mutate(across(-c(job, full_nm), ~ replace(.x, duplicated(full_nm), NA))) %>%
  select(-full_nm)

-输出

# A tibble: 6 × 3
    job name     id
  <int> <chr> <dbl>
1     1 j         1
2     2 <NA>     NA
3     3 j         2
4     4 c         1
5     5 c         5
6     6 <NA>     NA

我们可以创建一个 helper,然后使用 across:

ifelse 语句中识别重复项并用 NA 替换它们
library(dplyr)
test %>% 
  mutate(helper = paste(id, name)) %>% 
  mutate(across(c(name, id), ~ifelse(duplicated(helper), NA, .)), .keep="unused")

    job name     id
  <int> <chr> <dbl>
1     1 j         1
2     2 NA       NA
3     3 j         2
4     4 c         1
5     5 c         5
6     6 NA       NA