Существует ли функция R для получения уникальных ребер в ненаправленной (не направленной) сети? - PullRequest
4 голосов
/ 09 апреля 2019

Я хочу посчитать количество уникальных ребер в ненаправленной сети, например, net

   x  y
1  A  B
2  B  A
3  A  B

Должен быть только один уникальный край для этой матрицы, потому что края A-B и B-A одинаковы для ненаправленной сети.

Для направленной сети я могу получить количество уникальных ребер по:

nrow (уникальный (net [, c ("x", "y"]))

Но это не работает для ненаправленной сети.

Ответы [ 2 ]

2 голосов
/ 09 апреля 2019

Учитывая, что вы работаете с сетями, решение igraph:

library(igraph)

as_data_frame(simplify(graph_from_data_frame(dat, directed=FALSE)))

Затем используйте nrow


Объяснение

dat %>% 
  graph_from_data_frame(., directed=FALSE) %>% # convert to undirected graph
  simplify %>%                                 # remove loops / multiple edges
  as_data_frame                                # return remaining edges
1 голос
/ 09 апреля 2019

Попробуйте это,

df <- data.frame(x=c("A", "B", "A"), y = c("B", "A", "B"))
unique(apply(df, 1, function(x) paste(sort(unlist(strsplit(x, " "))),collapse = " ")))
[1] "A B"

Так как это работает?

  1. Мы применяем функцию к каждой строке фрейма данных, поэтому мы можем взятькаждая строка за раз.Возьмем вторую строку df:

    df[2,]
      x y
    1 B A
    
  2. Затем мы разбиваем (strsplit) это и unlist на вектор каждой буквы (Мы используем as.matrixчтобы выделить элементы)

    unlist(strsplit(as.matrix(df[2,]), " "))
    [1] "B" "A"
    
  3. Используйте функцию сортировки, чтобы расположить в алфавитном порядке, а затем вставьте их вместе,

    paste(sort(unlist(strsplit(as.matrix(df[2,]), " "))), collapse = " ")
    [1] "A B"
    

Затем функция apply делает это для всех строк, так как мы устанавливаем индекс на 1, а затем используем функцию unique для определения уникальных ребер.

Extension

Это может быть расширено до n переменных, например, n = 3,

df <- data.frame(x=c("A", "B", "A"), y = c("B", "A", "B"),  z = c("C", "D", "D"))
unique(apply(df, 1, function(x) paste(sort(unlist(strsplit(x, " "))),collapse = " ")))
[1] "A B C" "A B D"

Если требуется больше букв, просто объедините две буквы, как показано ниже,

df <- data.frame(x=c("A", "BC", "A"), y = c("B", "A", "BC"))
df
   x  y
1  A  B
2 BC  A
3  A BC
unique(apply(df, 1, function(x) paste(sort(unlist(strsplit(x, " "))),collapse = " ")))
[1] "A B"  "A BC"

Старая версия

Используя пакет tidyverse, создайте функцию с именем rev, которая может упорядочивать наши ребра, затем используйте mutate, чтобы создать новый столбец, объединяющий столбцы x и y,таким образом, он хорошо работает с функцией rev, затем запустите новый столбец через функцию и найдите уникальные пары.

library(tidyverse)
rev <- function(x){
  unname(sapply(x, function(x) {
    paste(sort(trimws(strsplit(x[1], ',')[[1]])), collapse=',')} ))
}
df <- data.frame(x=c("A", "B", "A"), y = c("B", "A", "B"))
rows <- df %>% 
  mutate(both = c(paste(x, y, sep = ", ")))

unique(rev(rows$both))
...