Сложное дерево в R
Я мотивирован этой статьей о Складном дереве в R
http://bl.ocks.org/mbostock/4339083
Я пытаюсь воспроизвести тот же пример, используя набор данных игрушек, подобный этому
ID Car Bus Train Feedback_Car Feedback_Bus Feedback_Train
23433 Yes Yes Yes Toyota GreyHound Amtrak
Что можно представить в виде сбрасываемого дерева следующим образом
![введите описание изображения здесь]()
Мне интересно, может ли кто-нибудь помочь мне воспроизвести эту концепцию (складные деревья) с использованием этого набора данных игрушек выше, этот пример даст мне представление о том, как работают разные компоненты, например форматирование данных JSON в R etc... и служат отправной точкой. Спасибо заранее.
Ответы
Ответ 1
Вы можете использовать пакет 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)
К сожалению, это еще не поддерживает сбрасываемые деревья. Но здесь - пример того, как получить то, что вы хотите, с помощью Shiny. Чтобы преобразовать ваши данные в правильный формат JSON, просто выполните следующее:
library(jsonlite)
json <- toJSON(lol)
Ответ 2
Это сжимаемое дерево выглядит действительно круто. Мой подход заключается в том, чтобы сначала создать граф, используя igraph
. Я надеялся, что уже есть функция для преобразования igraph в json, но похоже, что это issue в github, что hasn ' были реализованы. Итак, вот простая функция для этого. Затем вы можете просто подключить полученные данные к связанному источнику, и у вас есть сворачиваемое дерево.
## 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')))
Результаты также можно увидеть здесь.
Ответ 3
Я прочитал csv и создаю структуру node 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);
});
Рабочий код здесь
Надеюсь, это поможет!
Ответ 4
Я извиняюсь за то, что так опаздываю. Я думаю, что вы ищете решение в 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)
Изображение дерева с предоставленными данными
Ответ 5
Существует подробное объяснение того, как отформатировать ваши данные здесь. Они основываются на этом ответе о том, как создать Json с детьми.
Примечание. Я думаю, вам придется изменить свой набор данных, чтобы получить следующие столбцы: ID, Тип транспортного средства, Бренд.
Как только у вас будет готовый Json, вы возьмете 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-->
Этот фрагмент кода находится справа в начале элемента body в моем файле RHTML. После вязания данные будут записаны внутри выходного HTML файла и могут быть доступны через D3 через переменную json
.
Вот скриншот выходного HTML файла:
![введите описание изображения здесь]()
В нижней части рисунка вы можете видеть, что вам просто нужно проанализировать объект json
с помощью JSON.parse()
, и у вас есть готовые данные JS:)
Ответ 7
В текущей версии dev networkD3
(v0.4.9000 @2017.08.30) есть новая функция treeNetwork()
, которая имеет это (интерактивные, разборные сетевые графики деревьев) и многие другие новые встроенные функции.
Вы можете установить текущую версию dev с помощью...
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