在 R 中识别字符向量列表中的重复项

4

我有一个类似这样的字符向量列表:

my_list <- list(c('a','b','c','d','e'),c('e','f','g'),c('h','i','j'))
names(my_list) <- c("group1","group2","group3")

我希望有一种简单的方法来测试 my_list 中在我的列表中的任何3组/向量中是否存在重复字母。例如,"e" 在第1组和第2组中都出现了,所以这是一个重复项。只需返回逻辑值,即在2个或更多组中是否至少存在一个重复项,这将是最理想的情况。因此,FALSE 返回将意味着每个组中的字母仅对该组唯一(在我的示例中显然不是这种情况)。
非常感谢!
4个回答

6
可以通过以下方式生成二进制输出:
any(duplicated(unlist(my_list)))
[1] TRUE

正如@sindri_baldur在评论中正确指出的,如果组内有重复项,则应使用unique进行处理(如果需要):

any(duplicated(unlist(lapply(my_list, unique))))
[1] TRUE

或者使用另一个 基于 R 语言的 替代方案

anyDuplicated(unlist(lapply(my_list, unique))) > 1
[1] TRUE

1
anyDuplicated(unlist(my_list)) > 0 应该更有效率。如果向量内允许重复,你需要使用 lapply(my_list, unique) 开始处理。 - s_baldur
@sindri_baldur 确实,如果需要的话,我们应该保证组内唯一性!将其作为选项提供,谢谢! - Andre Wildberg
谢谢你们两个!还有@Andre Wildberg,我很感激你的逻辑输出。这对我编写需要if语句的代码非常有帮助。 - beanboy

5

你可以这样做:

subset(stack(my_list), duplicated(values))$values
[1] "e"

如果您需要确定一组中的所有值是否唯一,您可以执行以下操作:

result <- setNames(logical(length(my_list)), names(my_list))

result[unique(unlist(Filter(\(x)length(x)>1,
                            unstack(rev(stack(my_list))))))] <- TRUE
result
group1 group2 group3 
  TRUE   TRUE  FALSE 

甚至可能是:
stack(my_list) %>%
  mutate(dups = duplicated(values) | duplicated(values, f = T)) %>%
  group_by(ind) %>%
  summarise(logic = any(dups))

# A tibble: 3 x 2
  ind    logic
  <fct>  <lgl>
1 group1 TRUE 
2 group2 TRUE 
3 group3 FALSE

使用 dplyrstack(my_list) %>% filter(duplicated(values)) %>% select(values) - Ruam Pimentel
谢谢 @Onyambu!我也正在使用它来报告重复的特定值。 - beanboy
你也可以写成 dups = values %in% values[duplicated(values)],这样可以处理超过2个重复值的情况。 - Dan Chaltiel

2
我们可以将命名列表stack到一个两列的数据框中,使用table获取频率计数,通过在逻辑向量上使用colSums检查列是否有重复,并返回出现超过1次的names
names(which(colSums(table(stack(my_list)[2:1])> 0) > 1))
[1] "e"

或者稍微更紧凑一些

 names(which(table(unlist(my_list)) > 1))
[1] "e"

如果我们想要一个逻辑列
library(dplyr)
library(tidyr)
library(tibble)
enframe(my_list) %>%
   unnest(value) %>% 
  group_by(value) %>%
   mutate(flag = any(n_distinct(name) > 1)) %>% 
 group_by(name) %>% 
  summarise(flag = any(flag))

-输出

# A tibble: 3 × 2
  name   flag 
  <chr>  <lgl>
1 group1 TRUE 
2 group2 TRUE 
3 group3 FALSE

0
另一个可能的解决方案,基于tidyr :: expand_gridpurrr :: pmap_lgl
library(tidyverse)

my_list <- list(c('a','b','c','d','e'),c('e','f','g'),c('h','i','j'))
names(my_list) <- c("group1","group2","group3")

expandg <- expand_grid(names(my_list), names(my_list))

pmap_lgl(expandg, ~ any(my_list[[.x]] %in% my_list[[.y]])) %>% 
  bind_cols(id1 = expandg[[1]], id2 = expandg[[2]], value = .) %>% 
  group_by(Group = id1) %>% summarise(value = any(value[id1 != id2]))

#> # A tibble: 3 × 2
#>   Group  value
#>   <chr>  <lgl>
#> 1 group1 TRUE 
#> 2 group2 TRUE 
#> 3 group3 FALSE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接