2015-10-15 2 views
10

я руководствуюсь этой статьей относительно Складная дерева в 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 

Который может будут представлены в виде сбрасываемого дерева следующим образом:

enter image description here

Мне интересно, может ли кто-нибудь помочь мне воспроизвести эту концепцию (складные деревья) с использованием этого набора данных игрушек выше, этот пример даст мне представление о том, как работают разные компоненты, например форматирование данных JSON в R etc ... и подача в качестве отправной точки. Заранее спасибо.

+0

Что такое набор данных, упомянутый выше, это csv? – Cyril

+0

@ Кирилл, да, это правильно –

+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, но похоже, что это issue на github, который не был реализован. Итак, вот простая функция для этого. Затем вы можете просто подключить полученные данные к связанному источнику, и у вас есть сворачиваемое дерево.

## 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 с детьми.

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

Как только у вас будет готовый Json, вы получите файл html your example, и вы замените '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. После вязания данные будут записаны внутри выходного HTML-файла и могут быть доступны через D3 через переменную json. Вот скриншот выходного HTML файла:

enter image description here

В нижней части изображения вы можете увидеть, что вы просто должны разобрать json объект с JSON.parse() и у вас есть ваши 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

В текущей версии 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

Смежные вопросы