2015-10-15 198 views
10

我這篇文章中的R關於可摺疊的樹被激發可摺疊的樹

http://bl.ocks.org/mbostock/4339083

我試圖使用玩具的數據集這樣

ID  Car Bus Train Feedback_Car Feedback_Bus Feedback_Train 
23433 Yes Yes Yes  Toyota   GreyHound  Amtrak 

再現相同的例子,可以可表示爲如下的可摺疊樹:

enter image description here

我想知道是否有人可以幫助我使用上面這個玩具數據集來重現這個概念(可摺疊樹),然後這個例子會給我一個想法,不同的組件如何工作,例如格式化R等數據中的JSON數據,作爲一個起點。提前致謝。

+0

什麼是數據集,上面提到的是這是一個csv? – Cyril

+0

@Cyril,是的,這是正確的 –

+0

看看[這個例子](http://104.131.111.111:3838/ggtree/)這個繁重的工作由D3.js完成,但它在一個閃亮的應用程序中。 – jeremycg

回答

0

可以使用data.tree包,讓您的數據轉換成JSON,或者也可以使用networkD3包:

dat <- read.table(text="ID  Car Bus Train Feedback_Car Feedback_Bus Feedback_Train 
23433 Yes Yes Yes  Toyota   GreyHound  Amtrak", header=TRUE) 

## Make an edgelist from your data 
edges <- rbind(cbind(dat$ID, names(dat)[2:4]), 
       cbind(names(dat)[2:4], as.vector(t(dat[5:7])))) 

library(data.tree) 
tree <- FromDataFrameNetwork(as.data.frame(edges)) 

tree 

這將打印如下:

  levelName 
1 23433    
2 ¦--Car   
3 ¦ °--Toyota 
4 ¦--Bus   
5 ¦ °--GreyHound 
6 °--Train   
7  °--Amtrak 

現在,用樹狀結構networkD3繪製:

lol <- ToListExplicit(tree, unname = TRUE) 

library(networkD3) 

diagonalNetwork(lol) 

不幸的是,不支持可摺疊的樹呢。但是here就是一個例子,如何用Shiny獲得你想要的。爲了將數據轉換爲正確的JSON格式,只要做到這一點:

library(jsonlite) 
json <- toJSON(lol) 
+0

這是非常有效的。我將嘗試可摺疊樹例子。 –

2

我讀了CSV,使節點JSON結構如下圖所示:

d3.csv("my.csv", function(error, data) { 
    var map1 = [] 
    data.reduce(function(map, node) { 
    map1.push(node) 
    return node; 
    }, {}); 

    root = {}; 
    root.name = map1[0].ID; 
    root.children = []; 
    var car = { 
    name: "Car", 
    children: [{ 
     name: map1[0].Feedback_Car, 
     children: [] 
    }] 
    }; 
    root.children.push(car); 
    var bus = { 
    name: "Bus", 
    children: [{ 
     name: map1[0].Feedback_Bus, 
     children: [] 
    }] 
    }; 
    root.children.push(bus); 
    var train = { 
    name: "Bus", 
    children: [{ 
     name: map1[0].Feedback_Train, 
     children: [] 
    }] 
    }; 
    root.children.push(train); 

}); 

工作代碼here

希望這有助於!

+0

我如何在R內工作,只需複製粘貼? –

+0

我的歉意,我不知道R ...我回答這個是因爲它在d3中被標記。 – Cyril

+1

沒問題,這會讓我開始。 :) –

5

這個可摺疊的樹看起來非常酷。我的方法是首先使用igraph創建圖表。我希望已經有一個將igraph轉換爲json的函數,但是,它看起來像github上的issue還沒有實現。所以,這是一個簡單的功能。然後,您可以將生成的數據插入到鏈接的源代碼中,並且您有一個可摺疊的樹。

## Read your data 
dat <- read.table(text="ID  Car Bus Train Feedback_Car Feedback_Bus Feedback_Train 
23433 Yes Yes Yes  Toyota   GreyHound  Amtrak", header=TRUE) 

## Make an edgelist from your data 
edges <- rbind(cbind(dat$ID, names(dat)[2:4]), 
       cbind(names(dat)[2:4], as.vector(t(dat[5:7])))) 

## Convert to a graph data structure 
library(igraph) 
g <- graph_from_edgelist(edges) 

## This is the non-interactive version 
plot(g, layout=layout.reingold.tilford(g, root='23433')) 

enter image description here

## Recursive function to make a list of nodes to be parsed by toJSON 
## call it with 'node' as the root node (here '23433') 
f <- function(g, node, size=1000) { 
    n <- neighbors(g, node, mode='out') 
    if (length(n) == 0) return(list(name=node, size=size)) 
    children <- lapply(n$name, function(x) f(g, x, size)) 
    list(name=node, children=children) 
} 

## Convert to json 
library(jsonlite) 
json <- toJSON(f(g, '23433'), auto_unbox = TRUE) 

## I made a directory collapsible to store the index.html from the linked 
## site, as well as this data 
## For completeness, you should be able to run this to see the interactive results, 
## But, of course, this is creating files on your box 
dir.create('collapsible') 
writeLines(json, 'collapsible/data.json') 

## Download the index.html 
download.file("https://gist.githubusercontent.com/mbostock/4339083/raw/0d003e5ea1686dd6e79562b37f8c7afca287d9a2/index.html", "collapsible/index.html", method='curl') 

## Replace with the correct data 
txt <- readLines('collapsible/index.html') 
txt[grepl("^d3.json", txt)] <- "d3.json('data.json', function(error, flare) {" 
writeLines(txt, 'collapsible/index.html') 

## Open in broweser 
browseURL(paste0('file://', normalizePath('collapsible/index.html'))) 

結果也可以看出here

+0

當前函數'browseURL ...'打開一個網頁它是空的.....是因爲在行'txt [grepl(「^ d3.json」 .....'沒有關閉......? –

+1

雖然看起來很混亂,但它只是該函數的開始,該行的目的是簡單地替換傳遞給d3.json的數據參數如果你看看整個文檔,這將是有意義的 – jenesaisquoi

+0

....嗯...奇怪爲什麼我看到一個空白頁... –

0

有關如何格式化數據here的詳細說明。他們建立在this answer關於如何爲孩子創建Json。

注:我認爲你將不得不重塑你的數據集以獲得以下列:ID,車輛類型,品牌。

一旦您準備好了Json,就可以抓取your example的html文件,並用我們的數據輸出路徑替換'flare.json'。

0

對於它的價值,我想和大家分享我從推R數據到D3的方式:

<!--begin.rcode results="asis", echo=FALSE, warning=FALSE, message=FALSE 
    library(RJSONIO) 
    library(MASS) 
    set.seed(1234) 
    data <- data.frame("Sample"=rbeta(1000,10,15)) 
    out <- paste("<script type='text/javascript'> var json ='", jsonlite::serializeJSON(data), "';</script>", sep="") 
end.rcode--> 

此代碼塊正位於我的RHTML文件body元素的開始。編織完成後,數據將寫入輸出HTML文件中,D3可通過變量json訪問。 下面是輸出HTML文件的截圖:

enter image description here

在圖片的底部,你可以看到你剛剛有JSON.parse()解析json對象,你必須準備好:)

數據JS
1

我很抱歉爲時已晚。我認爲你正在尋找R的解決方案,而不是一個迫使你使用外部代碼的解決方案。利用k3d3軟件包。 https://github.com/kaseyriver11/k3d3 這裏是想:

library(k3d3) 
library(RJSONIO) 
library(stringr) 

type <- c("Car", "Car", "Truck", "Truck", "Bus", "Bus") 
name <- c("Chevy", "Ford", "Chevy", "Ford", "Greyhound", "Holiday Express") 
size <- c(rep(3840,6)) 
data <- data.frame(type, name, size) 


makeList<-function(x){ 
    if(ncol(x)>2){ 
     listSplit<-split(x[-1],x[1],drop=T) 
     lapply(names(listSplit),function(y){list(name=y,children=makeList(listSplit[[y]]))}) 
    }else{ 
     lapply(seq(nrow(x[1])),function(y){list(name=x[,1][y],Percentage=x[,2][y])}) 
    } 
} 

jsonOut<-toJSON(list(name="23433",children=makeList(data))) 
jsonOut2 <- str_replace_all(jsonOut, "[\r\n]" , "") 

CTR(jsonOut2) 

Picture of Tree with Data Provided

0

networkD3(v0.4.9000 @ 2017年8月30日),目前開發的版本,有一個新的treeNetwork()功能有這個(交互式,可摺疊的樹形網絡圖)以及許多其他內置的新功能。

您可以安裝與當前版本的開發...

devtools::install_github("christophergandrud/networkD3") 

並繪製使用您的數據可摺疊的樹形網絡曲線...

library(networkD3) 

df <- read.table(header = T, stringsAsFactors = F, text = " 
ID  Car Bus Train Feedback_Car Feedback_Bus Feedback_Train 
23433 Yes Yes Yes  Toyota   GreyHound  Amtrak 
") 

links <- data.frame(nodeId = c(df$ID, names(df)[2:4], as.character(df[5:7])), 
        parentId = c("", rep(df$ID, 3), sub("^Feedback_", "", names(df[5:7])))) 
links$name <- links$nodeId 

treeNetwork(links, type = "tidy") 

仍有許多漏洞來制定出來,所以我們會很感激測試,填寫問題/錯誤報告和/或拉取請求。 https://github.com/christophergandrud/networkD3