Фильтровать направленные вхождения в таблицу
У меня есть данные совместного вхождения, которые могут быть представлены в двух столбцах. Записи в каждом столбце относятся к одному и тому же набору возможностей. В конечном счете, я стремлюсь построить ориентированную сеть, но сначала я бы хотел разделить таблицу на взаимные (то есть 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