Фильтровать направленные вхождения в таблицу

У меня есть данные совместного вхождения, которые могут быть представлены в двух столбцах. Записи в каждом столбце относятся к одному и тому же набору возможностей. В конечном счете, я стремлюсь построить ориентированную сеть, но сначала я бы хотел разделить таблицу на взаимные (то есть X->Y и Y->X) и те, которые встречаются только в одном направлении (т.е. только Y->Z). Вот пример:

library(tidyverse)

# Example data
from <-  c("A", "B", "F", "Q", "T", "S", "D", "E", "A", "T", "F")
to <- c("E", "D", "Q", "S", "F", "T", "B", "A", "D", "A", "E")
df <- data_frame(from, to)
df
# A tibble: 11 x 2
   from  to   
   <chr> <chr>
 1 A     E    
 2 B     D    
 3 F     Q    
 4 Q     S    
 5 T     F    
 6 S     T    
 7 D     B    
 8 E     A    
 9 A     D    
10 T     A    
11 F     E   

и вот мой желаемый результат:

# Desired output 1 - reciprocal co-occurrences
df %>% 
  slice(c(1,2)) %>% 
  rename(item1 = from, item2 = to)

# A tibble: 2 x 2
  item1 item2
  <chr> <chr>
1 A     E    
2 B     D

# Desired output 2 - single occurrences
df %>% 
  slice(c(3,4,6,6,9,10,11))

# A tibble: 7 x 2
  from  to   
  <chr> <chr>
1 F     Q    
2 Q     S    
3 S     T    
4 S     T    
5 A     D    
6 T     A    
7 F     E 

Если совпадения взаимны, не имеет значения, в каком порядке находятся записи, мне нужны только их имена. Мне не нужно знать направление.

Это похоже на проблему с графиком, поэтому я попробовал, но не знаком с работой с данными такого типа, и большинство уроков, кажется, охватывают неориентированные графики. Глядя на tidygraph пакет, который я понимаю, использует igraph Пакет я пробовал это:

library(tidygraph)

df %>% 
  as_tbl_graph(directed = TRUE) %>%
  activate(edges) %>% 
  mutate(recip_occur = edge_is_mutual()) %>% 
  as_tibble() %>%
  filter(recip_occur == TRUE) 
# A tibble: 4 x 3
   from    to recip_occur
  <int> <int> <lgl>      
1     1     8 TRUE       
2     2     7 TRUE       
3     7     2 TRUE       
4     8     1 TRUE   

Однако это отделяет ребра от узлов и повторяет взаимные совпадения. У кого-нибудь есть опыт работы с такими данными?

1 ответ

Решение

Попробуй это:

данные:

from <-  c("A", "B", "F", "Q", "T", "S", "D", "E", "A", "T", "F")
to <- c("E", "D", "Q", "S", "F", "T", "B", "A", "D", "A", "E")
df <- data_frame(from, to)

код:

recursive_IND <-
1:nrow(df) %>% 
sapply(function(x){
    if(any((as.character(df[x,]) == t(df[,c(2,1)])) %>% {.[1,] & .[2,]}))
        return(T) else return(F)
    })

df[recursive_IND,][!(df[recursive_IND,] %>% apply(1,sort) %>% t %>% duplicated(.)),]
df[!recursive_IND,]

результат:

# A tibble: 2 x 2
#  from  to   
#  <chr> <chr>
#1 A     E    
#2 B     D    

# A tibble: 7 x 2
#  from  to   
#  <chr> <chr>
#1 F     Q    
#2 Q     S    
#3 T     F    
#4 S     T    
#5 A     D    
#6 T     A    
#7 F     E    
Другие вопросы по тегам