Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting ctree output into JSON Format (for D3 tree layout)

I'm working on a project that requires to run a ctree and then plot it in interactive mode - like the 'D3.js' tree layout, my main obstacle is to convert the ctree output into a json format, to later use by javascript.

Following is what i need (with example from the iris data):

> library(party)
> irisct <- ctree(Species ~ .,data = iris)
> irisct

     Conditional inference tree with 4 terminal nodes

Response:  Species 
Inputs:  Sepal.Length, Sepal.Width, Petal.Length, Petal.Width 
Number of observations:  150 

1) Petal.Length <= 1.9; criterion = 1, statistic = 140.264
  2)*  weights = 50 
1) Petal.Length > 1.9
  3) Petal.Width <= 1.7; criterion = 1, statistic = 67.894
    4) Petal.Length <= 4.8; criterion = 0.999, statistic = 13.865
      5)*  weights = 46 
    4) Petal.Length > 4.8
      6)*  weights = 8 
  3) Petal.Width > 1.7
    7)*  weights = 46 

Now i want to convert the ctee output into the following JSON format using some algorithm (i did it manually), though, this is probably not the best way to convert it:

{"name" : "Petal.Length <= 1.9  criterion = 1","value": 60, "children" : [
            {"name" : "n=50" ,"value": 60},
            {"name" : "Petal.Length > 1.9 criterion = 1","value": 60, "children": [
                  {"name" : "n=46","value": 60 },
                  {"name" : "Petal.Length > 4.8","value": 60, "children" :[
            {"name" : "Petal.Width > 1.7" ,"value": 60},
            {"name" : "46" ,"value": 60}
    ]}] }
      ]}

Here are two pictures of both R and D3.js plots:

enter image description hereenter image description here

i already tried using RJSONIO on the ctree object, that didn't help much.

Has anyone ever converted a ctree object/output into JSON for the use of D3.js tree layout? if not, does anyone have any idea of an algorithm that can convert one output to the other?

Thanks in advance for any help!

like image 228
Yehoshaphat Schellekens Avatar asked Sep 02 '14 10:09

Yehoshaphat Schellekens


1 Answers

The trick is to extract the useful bits of the irisct object, and only convert those to JSON. Something like this:

get_ctree_parts <- function(x, ...)
{
  UseMethod("get_ctree_parts")
}

get_ctree_parts.BinaryTree <- function(x, ...)
{
  get_ctree_parts(attr(x, "tree"))
}

get_ctree_parts.SplittingNode <- function(x, ...)
{
  with(
    x,
    list(
      nodeID       = nodeID,
      variableName = psplit$variableName,
      splitPoint   = psplit$splitpoint,
      pValue       = 1 - round(criterion$maxcriterion, 3),
      statistic    = round(max(criterion$statistic), 3),
      left         = get_ctree_parts(x$left),
      right        = get_ctree_parts(x$right)
    )
  )
}

get_ctree_parts.TerminalNode <- function(x, ...)
{
  with(
    x,
    list(
      nodeID     = nodeID,
      weights    = sum(weights),
      prediction = prediction
    )
  )
}

useful_bits_of_irisct <- get_ctree_parts(irisct)
toJSON(useful_bits_of_irisct)

I figured this answer out through judicious use of the unclass function. For example:

unclass(irisct)
unclass(attr(irisct, "tree"))
unclass(attr(irisct, "tree")$psplit)

The print methods in the package, party:::print.SplittingNode and party:::print.TerminalNode were also very useful. (Type party:::print. and autocomplete to see what is available.)

like image 165
Richie Cotton Avatar answered Nov 13 '22 06:11

Richie Cotton