Как найти общие элементы среди столбцов разного размера в R?

#r #duplicates #identify

Вопрос:

У меня есть фрейм данных под названием animals , содержащий столбцы разного размера, которые имеют некоторые общие и необычные элементы друг между другом, как показано ниже:

 Dog     Cat      Lion     Dog
Cat     Lion     Dog      Shark
Lion    Dog      Shark    Cat
Shark   Shark    Cat      Lion
        Whale    Seal     Moose
        Seal              Whale
                          Deer
 

Что я хочу сделать, так это определить все общие элементы в каждом столбце, исключить необычные элементы и объединить общие элементы в один столбец, как это:

 Dog
Cat
Lion
Shark
 

До сих пор я пытался идентифицировать дублированные элементы с помощью duplicated(animals) , а затем извлечь дублированные элементы с помощью animals[duplicated(animals)] , но это не дает никаких результатов. У кого-нибудь есть лучший метод?

Ответ №1:

Мы можем использовать intersect

 Reduce(intersect, animals)
#[1] "Dog"   "Cat"   "Lion"  "Shark"
 

Или может использовать tidyverse

 library(dplyr)
library(tidyr)
pivot_longer(animals, cols = everything(), values_drop_na = TRUE) %>% 
     group_by(value) %>% 
     filter(n_distinct(name) == ncol(animals)) %>% 
     ungroup %>% 
     distinct(value)
# A tibble: 4 x 1
#  value
#  <chr>
#1 Dog  
#2 Cat  
#3 Lion 
#4 Shark
 

данные

 animals <- structure(list(v1 = c("Dog", "Cat", "Lion", "Shark", NA, NA, 
NA), v2 = c("Cat", "Lion", "Dog", "Shark", "Whale", "Seal", NA
), v3 = c("Lion", "Dog", "Shark", "Cat", "Seal", NA, NA), v4 = c("Dog", 
"Shark", "Cat", "Lion", "Moose", "Whale", "Deer")), 
    class = "data.frame", row.names = c(NA, 
-7L))
 

Ответ №2:

Еще один базовый вариант R с использованием stack table rowSums

 > names(which(rowSums(table(na.omit(stack(animals)))) == ncol(animals)))
[1] "Cat"   "Dog"   "Lion"  "Shark"
 

Ниже мы разбиваем код на этапы

 > stack(animals)
   values ind
1     Dog  v1
2     Cat  v1
3    Lion  v1
4   Shark  v1
5    <NA>  v1
6    <NA>  v1
7    <NA>  v1
8     Cat  v2
9    Lion  v2
10    Dog  v2
11  Shark  v2
12  Whale  v2
13   Seal  v2
14   <NA>  v2
15   Lion  v3
16    Dog  v3
17  Shark  v3
18    Cat  v3
19   Seal  v3
20   <NA>  v3
21   <NA>  v3
22    Dog  v4
23  Shark  v4
24    Cat  v4
25   Lion  v4
26  Moose  v4
27  Whale  v4
28   Deer  v4

> na.omit(stack(animals))
   values ind
1     Dog  v1
2     Cat  v1
3    Lion  v1
4   Shark  v1
8     Cat  v2
9    Lion  v2
10    Dog  v2
11  Shark  v2
12  Whale  v2
13   Seal  v2
15   Lion  v3
16    Dog  v3
17  Shark  v3
18    Cat  v3
19   Seal  v3
22    Dog  v4
23  Shark  v4
24    Cat  v4
25   Lion  v4
26  Moose  v4
27  Whale  v4
28   Deer  v4

> table(na.omit(stack(animals)))
       ind
values  v1 v2 v3 v4
  Cat    1  1  1  1
  Deer   0  0  0  1
  Dog    1  1  1  1
  Lion   1  1  1  1
  Moose  0  0  0  1
  Seal   0  1  1  0
  Shark  1  1  1  1
  Whale  0  1  0  1

> rowSums(table(na.omit(stack(animals))))
  Cat  Deer   Dog  Lion Moose  Seal Shark Whale
    4     1     4     4     1     2     4     2