2017-12-14 7 views
4

Ich habe versucht, ein Sankey-Diagramm mit den Paketen ggalluvial und networkd3 zu erstellen, die bisher fehlgeschlagen sind. Idealerweise würde ich gerne verstehen, wie ich das bekommen kann, was ich in beiden machen möchte.Datenaufbereitung für Sankey Daten in R, um die Flusshäufigkeit zu erhalten

Die Daten werden wie folgt generiert:

dat <- data.frame(customer = c(rep(c(1, 2), each=3), 3, 3), 
       holiday_loc = c("SA", "SA", "AB", "SA", "SA", "SA", "AB", "AB"), 
       holiday_num = c(1, 2, 3, 1, 2, 3, 1, 2)) 

dat_wide <- dat %>% 
     spread(key=holiday_num, value=holiday_loc`) 

Nicht sicher, ob dat oder dat_wide besser geeignet ist? Ich mag die Ausgabe die folgenden Informationen

SA (wobei die Zahl in Klammern die Frequenz und damit Breite der Strömung ist) sichtbar zu machen - (2) - SA - (1) - AB

  - (1) - SA 

AB - (1) - AB

gefolgt I die Anweisungen auf dieser Verbindung für networkd3 Sankey diagram for Discrete State Sequences in R using networkd3 jedoch I mit Schleifen in dem Diagramm endete.

Ein ähnliches Diagramm von dem, was ich will, ist im Bild unten dargestellt: [! [Sankey Diagramm von SAS VA genommen] [2]] [2]

Vorschläge und Hilfe sehr geschätzt werden ...

Danke!

[2]: https://i.stack.imgur.com/wTJ1k.pngenter image description here

+0

ich Ihre (Probe) Daten nicht verstehen. Sankey-Diagramme sind eine Visualisierung von gerichteten (gewichteten) Graphen. Wo sind Ihre Sätze von (gewichteten) Links (Kanten) und Knoten (Vertices)? –

Antwort

2

Das Kernproblem mit Ihren Daten (unter networkD3) besteht darin, dass Sie Knoten mit demselben Namen haben. Sie müssen diese also unterscheiden, zumindest während Sie die Daten verarbeiten.

den Standort Kombinieren und die Anzahl Informationen zu unterscheiden Knoten zu machen, dann Ihre Daten in einen Links-Datenrahmen verwandeln, so ...

links <- 
    dat %>% 
    mutate("source" = paste(holiday_loc, holiday_num, sep = "_")) %>% 
    group_by(customer) %>% 
    arrange(holiday_num) %>% 
    mutate("target" = lead(source)) %>% 
    ungroup() %>% 
    arrange(customer) %>% 
    filter(!is.na(target)) %>% 
    select(source, target) 

Von diesem können Sie einen Knoten Datenrahmen bauen, die enthält eine Zeile für jeden einzelnen Knoten, so ...

node_names <- factor(sort(unique(c(as.character(links$source), 
            as.character(links$target))))) 
nodes <- data.frame(name = node_names) 

dann den Links-Datenrahmen konvertieren, den Index zu verwenden (0-indexierte, da es letztendlich zu JavaScript übergeben wird) des Knotens im Frame Knoten Daten, so ...

An diesem Punkt
links <- data.frame(source = match(links$source, node_names) - 1, 
        target = match(links$target, node_names) - 1, 
        value = 1) 

, wenn Sie die Knoten wollen nicht unterschiedliche Namen haben, können Sie das jetzt ändern, so ...

nodes$name <- sub("_[0-9]$", "", nodes$name) 

Und jetzt können Sie es zeichnen ...

library(networkD3) 
sankeyNetwork(links, nodes, "source", "target", "value", "name") 

sankey plot

+0

Gibt es eine Möglichkeit, anzugeben, dass die Flüsse übrig sind -gerichtet statt rechtsbündig? Das heißt, die Top-Flow-Wld beginnt bei Index 0. Ich verwende sonst eine Umgehung, indem ich einen Dummy-Knoten für "Drop-Off" verwende und in ein leeres Zeichen umbenenne und das wird gut funktionieren. – user1420372

+0

Überprüfen Sie die Hilfedatei ... 'sinksRight = F' –

0

Ich finde das alluvialen Paket für diese Aufgabe nützlich, aber ich weiß nicht, ob das Ihre Verriegelung ist, was für:

library(tidyverse) 
library(alluvial) 
dat <- data.frame(customer = c(rep(c(1, 2), each=3), 3, 3), 
        holiday_loc = c("SA", "SA", "AB", "SA", "SA", "SA", "AB", "AB"), 
        holiday_num = c(1, 2, 3, 1, 2, 3, 1, 2)) 

dat_summarized <- dat %>% group_by(holiday_num, holiday_loc, customer) %>% 
    summarise(n = n()) %>% mutate(color = recode(customer, 
               `1` = "cadetblue1", 
               `2` = "cadetblue2", 
               `3` = "cadetblue3")) 

alluvial(dat_summarized[1:3], 
     freq = dat_summarized$n, 
     col = dat_summarized$color) 

alluvial

+0

Ich habe gerade ein Foto hinzugefügt, das macht es hoffentlich klarer. Ich möchte nicht eine Zeile pro Kunde, aber für die Links die Anzahl der Kunden, die von Ort x an Feiertagsnummer i bis Ort y an Feiertagsnummer i + 1 gingen. – user1420372

Verwandte Themen