2016-07-23 7 views
2

J'ai recueilli les données d'un ensemble de forums en ligne et j'ai voulu tracer, en utilisant ggplot et facettes (une facette par forum), la matrice qui représente combien de fois l'utilisateur A a répondu à l'utilisateur B.Tracer des matrices multiples dans des facettes avec différents axes xy

Voici le code pour charger un exemple de jouet:

library(ggplot2) 
library(dplyr) 

df.edges <- data.frame(from = c('forum1_user1', 'forum1_user1', 
           'forum1_user2', 'forum1_user2', 
           'forum2_user1', 'forum2_user1', 
           'forum2_user2', 'forum2_user2', 
           'forum3_user1', 'forum3_user1', 
           'forum3_user2', 'forum3_user2'), 
         to = c('forum1_user1', 'forum1_user2', 
           'forum1_user1', 'forum1_user2', 
           'forum2_user1', 'forum2_user2', 
           'forum2_user1', 'forum2_user2', 
           'forum3_user1', 'forum3_user2', 
           'forum3_user1', 'forum3_user2'), 
         weight = 1:12, 
         timestamp = 1:12, 
         subforum = c('forum1', 'forum1', 'forum1', 'forum1', 
            'forum2', 'forum2', 'forum2', 'forum2', 
            'forum3', 'forum3', 'forum3', 'forum3')) 

J'essaie ceci:

# Sort for later use in scale_discrete 
df.edges <- df.edges %>% arrange(timestamp) 


gg <- ggplot(df.edges, aes(x = from, y = to, fill = weight)) + 
    geom_raster() + coord_fixed() + 
    facet_grid(. ~subforum, scales='fixed') + 
    scale_x_discrete("from", aes(limits = from))+ 
    scale_y_discrete("to", aes(limits = from)) + 
    theme_bw() + 
    theme(axis.line  = element_blank(), 
     axis.text.x  = element_text(angle = 90, hjust=1, size=8), 
     axis.text.y  = element_text(hjust=1, size=10), 
     axis.ticks  = element_blank(), 
     strip.background = element_rect(fill = 'white'), 
     aspect.ratio = 1) + 
    ggtitle("Matrix of interactions") + xlab('from') + ylab('to') 
print(gg) 

qui donne ceci:

enter image description here

Et si je mets l'échelle de la facette scale='free':

enter image description here

Cependant, je veux chaque facette pour afficher uniquement les utilisateurs appartenant à ce forum. Les matrices doivent être complètement remplies de 4 cellules dans chacune d'elles.

Une idée?

+0

Je ne pense pas que vous pouvez le faire avec 'facet_grid', essayez d'utiliser' facet_wrap' ou encore tweak vos données..'df.edges [c ("de", "à")] <- lapply (df.edges [c ("de", "à")], gsub, pattern = "forum \\ d + _", replacement = "") ' – user20650

Répondre

3

Vous pouvez créer un terrain pour chaque niveau de subforum puis les poser ensemble à l'aide grid.arrange:

library(gridExtra) 
library(grid) 

D'abord, créer les parcelles séparées et stocker dans une liste. Nous ajoutons scale_fill_continuous(limits=range(df.edges$weight)) pour assurer un gradient de remplissage uniforme dans les trois parcelles:

pl = lapply(split(df.edges, df.edges$subforum), function(df) { 
    ggplot(df, aes(x = from, y = to, fill = weight)) + 
     geom_raster() + coord_fixed() + 
     facet_grid(. ~subforum, scales='fixed') + 
     scale_x_discrete("from", aes(limits = from))+ 
     scale_y_discrete("to", aes(limits = from)) + 
     scale_fill_continuous(limits=range(df.edges$weight)) + 
     theme_bw() + 
     theme(axis.line  = element_blank(), 
      axis.text.x  = element_text(angle = 90, hjust=1, size=8), 
      axis.text.y  = element_text(hjust=1, size=10), 
      axis.ticks  = element_blank(), 
      strip.background = element_rect(fill = 'white'), 
      aspect.ratio = 1) + 
     xlab('from') + ylab('to') 
    }) 

Extrait la légende, que nous ne voulons qu'une légende, plutôt qu'une légende distincte pour chaque parcelle:

# Function to extract legend 
#https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs 
g_legend<-function(a.gplot){ 
    tmp <- ggplot_gtable(ggplot_build(a.gplot)) 
    leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box") 
    legend <- tmp$grobs[[leg]] 
    return(legend) } 

# Extract legend as a grob 
leg = g_legend(pl[[1]]) 

Organiser la parcelles avec la légende et le titre:

grid.arrange(
    textGrob("Matrix of Interactions"), 
    arrangeGrob(
    arrangeGrob(grobs=lapply(pl, function(x) x + guides(fill=FALSE)), ncol=3), 
    leg, ncol=2, widths=c(10,1) 
), 
    heights=c(1,20) 
) 

enter image description here

+0

Merci eipi10, ça marche! Cependant, juste pour le compte rendu, si vous voulez l'étiquette d'utilisateur (ce ne sera pas mon cas parce que j'en ai mille) dans l'axe et leurs noms d'utilisateur ont des longueurs différentes, chaque matrice a une taille différente. – alberto

+1

Vous pouvez vous assurer que la zone de traçage a la même taille dans chaque tracé en utilisant la fonction 'plot_grid' de la pacakge' cowplot'. Voir aussi [cette réponse SO] (http://stackoverflow.com/a/35304121/496488). – eipi10