R中的可折叠树
Posted
技术标签:
【中文标题】R中的可折叠树【英文标题】:Collapsible tree in R 【发布时间】:2015-10-15 06:44:57 【问题描述】:这篇关于 R 中的可折叠树的文章激励了我
http://bl.ocks.org/mbostock/4339083
我正在尝试使用这样的玩具数据集重现相同的示例
ID Car Bus Train Feedback_Car Feedback_Bus Feedback_Train
23433 Yes Yes Yes Toyota GreyHound Amtrak
可以如下表示为可折叠树
我想知道是否有人可以帮助我使用上面的这个玩具数据集重现该概念(可折叠树),然后这个示例将让我了解不同组件的工作原理,例如在 R 中格式化 JSON 数据等......以及作为起点。提前致谢。
【问题讨论】:
什么是数据集,上面提到这是一个csv吗? @Cyril,是的,没错 看看this example 繁重的工作是由 D3.js 完成的,但它在一个闪亮的应用程序中。 好答案。以后请不要问“为我写这段代码”的问题 【参考方案1】:这棵可折叠的树看起来很酷。我的方法是首先使用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'))
## 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。
【讨论】:
目前browseURL...
函数打开网页时是空的.....是因为txt[grepl("^d3.json".....
行尾有一个打开的
没有关闭.. .?
应该在那里,虽然它看起来很混乱,它只是那个功能的开放。该行的目的是简单地替换传递给 d3.json 的数据参数。如果您查看整个文档,这将是有意义的。
@EzraPolson 我也是 :),你做了什么,什么错误信息?您可以单击底部的链接以查看它的全部荣耀,以及您需要重现的所有代码。
:) 大声笑,点击链接有效,但是当我将这个示例复制粘贴到我的 R 中并运行代码时,我在运行 download.file....
行 Warning messages: 1: running command 'curl "https://gist.githubusercontent.com/mbostock/4339083/raw/0d003e5ea1686dd6e79562b37f8c7afca287d9a2/index.html" -o "collapsible/index.html"' had status 127 2: In download.file("https://gist.githubusercontent.com/mbostock/4339083/raw/0d003e5ea1686dd6e79562b37f8c7afca287d9a2/index.html", : download had nonzero exit status
时看到一个警告跨度>
@EzraPolson 你只是在curl
选项到download.file
听起来有问题。你可以弄乱其他选项,但它是https:
,这样会限制它们一点。手动复制该页面并将其粘贴到index.html
可能更容易。然后,其余的应该可以工作了。【参考方案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
希望这会有所帮助!
【讨论】:
抱歉,我不知道 R...我回答了这个问题,因为它被标记在 d3 中。【参考方案3】:我很抱歉这么晚了。我认为您正在寻找 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
【讨论】:
【参考方案4】:您可以使用 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)
【讨论】:
这非常有效。我将尝试可折叠树的示例。【参考方案5】:有一个关于如何格式化你的数据here的详细解释。他们以 this answer 为基础,介绍如何使用孩子创建 Json。
注意:我认为您必须重塑数据集以获取以下列:ID、车辆类型、品牌。
准备好 Json 后,获取 your example 的 html 文件,并将“flare.json”替换为我们的数据输出路径。
【讨论】:
【参考方案6】:我想分享一下我将数据从 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
variable 访问。
这是输出 HTML 文件的屏幕截图:
在图片的底部你可以看到你只需要用JSON.parse()
解析json
对象并且你已经准备好你的数据JS了:)
【讨论】:
【参考方案7】:在networkD3
(v0.4.9000 @ 2017.08.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
【讨论】:
以上是关于R中的可折叠树的主要内容,如果未能解决你的问题,请参考以下文章
Bootstrap 2.3 android 手机中的可折叠菜单问题
Visual Studio 2012(C#)中的可折叠(条件、循环)块[重复]