2015-11-03 6 views
3

Я пытаюсь создать sankey diagram в R, который также упоминается как участок реки. Я видел этот вопрос Sankey Diagrams in R?, где перечислены широкие вариации пакетов, производящих диаграммы sankey. Поскольку у меня есть входные данные и я знаю разные инструменты/пакеты, я могу создать такую ​​диаграмму. Но мой euqestion: как я могу подготовить входные данные для таких?Как подготовить входные данные для диаграмм sankey в R?

Давайте предположим, что мы хотели бы представить, как пользователи мигрировали между различными государствами в течение 10 дней и имеют начать набор данных, как показано ниже:

data.frame(userID = 1:100, 
        day1_state = sample(letters[1:8], replace = TRUE, size = 100), 
        day2_state = sample(letters[1:8], replace = TRUE, size = 100), 
        day3_state = sample(letters[1:8], replace = TRUE, size = 100), 
        day4_state = sample(letters[1:8], replace = TRUE, size = 100), 
        day5_state = sample(letters[1:8], replace = TRUE, size = 100), 
        day6_state = sample(letters[1:8], replace = TRUE, size = 100), 
        day7_state = sample(letters[1:8], replace = TRUE, size = 100), 
        day8_state = sample(letters[1:8], replace = TRUE, size = 100), 
        day9_state = sample(letters[1:8], replace = TRUE, size = 100), 
        day10_state = sample(letters[1:8], replace = TRUE, size = 100) 
        ) -> dt 

Теперь, если один хотел бы создать Санки диаграмму с networkD3 package как следует один tranform этого dt data.frame в необходимый вход

так, что мы имели бы вход как из этого примера

library(networkD3) 
URL <- paste0(
     "https://cdn.rawgit.com/christophergandrud/networkD3/", 
     "master/JSONdata/energy.json") 
Energy <- jsonlite::fromJSON(URL) 
# Plot 
sankeyNetwork(Links = Energy$links, Nodes = Energy$nodes, Source = "source", 
      Target = "target", Value = "value", NodeID = "name", 
      units = "TWh", fontSize = 12, nodeWidth = 30) 

EDIT

Я нашел такой скрипт, который подготавливает данные в другой ситуации и воспроизведенный, так что я предполагаю, что это может быть в настоящее время закрыты:

https://github.com/mi2-warsaw/JakOniGlosowali/blob/master/sankey/sankey.R

+1

Вместо того, чтобы закрывать его, вы также можете рассмотреть вопрос о предоставлении ответа на свой вопрос. Это может помочь другим людям – PavoDive

+1

Хорошо, я загрузил код с примером и отвечу :) –

ответ

2

Я нашел такой скрипт, который подготавливает данные другая ситуация и воспроизводится так, я предполагаю, что это может быть закрыто:

https://github.com/mi2-warsaw/JakOniGlosowali/blob/master/sankey/sankey.R

Затем этот код генерирует такую ​​диаграмму sankey для упомянутых в вопросе данных.frame

fixtable <- function(...) { 
    tab <- table(...) 
    if (substr(colnames(tab)[1],1,1) == "_" & 
       substr(rownames(tab)[1],1,1) == "_") { 
     tab2 <- tab 
     colnames(tab2) <- sapply(strsplit(colnames(tab2), split=" "), `[`, 1) 
     rownames(tab2) <- sapply(strsplit(rownames(tab2), split=" "), `[`, 1) 
     tab2[1,1] <- 0 
     # mandat w klubie 
     for (par in names(which(tab2[1,] > 0))) { 
      delta = min(tab2[par, 1], tab2[1, par]) 
      tab2[par, par] = tab2[par, par] + delta 
      tab2[1, par] = tab2[1, par] - delta 
      tab2[par, 1] = tab2[par, 1] - delta 
     } 
     # przechodzi przez niezalezy 
     for (par in names(which(tab2[1,] > 0))) { 
      tab2["niez.", par] = tab2["niez.", par] + tab2[1, par] 
      tab2[1, par] = 0 
     } 
     for (par in names(which(tab2[,1] > 0))) { 
      tab2[par, "niez."] = tab2[par, "niez."] + tab2[par, 1] 
      tab2[par, 1] = 0 
     } 

     tab[] <- tab2[] 
    } 
    tab 
} 


flow2 <- rbind(
    data.frame(fixtable(z = paste0(dat$day1_state, " day1"), do = paste0(dat$day2_state, " day2"))), 
    data.frame(fixtable(z = paste0(dat$day2_state, " day2"), do = paste0(dat$day3_state, " day3"))), 
    data.frame(fixtable(z = paste0(dat$day3_state, " day3"), do = paste0(dat$day4_state, " day4"))), 
    data.frame(fixtable(z = paste0(dat$day4_state, " day4"), do = paste0(dat$day5_state, " day5"))), 
    data.frame(fixtable(z = paste0(dat$day5_state, " day5"), do = paste0(dat$day6_state, " day6"))), 
    data.frame(fixtable(z = paste0(dat$day6_state, " day6"), do = paste0(dat$day7_state, " day7"))), 
    data.frame(fixtable(z = paste0(dat$day7_state, " day7"), do = paste0(dat$day8_state, " day8"))), 
    data.frame(fixtable(z = paste0(dat$day8_state, " day8"), do = paste0(dat$day9_state, " day9"))), 
    data.frame(fixtable(z = paste0(dat$day9_state, " day9"), do = paste0(dat$day10_state, " day10")))) 

flow2 <- flow2[flow2[,3] > 0,] 

nodes2 <- data.frame(name=unique(c(levels(factor(flow2[,1])), levels(factor(flow2[,2]))))) 
nam2 <- seq_along(nodes2[,1])-1 
names(nam2) <- nodes2[,1] 

links2 <- data.frame(source = nam2[as.character(flow2[,1])], 
             target = nam2[as.character(flow2[,2])], 
             value = flow2[,3]) 

sankeyNetwork(Links = links, Nodes = nodes, 
          Source = "source", Target = "target", 
          Value = "value", NodeID = "name", 
          fontFamily = "Arial", fontSize = 12, nodeWidth = 40, 
          colourScale = "d3.scale.category20()")