0

I want to make a directed graph in R by making 2 data frame: one for vertices and one for edges. Also, my graph should have these attributes:

  • No circle (therefore no A -> A)
  • There is maximum 1 edge between 2 nodes.

I come up with the code as below:

library(dplyr)

USER_BASE <- 1:100
MAXIMUM_USER_RELATIONSHIP = length(USER_BASE)*4

my_random <- function(vector, size, replace, seed)
{
    set.seed(seed)
    return(sample(vector, size = size, replace = replace))
}

user <- data.frame(
    id = USER_BASE
)

relationship <- data.frame(
    from = my_random(USER_BASE, MAXIMUM_USER_RELATIONSHIP, replace = TRUE, 1),
    to = my_random(USER_BASE, MAXIMUM_USER_RELATIONSHIP, replace = TRUE, 2)
) %>% filter(from != to) %>% unique()

My code still allows 2 edges between 2 nodes (A -> B AND B -> A). How could I achieve that only 1 edge between A and B?

Kind regards

Edit: I found a solution from: Unique rows, considering two columns, in R, without order

My complete code:

library(dplyr)
library(data.table)

USER_BASE <- 1:100
MAXIMUM_USER_RELATIONSHIP = length(USER_BASE)*4

my_random <- function(vector, size, replace, seed)
{
    set.seed(seed)
    return(sample(vector, size = size, replace = replace))
}

user <- data.frame(
    id = USER_BASE
)

relationship <- data.frame(
    from = my_random(USER_BASE, MAXIMUM_USER_RELATIONSHIP, replace = TRUE, 1),
    to = my_random(USER_BASE, MAXIMUM_USER_RELATIONSHIP, replace = TRUE, 2)
) %>% filter(from != to) %>% unique()

relationship <- unique(as.data.table(relationship)[, c("from", "to") := list(pmin(from, to),
                                                 pmax(from, to))], by = c("from", "to"))
Community
  • 1
  • 1

1 Answers1

0

You could use anti_join to remove any rows which exist in an reversed version.

reverse <- data.frame(to = relationship$from, from = relationship$to)

anti_join(relationship, reverse)
Mhairi McNeill
  • 1,951
  • 11
  • 20