2015-10-15 113 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