3 votes

Création de noeuds et de bords à partir de dataframes rangés

J'ai un data frame qui a cette structure :

df <- data.frame(var1 = c(1,1,1,2,2,3,3,3,3),
                 cat1 = c("A","B","D","B","C","D","E","B","A"))`

> df
  var1 cat1
1    1    A
2    1    B
3    1    D
4    2    B
5    2    C
6    3    D
7    3    E
8    3    B
9    3    A

Et je cherche à créer à partir de celui-ci des data frames nodes et edges, pour que je puisse dessiner un graphique de réseau, en utilisant VisNetwork. Ce réseau montrera le nombre/la force des connexions entre les différentes valeurs de cat1, regroupées par la valeur de var1.

J'ai trié le data frame nodes :

nodes <- data.frame(id = unique(df$cat1))
> nodes
  id
1  A
2  B
3  D
4  C
5  E

Je souhaiterais de l'aide pour traiter df de la manière suivante : pour chaque valeur distincte de var1 dans df, compter le groupe de nodes qui sont communs à cette valeur de var1 pour donner un data frame edges qui ressemblera en fin de compte à celui ci-dessous. Notez que je ne me sens pas concerné par le sens du flux le long des arêtes. Juste le fait qu'ils sont connectés est tout ce dont j'ai besoin.

> edges
  from to value
1    A  B     2
2    A  D     2
3    A  E     1
4    B  C     1
5    B  D     2
6    B  E     1
7    D  E     1

Merci d'avance, Nevil

Mise à jour : J'ai trouvé ici un problème similaire, et j'ai adapté ce code pour obtenir, qui se rapproche de ce que je veux, mais pas tout à fait...

    > df %>% group_by(var1) %>%
             filter(n()>=2) %>% group_by(var1) %>%
             do(data.frame(t(combn(.$cat1, 2,function(x) sort(x))), 
                           stringsAsFactors=FALSE))

# A tibble: 10 x 3
# Groups:   var1 [3]
    var1 X1    X2   

 1    1. A     B    
 2    1. A     D    
 3    1. B     D    
 4    2. B     C    
 5    3. D     E    
 6    3. B     D    
 7    3. A     D    
 8    3. B     E    
 9    3. A     E    
10    3. A     B

1voto

nghauran Points 5191

Je ne sais pas s'il existe déjà une fonction appropriée pour accomplir cette tâche. Voici une procédure détaillée pour le faire. Avec ceci, vous devriez être en mesure de définir votre propre fonction. J'espère que cela vous aidera!

# créer une matrice d'adjacence
mat <- table(df)
mat <- t(mat) %*% mat 
as.table(mat) # regardez votre matrice d'adjacence
# puisque le réseau n'est pas dirigé, nous ne considérer que la matrice triangulaire supérieure (strictement)
mat[lower.tri(mat, diag = TRUE)] <- 0
as.table(mat) # regardez la nouvelle matrice d'adjacence

library(dplyr)
edges <- as.data.frame(as.table(mat))
edges <- filter(edges, Freq != 0)
colnames(edges) <- c("from", "to", "value")
edges <- arrange(edges, from)
edges # sortie

#  from to value
#1    A  B     2
#2    A  D     2
#3    A  E     1
#4    B  C     1
#5    B  D     2
#6    B  E     1
#7    D  E     1

1voto

CJ Yetman Points 3545

Voici quelques autres façons...

en base R...

valeurs <- unique(df$var1[duplicated(df$var1)])

do.call(rbind,
  lapply(valeurs, function(i) {
    noeuds <- as.character(df$cat1[df$var1 == i])
    arrêtes <- combn(noeuds, 2)
    data.frame(de = arrêtes[1, ],
               à = arrêtes[2, ],
               valeur = i,
               stringsAsFactors = F)
  })
)

dans tidyverse...

bibliothèque(dplyr)
bibliothèque(tidyr)

df %>%
  group_by(var1) %>%
  filter(n() >= 2) %>%
  mutate(cat1 = as.character(cat1)) %>% 
  summarise(arrêtes = list(data.frame(t(combn(cat1, 2)), stringsAsFactors = F))) %>%
  unnest(arrêtes) %>% 
  select(from = X1, to = X2, valeur = var1)

dans tidyverse en utilisant tidyr::complete...

bibliothèque(dplyr)
bibliothèque(tidyr)

df %>%
  group_by(var1) %>%
  mutate(cat1 = as.character(cat1)) %>% 
  mutate(i.cat1 = cat1) %>% 
  complete(cat1, i.cat1) %>% 
  filter(cat1 < i.cat1) %>% 
  select(from = cat1, to = i.cat1, valeur = var1)

dans tidyverse en utilisant tidyr::expand...

bibliothèque(dplyr)
bibliothèque(tidyr)

df %>%
  group_by(var1) %>%
  mutate(cat1 = as.character(cat1)) %>%
  expand(cat1, to = cat1) %>% 
  filter(cat1 < to) %>% 
  select(from = cat1, to, valeur = var1)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X