[
  {
    "path": ".Rbuildignore",
    "content": "^.*\\.Rproj$\n^\\.Rproj\\.user$\n^\\.travis\\.yml$\ndata_gen\ncran-comments.md\npublish-cheat-sheet.md\ngetting-started-with-development.md\nappveyor.yml\ntravis-tool.sh.cmd\nRprof.out\n^appveyor\\.yml$\nrevdep\nREADME.md\n^CRAN-RELEASE$\n^\\.github$\n^CRAN-SUBMISSION$\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto\ndata/* binary\nsrc/* text=lf\nR/* text=lf"
  },
  {
    "path": ".github/.gitignore",
    "content": "*.html\n"
  },
  {
    "path": ".github/workflows/R-CMD-check.yaml",
    "content": "# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples\n# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help\non:\n  push:\n    branches: [main, master]\n  pull_request:\n    branches: [main, master]\n\nname: R-CMD-check\n\njobs:\n  R-CMD-check:\n    runs-on: ${{ matrix.config.os }}\n\n    name: ${{ matrix.config.os }} (${{ matrix.config.r }})\n\n    strategy:\n      fail-fast: false\n      matrix:\n        config:\n          - {os: macos-latest,   r: 'release'}\n          - {os: windows-latest, r: 'release'}\n          - {os: ubuntu-latest,   r: 'devel', http-user-agent: 'release'}\n          - {os: ubuntu-latest,   r: 'release'}\n          - {os: ubuntu-latest,   r: 'oldrel-1'}\n\n    env:\n      GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}\n      R_KEEP_PKG_SOURCE: yes\n\n    steps:\n      - uses: actions/checkout@v3\n\n      - uses: r-lib/actions/setup-pandoc@v2\n\n      - uses: r-lib/actions/setup-r@v2\n        with:\n          r-version: ${{ matrix.config.r }}\n          http-user-agent: ${{ matrix.config.http-user-agent }}\n          use-public-rspm: true\n\n      - uses: r-lib/actions/setup-r-dependencies@v2\n        with:\n          extra-packages: any::rcmdcheck\n          needs: check\n\n      - uses: r-lib/actions/check-r-package@v2\n        with:\n          upload-snapshots: true\n"
  },
  {
    "path": ".github/workflows/test-coverage.yaml",
    "content": "# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples\n# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help\non:\n  push:\n    branches: [main, master]\n  pull_request:\n    branches: [main, master]\n\nname: test-coverage\n\njobs:\n  test-coverage:\n    runs-on: ubuntu-latest\n    env:\n      GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}\n\n    steps:\n      - uses: actions/checkout@v3\n\n      - uses: r-lib/actions/setup-r@v2\n        with:\n          use-public-rspm: true\n\n      - uses: r-lib/actions/setup-r-dependencies@v2\n        with:\n          extra-packages: any::covr\n          needs: coverage\n\n      - name: Test coverage\n        run: |\n          covr::codecov(\n            quiet = FALSE,\n            clean = FALSE,\n            install_path = file.path(normalizePath(Sys.getenv(\"RUNNER_TEMP\"), winslash = \"/\"), \"package\")\n          )\n        shell: Rscript {0}\n\n      - name: Show testthat output\n        if: always()\n        run: |\n          ## --------------------------------------------------------------------\n          find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \\; || true\n        shell: bash\n\n      - name: Upload test results\n        if: failure()\n        uses: actions/upload-artifact@v3\n        with:\n          name: coverage-test-failures\n          path: ${{ runner.temp }}/package\n"
  },
  {
    "path": ".gitignore",
    "content": ".Rproj.user\n.Rhistory\n.RData\ninst/doc\nprivate\nRprof.out\nrevdep"
  },
  {
    "path": ".travis.yml",
    "content": "language: r\ncache: packages\nr:\n  - oldrel\n  - release\n  - devel\n\nsudo: false\n\nwarnings_are_errors: true\n\nr_packages:\n  - rmarkdown\n  - covr\n\nr_check_args: --as-cran\n\nafter_success:\n  - Rscript -e 'library(covr);codecov()'\n\nnotifications:\n  email:\n    on_success: change\n    on_failure: change\n"
  },
  {
    "path": "CRAN-SUBMISSION",
    "content": "Version: 1.1.0\nDate: 2023-11-12 11:25:34 UTC\nSHA: d9ceaf8a4343f32483a5856ff530f4a31a6b40fa\n"
  },
  {
    "path": "DESCRIPTION",
    "content": "Package: data.tree\nType: Package\nTitle: General Purpose Hierarchical Data Structure\nVersion: 1.1.0\nDate: 2023-11-11\nAuthors@R: c(\n      person(\n        \"Russ\", \"Hyde\",\n        role = c(\"ctb\"),\n        comment = \"improve dependencies\"\n      ),\n      person(\n        \"Chris\", \"Hammill\",\n        role = c(\"ctb\"),\n        comment = \"improve getting\"\n      ),\n      person(\n        \"Facundo\", \"Munoz\",\n        role = c(\"ctb\"),\n        comment = \"improve list conversion\"\n      ),\n      person(\n        \"Markus\", \"Wamser\"\n        , role = c(\"ctb\")\n        , comment = \"fixed some typos\"\n      ),\n      person(\n        \"Pierre\", \"Formont\"\n        , role = c(\"ctb\")\n        , comment = \"additional features\"\n      ),\n      person(\n        \"Kent\", \"Russel\"\n        , role = c(\"ctb\")\n        , comment = \"documentation\"\n      ),\n      person(\n        \"Noam\", \"Ross\"\n        , role = c(\"ctb\")\n        , comment = \"fixes\"\n      ),\n      person(\n        \"Duncan\", \"Garmonsway\"\n        , role = c(\"ctb\")\n        , comment = \"fixes\"\n      ),\n      person(\n        \"Christoph\", \"Glur\"\n        , role = c(\"aut\", \"cre\")\n        , comment = \"R interface\"\n        , email = \"christoph.glur@powerpartners.pro\"\n      )\n    )\nVignetteBuilder: \n    knitr,\n    rmarkdown\nImports:\n    R6,\n    stringi,\n    methods\nSuggests:\n    Formula,\n    graphics,\n    testthat,\n    knitr,\n    rmarkdown,\n    ape,\n    yaml,\n    networkD3,\n    jsonlite,\n    treemap,\n    party,\n    partykit,\n    doParallel,\n    foreach,\n    htmlwidgets,\n    DiagrammeR (>= 1.0.0),\n    mockery,\n    rpart\nEnhances: \n    igraph\nDescription: Create tree structures from hierarchical data, and traverse the\n    tree in various orders. Aggregate, cumulate, print, plot, convert to and from\n    data.frame and more. Useful for decision trees, machine learning, finance,\n    conversion from and to JSON, and many other applications.\nLicense: GPL (>= 2)\nURL: https://github.com/gluc/data.tree\nBugReports: https://github.com/gluc/data.tree/issues\nDepends:\n    R (>= 3.5)\nRoxygenNote: 7.2.3\nEncoding: UTF-8\n"
  },
  {
    "path": "NAMESPACE",
    "content": "# Generated by roxygen2: do not edit by hand\n\nS3method(as.Node,BinaryTree)\nS3method(as.Node,data.frame)\nS3method(as.Node,dendrogram)\nS3method(as.Node,list)\nS3method(as.Node,party)\nS3method(as.Node,phylo)\nS3method(as.Node,rpart)\nS3method(as.data.frame,Node)\nS3method(as.dendrogram,Node)\nS3method(as.list,Node)\nS3method(plot,Node)\nS3method(print,Node)\nexport(.parentSeparator)\nexport(.separator)\nexport(Aggregate)\nexport(AreNamesUnique)\nexport(Climb)\nexport(Clone)\nexport(CreateRandomTree)\nexport(CreateRegularTree)\nexport(Cumulate)\nexport(DefaultPlotHeight)\nexport(Distance)\nexport(Do)\nexport(FindNode)\nexport(FormatFixedDecimal)\nexport(FormatPercent)\nexport(FromDataFrameNetwork)\nexport(FromDataFrameTable)\nexport(FromListExplicit)\nexport(FromListSimple)\nexport(Get)\nexport(GetAttribute)\nexport(GetDefaultTooltip)\nexport(GetPhyloNr)\nexport(NODE_RESERVED_NAMES_CONST)\nexport(Navigate)\nexport(Node)\nexport(Prune)\nexport(Revert)\nexport(Set)\nexport(SetEdgeStyle)\nexport(SetFormat)\nexport(SetGraphStyle)\nexport(SetNodeStyle)\nexport(Sort)\nexport(ToDataFrameNetwork)\nexport(ToDataFrameTable)\nexport(ToDataFrameTree)\nexport(ToDataFrameTypeCol)\nexport(ToDiagrammeRGraph)\nexport(ToListExplicit)\nexport(ToListSimple)\nexport(ToNewick)\nexport(Traverse)\nexport(as.Node)\nexport(as.igraph.Node)\nexport(as.phylo.Node)\nexport(averageBranchingFactor)\nexport(isLeaf)\nexport(isNotLeaf)\nexport(isNotRoot)\nexport(isRoot)\nimport(methods)\nimport(stats)\nimport(stringi)\nimportFrom(R6,R6Class)\n"
  },
  {
    "path": "NEWS",
    "content": "# All changes to data.tree are documented here.\n\n## Version 1.1.0\n- IMPROVE: Node names may no longer be `NA`.  It was not fully supported, and now it is an error. (#152)\n- FIX: changed lock_object to lock_objects (#149 thx to Olly Beagly)\n- FIX: help('data.tree') works again\n- IMPROVE: FromListSimple and as.Node.list now have an additional parameter 'interpretNullAsList'. See #169 for details.\n- IMPROVE: added parameter `row.names = FALSE`in `print.Node()` to hide row numbers when printing a data.tree.\n\n## Version 1.0.0\n- IMPROVE: Replaced dependency on stringr by dependency on stringi, which make data.tree even more light-weight\n- CHANGE: Node serialization changed. In many cases, you might still be able to load previously saved data.tree objects, but then they do not correspond to the latest version.\n- CHANGE: New reserved words for Node: attributes and attributesAll\n- NOTE: Node$fields and Node$fieldsAll will be deprecated in the next version. Use Node$attributes and Node$attributesAll instead\n- REMOVE: Deprecated Node$FindNode has been removed (use FindeNode(node, ...) instead)\n- IMPROVE: Node is now fully documented, (thx to roxygen2 for supporting R6)\n- CHANGE: data.tree now depends on R 3.5\n- FIX: adjusted sample data that didn't support correct handling of active bindings\n- IMPROVE: Adding reserved word check to FromDataFrameNetwork (#147 thx to wkumler)\n\n## Version 0.7.11\n- IMPROVE: diagrammeR is now only suggested, so data.tree is much more lightweight if plotting is not needed (#143 thx to Russ Hyde)\n- FIX: plot now also works with quotations in names (#137 thx to thotal)\n- IMPROVE: as.list and other conversions to list now contain pruneFun argument (#142)\n\n## Version 0.7.10\n- IMPROVE: various spell errors fixed in vignettes\n\n## Version 0.7.9\n- FIX: Bug in as.data.frame.Node: NA for certain lists slots (#135)\n- FIX: Get prints Null as NA by default (#128)\n\n## Version 0.7.8\n- FIX: wrong export of S3\n\n## Version 0.7.7\n- IMPROVE: if an attribute of a node has n dimensions, then Get will return an array of dim n+1, with the names of the first dimension being equal to the node names (thanks to Chris Hammil)\n- FIX: fieldsAll now doesn't simplify (thanks to Vaclav Slimacek)\n\n## Version 0.7.6\n- IMPROVE: plot now also works for trees with a single root node (thx to Pierre Neuvial)\n- IMPROVE: ellipsis parameters are not passed to DiagrammeR for plotting (#109)\n- FIX: Dependency on DiagrammeR (>= 1.0.0) explicitly stated (#111)\n- IMPROVE: Allow tibble in FromDataFrameNetwork and FromDataFrameTable (#115)\n\n## Version 0.7.5\n- IMPROVE: namesNotUnique parameter in as.Node.phylo (#106)\n- FIX: fixed incompatibility issue with DiagrammeR (#110)\n\n## Version 0.7.4\n- IMPROVE: print now has an explicit arg pruneFun\n- FIX: partykit tests now pass\n- FIX: DESCRIPTION now in line with latest changes from CRAN (rmarkdown declared)\n- FIX: Skipped tests in testMethods included\n\n## Version 0.7.3\n- FIX: Various typos in documentation\n\n## Version 0.7.2\nUpgrade to R 3.4.x and newest package versions.\n- FIX: plot: global graph attributes now work (#88)\n- FIX: typo in vignette data.tree vignette('applications', package = \"data.tree\")\n- FIX: warnings in as.dendrogram\n- FIX: warnings in sample code for Do\n- FIX: as.data.frame created warnings for values that were of length 0\n\n## Version 0.7.0\n- ADD: ToDiagrammeRGraph to convert to a DiagrammeR graph object\n- REMOVE: ToGraphViz (replaced with ToDiagrammeRGraph, to support the latest features in the DiagrammeR package). You can still get the dot representation by using DiagrammeR::generate_dot(ToDiagrammeRGraph(node))\n- CHANGE: plot.Node 's last parameter is now 'graph', and not 'engine' anymore.\n- FIX: minor typos fixed\n\n## Version 0.6.2\n- ADD: new Distance function to measure distance from one Node to another in the same tree\n\n## Version 0.6.1\n- IMPROVE: FromListSimple now accepts subclasses of lists (#79)\n- IMPROVE: FromDataFrameTable now supports tibbles (#89)\n- IMPROVE: print.Node and as.data.frame.Node now also work for node fields with length > 1 (#81)\n- FIX: print.Node and as.data.frame.Node now also work if some Nodes have the same name as some fileds (#82)\n- REMOVE: node$FindNode, and node$Navigate are now deprecated. Use FindNode(node, ...) and Naviate(node, ...) instead\n- REMOVE: node$Sort, node$Prune, and node$Revert are now deprecated. Use Sort(node, ...), Prune(node, ...) and Revert(node, ...) instead\n\n## Version 0.5.0\n- IMPROVE: Performance improvement for many functions. For example, as.Node roughly by factor 4 for large dataset (#74)\n- CHANGE: by default, as.data.frame.Node (and derivatives) do not format anymore (use the format parameter if you want to format)\n- IMPROVE: Allow the possibility to keep only some fields when converting to list using as.list.Node (#76)\n- FromDataFrameTable (#77)\n  - FIX: now also works if there is only the pathString column\n  - IMPROVE: pathString can now also be a factor (or any other type convertible to character)\n\n\n## Version 0.4.0\n- IMPROVE: as.Node.data.frame and FromDataFrameTable now support paths containing reserved words (#65)\n- CHANGE: Node$new now checks that names are not reserved names. As a consequence, many conversions to Node now contain a check parameter.\n- IMPROVE: Climb is now much faster when climbing by name (#71)\n- IMPROVE: As a result of #71, many other functions are much faster, e.g. FromDataFrameTable (#72)\n\n\n## Version 0.3.7\n- ADD: Traverse can now also take custom function as a traversal argument\n- ADD: Navigate method\n- ADD: as.Node.BinaryTree Convert SplittingNode from party package to data.tree (#6)\n- ADD: as.Node.party Convert party class from partykit package to data.tree (#6)\n\n## Version 0.3.6\n- FIX: GetDefaultTooltip now also works for attributes which are functions\n- FIX: GetAttribute now returns attributes with length 0 (e.g. an empty list)\n- ADD: Sort, Revert and Prune are now also available in traditional format (e.g. Prune(node, pruneFun))\n- FIX: FromListSimple: Empty lists now become empty nodes (#59)\n- IMPROVE: FromListSimple: Unnamed list elements are now also converted (#61)\n- IMPROVE: documentation of Aggregate\n- IMPROVE: Check type when setting Node$parent and Node$children (#63)\n\n\n## Version 0.3.5\n- FIX: minor correction in documentation\n\n## Version 0.3.4\n- FIX: minor correction in documentation\n\n## Version 0.3.3\n- CHANGE: Renamed Find method to FindNode, in order to avoid masking from base\n- FIX: upgrade to latest version of treemap package\n- FIX: a few typos in documentation\n\n\n## Version 0.3.2\n- ADD: FromListExplicit now interprets character vectors as a list of nodes (#58)\n\n\n## Version 0.3.1\n- IMPROVE: as.list.Node \n  - now generates auto name if unique name is not available (#54)\n  - now has warn arg, warning if source data contains reserved names\n  - now also imports fiels with names equal to reserved names (e.g. count), they will be renamed (to e.g. count2)\n- CHANGE: node$leaves now returns a list even when called on a leaf itself\n- ADD: Find method to find a single Node in a (sub-)tree (#52)\n\n## Version 0.3.0 Pine Tree\n- REMOVE: Removed the cacheAttribute parameter from Aggregate and Cumulate (they were confusing, even to me. Use Do instead to manually store aggregate values in the tree)\n- ADD: plot function (see ?plot.Node)\n- ADD: ToDataFrameTypeCol to export e.g. the path to columns by level in columns: ToDataFrameTypeCol(acme)\n- ADD: Node$AddSibling\n- ADD: Node$RemoveAttribute now contains a mandatory parameter so that it can be used if the node does not have the attribute to be removed.\n- ADD: Get works on methods without args\n- IMPROVE: FormatFixedDecimal and FormatPercent work for NULL values\n- IMPROVE: Documentation\n- FIX: Aggregate will not return attribute from callee anymore, but *always* aggregate children attributes\n- FIX: Removed ... parameter from ToListExplicit and ToListSimple \n- FIX: Clone was adding empty children list, which caused a series of problems (#44)\n- FIX: Cloning a subtree does not keep reference to un-cloned parent anymore (#49)\n- FIX: print with limit parameter ignored formatter (#43)\n- FIX: cannot rename to int, e.g. acme$Do(function(x) x$name <- x$position) (#53)\n\n\n## Version 0.2.4\n- FIX: applications vignette, changed from http://htmlwidgets.org to http://www.htmlwidgets.org, as requested by CRAN\n\n## Version 0.2.3\n- FIX #33: applications vignette doesn't build because of DiagrammeR update\n- FIX #32: Cannot subclass Node\n- FIX #30: strange errors when using data.tree multiple times\n\n## Version 0.2.2\n- FIX: Get can now fetch vectors and matrices too\n- ADD: Node$siblings\n\n## Version 0.2.0-rc.1 Elder\n\n- ADD: ClimbByAttribute\n- FIX: Aggregate and Cumulate now work always on attributes having a formatter\n- ADD: as.igraph now has a 'directed' parameter\n- ADD: print now has a pruneMethod, allowing different methods to avoid that a huge tree is printed to the console\n- REMOVE: FromDataFrameTaxonomy and ToDataFrameTaxonomy (replaced by FromDataFrameNetwork and ToDataFrameNetwork, but with some differences)\n- ADD: FromDataFrameNetwork and ToDataFrameNetwork\n- IMPROVE: make Traversal \"level\" much faster\n- ADD: Node$RemoveChild\n- ADD: Node$RemoveAttribute\n- ADD: as.igraph.Node now supports different directions (climb and descend)\n\n## Version 0.1.9 Pine II\n\n- Set correct version number in DESCRIPTION file\n\n## Version 0.1.8 Pine\n\n- Node\n  - CHANGE: Node$depth is now called Node$height, as the old naming was confusing for many, because in CS, the Node$level is sometimes \n- Utils\n  - CHANGE: Renamed CreateDummyTree to CreateRegularTree\n  - CHANGE: Height renamed to DefaultPlotHeight, so as to avoid confusion with Node$height\n  - ADD: CreateRandomTree to test trees\n  - ADD: trees can now be climbed directly, e.g. acme$IT$`Go agile`\n  - ADD: print.Node with limit parameter is now much faster\n  - ADD: Clone is now much faster\n\n## Version 0.1.7 Chestnut\n\n- General\n  - ADD: demo portfolio\n  - ADD: demo decisiontree\n  - ADD: demo population / treemap\n- Node\n  - CHANGE: Node$level is now 1-based (used to be: 0-based), i.e. if Node$isRoot then Node$level = 1\n  - CHANGE: Node$Find is now called Node$Climb to avoid confusion with base::Find\ncalled depth\n  - ADD: print.Node contains a limit parameter, allowing to limit the max number of Nodes to be printed\n  - ADD: Clone (returning a deep copy)\n  - ADD: Prune (pruning the tree)\n  - ADD: SetFromat (support for setting formatter functions on a Node)\n  - ADD: Traverse, standalone traverse method that can be used for piping and whenever you need to apply multiple Get/Set/Do on the same traversal\n  - ADD: Node$isBinary active\n  - ADD: standalone versions of isLeaf, isNotLeaf, isRoot, isNotRoot for concise filtering\n  - ADD: AreNamesUnique to test if names of the node's are unique throughout the tree (and not only among siblings)\n  - FIX: node$position now returns 1 for root\n  - ADD: Aggregate function now supports functions\n  - ADD: node$averageBranchingFactor\n  - CHANGE: Aggregate function does not cache anymore by default. See cacheAttribute for details.\n  - Node$Get: \n    - CHANGE: Renamed filterFun parameter to pruneFun\n    - ADD: new parameter filterFun, as opposed to pruneFun\n    - CHANGE: removed the assign parameter (use Do instead)\n    - ADD: new traversal modes \"in-order\", \"level\"\n    - ADD: parameter inheritFromAncestors\n  - Node$Set:\n    - ADD: filterFun and pruneFun\n    - ADD: support for traversal order\n  - Node$Do:\n    - ADD: new function Do, which applies a function to Nodes\n- Conversions\n  - ADD: conversion to and from list of lists (and thus to and from yaml, json, etc.)\n  - ADD: conversion from data.frame\n  - ADD: conversion to and from dendrogram\n  - ADD: conversion to and from phylo from the ape package\n  - ADD: conversion to Newick notation\n  - ADD: conversion ToDataFrameTable (returning leafs only)\n  - ADD: conversion ToDataFrameTree\n  - ADD: conversion ToDataFrameTaxonomy\n  - ADD: conversion to igraph\n- Utils\n  - CHANGE: Renamed PrintFixedDecimal to FormatFixedDecimal to achieve better consistency\n  - ADD: CreateDummyTree to test large trees\n  - ADD: CreateRandomTree to test trees\n"
  },
  {
    "path": "R/data.tree-package.R",
    "content": "#' data.tree: Hierarchical Data Structures\n#' \n#' \\code{data.tree} is to hierarchical data what \\code{data.frame} is to tabular data: An extensible, general purpose structure to store, manipulate, \n#' and display hierarchical data.\n#' \n#' @section Introduction:\n#' \n#' Hierarchical data is ubiquitous in statistics and programming (XML, search trees, family trees, classification, file system, etc.). However, no general-use \\bold{tree data structure} is available in R. \n#' Where tabular data has \\code{data.frame}, hierarchical data is often modeled in lists of lists or similar makeshifts. These\n#' structures are often difficult to manage.\n#' This is where the \\code{data.tree} package steps in. It lets you build trees of hierarchical\n#' data for various uses: to print, to rapid prototype search algorithms, to test out new classification algorithms, and much more. \n#' \n#' @section Tree Traversal:\n#' \n#' \\code{data.tree} allows to \\code{\\link{Traverse}} trees in various orders (pre-order, post-order, level, etc.), and it lets you run operations on \\code{\\link{Node}s} via\n#' \\code{\\link{Do}}. \n#' Similarly, you can collect and store data while traversing a tree using the \\code{\\link{Get}} and the \\code{\\link{Set}} methods.\n#' \n#' @section Methods:\n#' \n#' The package also contains utility functions to \\code{\\link{Sort}}, to \\code{\\link{Prune}}, to \\code{\\link{Aggregate}} and \\code{\\link{Cumulate}} \n#' and to \\code{\\link{print}} in custom formats.\n#' \n#' \n#' @section Construction and Conversion:\n#'\n#' The package also contains many conversions from and to data.tree structures. Check out the see also section of \\code{\\link{as.Node}}.\n#'   \n#' You can construct a tree from a \\code{data.frame} using \\code{\\link{as.Node.data.frame}}, and convert it back using \\code{\\link{as.data.frame.Node}}.\n#' Similar options exist for list of lists. \n#' For more specialized conversions, see \\code{\\link{as.dendrogram.Node}}, \\code{\\link{as.Node.dendrogram}}, \n#' \\code{\\link{as.phylo.Node}} and \\code{\\link{as.Node.phylo}}\n#' \n#' Finally, easy conversion options from and to list, dataframe, JSON, YAML, igraph, ape, rpart, party and more exist:\n#' \n#' \\itemize{\n#'  \\item{list: both directions}\n#'  \\item{dataframe: both directions}\n#'  \\item{JSON, YAML: both directions, via lists}\n#'  \\item{igraph: from igraph to data.tree}\n#'  \\item{ape: both directions}\n#'  \\item{rpart: from rpart to data.tree}\n#'  \\item{party: from party to data.tree}\n#' }\n#'  \n#' @section Node and Reference Semantics:\n#'  \n#' The entry point to the package is \\code{\\link{Node}}. Each tree is composed of a number of \\code{Node}s, referencing each other.\n#' \n#' One of most important things to note about \\code{data.tree} is that it exhibits \\bold{reference semantics}. In a nutshell, this means that you can modify \n#' your tree along the way, without having to reassign it to a variable after each modification. By and large, this is a rather exceptional behavior\n#' in R, where value-semantics is king most of the time.\n#' \n#' @section Applications:\n#' \n#' \\code{data.tree} is not optimised for computational speed, but for implementation speed. Namely, its memory\n#' footprint is relatively large compared to traditional R data structures. However, it can easily handle trees with\n#' several thousand nodes, and once a tree is constructed, operations on it are relatively fast.\n#' data.tree is always useful when\n#' \\itemize{\n#'  \\item{you want to develop and test a new algorithm}\n#'  \\item{you want to import and convert tree structures (it imports and exports to list-of-list, data.frame, yaml, json, igraph, dendrogram, phylo and more)}\n#'  \\item{you want to play around with data, display it and get an understanding}\n#'  \\item{you want to test another package, to compare it with your own results}\n#'  \\item{you need to do homework}\n#' }\n#' \n#' For a quick overview of the features, read the \\code{\\link{data.tree}} vignette by running \\code{vignette(\"data.tree\")}. For stylized\n#' applications, see \\code{vignette(\"applications\", package='data.tree')}\n#'\n#' @examples\n#' data(acme)\n#' print(acme)\n#' acme$attributesAll\n#' acme$count\n#' acme$totalCount\n#' acme$isRoot\n#' acme$height\n#' print(acme, \"p\", \"cost\")\n#' \n#' outsource <- acme$IT$Outsource\n#' class(outsource)\n#' print(outsource)\n#' outsource$attributes\n#' outsource$isLeaf\n#' outsource$level\n#' outsource$path\n#' outsource$p\n#' outsource$parent$name\n#' outsource$root$name\n#' outsource$expCost <- outsource$p * outsource$cost\n#' print(acme, \"expCost\")\n#' \n#' acme$Get(\"p\")\n#' acme$Do(function(x) x$expCost <- x$p * x$cost)\n#' acme$Get(\"expCost\", filterFun = isLeaf)\n#' \n#' ToDataFrameTable(acme, \"name\", \"p\", \"cost\", \"level\", \"pathString\")\n#' ToDataFrameTree(acme, \"name\", \"p\", \"cost\", \"level\")\n#' ToDataFrameNetwork(acme, \"p\", \"cost\")\n#' \n#' \n#' @seealso \\code{\\link{Node}}\n#' @seealso For more details, see the \\code{data.tree} vignette by running: \\code{vignette(\"data.tree\")}\n#' @name data.tree\n#' @keywords internal\n\"_PACKAGE\"\nNULL"
  },
  {
    "path": "R/data_doc.R",
    "content": "#' Sample Data: A Simple Company with Departments\n#' \n#' acme's tree representation is accessed through its root, acme.\n#' \n#' \\itemize{\n#'   \\item cost, only available for leaf nodes. Cost of the project.\n#'   \\item p probability that a project will be undertaken.\n#' }\n#' \n#' @docType data\n#' @keywords datasets\n#' @name acme\n#' @usage data(acme)\n#' @format A data.tree root Node\nNULL\n\n\n\n#' Sample Data: Data Used by the ID3 Vignette\n#' \n#' mushroom contains attributes of mushrooms. We can use this data to predict a\n#' mushroom's toxicity based on its attributes.\n#' The attributes available in the data set are:\n#' \n#' \\itemize{\n#'   \\item color the color of a mushroom\n#'   \\item size whether a mushroom is small or large\n#'   \\item points whether a mushroom has points\n#'   \\item edibility whether a mushroom is edible or toxic\n#' }\n#' \n#' @docType data\n#' @keywords datasets\n#' @name mushroom\n#' @usage data(mushroom)\n#' @format data.frame\nNULL"
  },
  {
    "path": "R/node.R",
    "content": "#' Names that are reserved by the Node class.\n#'\n#' These are reserved by the Node class, you cannot use these as \n#' attribute names.\n#' Note also that all attributes starting with a . are reserved.\n#' \n#' @export\nNODE_RESERVED_NAMES_CONST <- c( \n                                'AddChild',\n                                'AddChildNode',\n                                'AddSibling',\n                                'AddSiblingNode',\n                                'attributes',\n                                'attributesAll',\n                                'averageBranchingFactor',\n                                'children',\n                                'Climb',\n                                'Navigate',\n                                'FindNode',\n                                'clone',\n                                'count',\n                                'Do',\n                                'fields',\n                                'fieldsAll',\n                                'Get',\n                                'GetAttribute',\n                                'height',\n                                'initialize',\n                                'isBinary',\n                                'isLeaf',\n                                'isRoot',\n                                'leafCount',\n                                'leaves',\n                                'level',\n                                'levelName',\n                                'name',\n                                'parent',\n                                'path',\n                                'pathString',\n                                'position',\n                                'printFormatters',\n                                'Prune',\n                                'Revert',\n                                'RemoveAttribute',\n                                'RemoveChild',\n                                'root',\n                                'Set',\n                                'siblings',\n                                'Sort',\n                                'totalCount',\n                                '.*')\n\n\n#' Create a \\code{data.tree} Structure With \\code{Nodes}\n#' \n#' @description \\code{Node} is at the very heart of the \\code{data.tree} package. All trees are constructed\n#' by tying together \\code{Node} objects.\n#' \n#' @details Assemble \\code{Node} objects into a \\code{data.tree}\n#' structure and use the traversal methods to set, get, and perform operations on it. Typically, you construct larger tree \n#' structures by converting from \\code{data.frame}, \\code{list}, or other formats.\n#' \n#' Most methods (e.g. \\code{node$Sort()}) also have a functional form (e.g. \\code{Sort(node)})\n#' \n#' @docType class\n#' @importFrom R6 R6Class\n#'   \n#' \n#' @usage # n1 <- Node$new(\"Node 1\")\n#'\n#' @examples\n#' library(data.tree)\n#' acme <- Node$new(\"Acme Inc.\")\n#' accounting <- acme$AddChild(\"Accounting\")$\n#'               AddSibling(\"Research\")$\n#'               AddChild(\"New Labs\")$\n#'               parent$\n#'               AddSibling(\"IT\")$\n#'               AddChild(\"Outsource\")\n#' print(acme)\n#'\n#'\n#' @param name the name of the node to be created\n#' @param check Either\n#' \\itemize{\n#'  \\item{\\code{\"check\"}: if the name conformance should be checked and warnings should be printed in case of non-conformance (the default)}\n#'  \\item{\\code{\"no-warn\"}: if the name conformance should be checked, but no warnings should be printed in case of non-conformance (if you expect non-conformance)}\n#'  \\item{\\code{\"no-check\" or FALSE}: if the name conformance should not be checked; use this if performance is critical. However, in case of non-conformance, expect cryptic follow-up errors}\n#' }\n#' @param ... A name-value mapping of node attributes\n#' @param attribute determines what is collected. The \\code{attribute} can be\n#'       \\itemize{\n#'         \\item a.) the name of a \\bold{field} or a \\bold{property/active} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"p\")} or \\code{acme$Get(\"position\")}\n#'         \\item b.) the name of a \\bold{method} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"levelZeroBased\")}, where e.g. \\code{acme$levelZeroBased <- function() acme$level - 1}\n#'         \\item c.) a \\bold{function}, whose first argument must be a \\code{Node} e.g. \\code{acme$Get(function(node) node$cost * node$p)}\n#'        }\n#'\n#' @param recursive if \\code{TRUE}, the method will be called recursively on the \\code{Node}'s children. This allows sorting an entire tree.\n#' @param traversal defines the traversal order to be used. This can be\n#'  \\describe{\n#'    \\item{pre-order}{Go to first child, then to its first child, etc.}\n#'    \\item{post-order}{Go to the first branch's leaf, then to its siblings, and work your way back to the root}\n#'    \\item{in-order}{Go to the first branch's leaf, then to its parent, and only then to the leaf's sibling}\n#'    \\item{level}{Collect root, then level 2, then level 3, etc.}\n#'    \\item{ancestor}{Take a node, then the node's parent, then that node's parent in turn, etc. This ignores the \\code{pruneFun} }\n#'    \\item{function}{You can also provide a function, whose sole parameter is a \\code{\\link{Node}} object. The function is expected to return the node's next node, a list of the node's next nodes, or NULL.}\n#'  }\n#'  Read the data.tree vignette for a detailed explanation of these traversal orders.\n#'       \n#'       \n#' @param pruneFun allows providing a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \n#' If the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.\n#'       \n#' @param filterFun allows providing a a filter, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}.\n#' Note that if filter returns \\code{FALSE}, then the node will be excluded from the result (but not the entire subtree).\n#'       \n#'       \n#' @seealso For more details see the \\code{\\link{data.tree}} documentations, or the \\code{data.tree} vignette: \\code{vignette(\"data.tree\")}\n#'\n#'    \n#' @export\n#' @format An \\code{\\link{R6Class}} generator object\nNode <- R6Class(\"Node\",\n                lock_objects = FALSE,\n                lock_class = TRUE,\n                portable = TRUE,\n                class = TRUE,\n                cloneable = TRUE,\n                    public = list(\n                      \n                     \n                      #' @description Create a new \\code{Node} object. This is often used to create the root of a tree when creating a tree programmatically.\n                      #' \n                      #' @examples \n                      #' node <- Node$new(\"mynode\", x = 2, y = \"value of y\")\n                      #' node$y\n                      #' \n                      #' @return A new `Node` object\n                      initialize=function(name, check = c(\"check\", \"no-warn\", \"no-check\"), ...) {\n                        if (!missing(name)) {\n                          name <- as.character(name)\n                          if (length(name) != 1) {\n                            stop(\"Node name must be a scalar\")\n                          } else if (is.na(name)) {\n                            stop(\"Node name must be a non-NA character scalar\")\n                          }\n                          name <- CheckNameReservedWord(name, check)\n                          private$p_name <- name\n                        }\n                        if (!missing(...)) {\n                          args <- list(...)\n                          mapply(FUN = function(arg, nme) self[[nme]] <- arg, args, names(args))\n                        }\n                        \n                        invisible (self)\n                      },\n                      \n                      \n                      \n                      ####################\n                      # Tree creation\n                      \n                      #' @description Creates a \\code{Node} and adds it as the last sibling as a child to the \\code{Node} on which this is called.\n                      #' \n                      #' @examples \n                      #' root <- Node$new(\"myroot\", myname = \"I'm the root\")\n                      #' root$AddChild(\"child1\", myname = \"I'm the favorite child\")\n                      #' child2 <- root$AddChild(\"child2\", myname = \"I'm just another child\")\n                      #' child3 <- child2$AddChild(\"child3\", myname = \"Grandson of a root!\")\n                      #' print(root, \"myname\")\n                      #' \n                      #' @return The new \\code{Node} (invisibly)\n                      AddChild = function(name, check = c(\"check\", \"no-warn\", \"no-check\"), ...) {\n                        child <- Node$new(as.character(name), check, ...)\n                        invisible (self$AddChildNode(child))\n                      },\n                      \n                      \n                      #' @description Adds a \\code{Node} as a child to this node.\n                      #' \n                      #' @param child The child \\code{\"Node\"} to add.\n                      #' \n                      #' @examples \n                      #' root <- Node$new(\"myroot\")\n                      #' child <- Node$new(\"mychild\")\n                      #' root$AddChildNode(child)\n                      #' \n                      #' @return the child node added (this lets you chain calls)\n                      AddChildNode = function(child) {\n                        private$p_children[[child$name]] <- child\n                        self[[child$name]] <- child\n                        child$parent <- self\n                        invisible (child)\n                      },\n                      \n                      \n                      \n                      #' @description Creates a new \\code{Node} called \\code{name} and adds it after this \\code{Node} as a sibling.\n                      #' \n                      #' @examples \n                      #' #' root <- Node$new(\"myroot\")\n                      #' child <- root$AddChild(\"child1\")\n                      #' sibling <- child$AddSibling(\"sibling1\")\n                      #' \n                      #' @return the sibling node (this lets you chain calls)\n                      #' \n                      AddSibling = function(name, check = c(\"check\", \"no-warn\", \"no-check\"), ...) {\n                        sibling <- Node$new(as.character(name), check, ...)\n                        invisible (self$AddSiblingNode(sibling))\n                      },\n                      \n                      \n                      #' @description Adds a \\code{Node} after this \\code{Node}, as a sibling.\n                      #'  \n                      #' @param sibling The \\code{\"Node\"} to add as a sibling.\n                      #' \n                      #' @examples \n                      #' root <- Node$new(\"myroot\")\n                      #' child <- Node$new(\"mychild\")\n                      #' sibling <- Node$new(\"sibling\")\n                      #' root$AddChildNode(child)$AddSiblingNode(sibling)\n                      #' \n                      #' @return the added sibling node (this lets you chain calls, as in the examples)\n                      #' \n                      AddSiblingNode = function(sibling) {\n                        if(isRoot(self)) stop(\"Cannot insert sibling to root!\")\n                        private$p_parent[[sibling$name]] <- sibling\n                        private$p_parent$children <- append(private$p_parent$children, sibling, after = self$position)\n                        names(private$p_parent$children)[self$position + 1] <- sibling$name\n                        sibling$parent <- private$p_parent\n                        invisible (sibling)\n                      },\n                      \n                      \n                      #' @description Remove the child \\code{Node} called \\code{name} from a \\code{Node} and returns it.\n                      #' \n                      #' @examples \n                      #' node <- Node$new(\"myroot\")$AddChild(\"mychild\")$root\n                      #' node$RemoveChild(\"mychild\")\n                      #' \n                      #' @return the subtree spanned by the removed child.  \n                      RemoveChild = function(name) {\n                        if (!name %in% names(private$p_children)) stop(paste0(\"Node \", self$name, \" does not contain child \", name))\n                        child <- private$p_children[[name]]\n                        self$RemoveAttribute(name)\n                        private$p_children <- private$p_children[-child$position]\n                        child$parent <- NULL\n                        return (child)\n                      },\n                      \n                      \n                      #' @description  Removes attribute called \\code{name} from this \\code{Node}. \n                      #' \n                      #' @param stopIfNotAvailable Gives an error if \\code{stopIfNotAvailable} and the attribute does not exist.\n                      #' \n                      #' @examples \n                      #' node <- Node$new(\"mynode\")\n                      #' node$RemoveAttribute(\"age\", stopIfNotAvailable = FALSE)\n                      #' node$age <- 27\n                      #' node$RemoveAttribute(\"age\")\n                      #' node\n                      #' \n                      RemoveAttribute = function(name, stopIfNotAvailable = TRUE) {\n                        attAvailable <- name %in% ls(self)\n                        if (stopIfNotAvailable && !attAvailable) stop(paste0(\"Node \", self$name, \" does not contain field \", name))\n                        else if (attAvailable) {\n                          rm(list = name, envir = self)\n                          return (TRUE)\n                        }\n                        return (FALSE)\n                      },\n                      \n                      \n                      # End Tree Creation\n                      ########################\n                      \n                      ########################\n                      ## Side Effects\n                      \n                      #' @description Sort children of a \\code{Node} or an entire \\code{data.tree} structure\n                      #' \n                      #' @details\n                      #' You can sort with respect to any argument of the tree. But note that sorting has\n                      #' side-effects, meaning that you modify the underlying, original data.tree object structure.\n                      #' \n                      #' See also \\code{\\link{Sort}} for the equivalent function.\n                      #' \n                      #' \n                      #' @param ... any parameters to be passed on the the attribute (in case it's a method or a \n                      #' function)\n                      #' @param decreasing sort order\n                      #' \n                      #' \n                      #' @return Returns the node on which Sort is called, invisibly. This can be useful to chain Node methods.\n                      #' \n                      #' @examples\n                      #' data(acme)\n                      #' acme$Do(function(x) x$totalCost <- Aggregate(x, \"cost\", sum), traversal = \"post-order\")\n                      #' Sort(acme, \"totalCost\", decreasing = FALSE)\n                      #' print(acme, \"totalCost\")\n                      #' \n                      Sort = function(attribute, ..., decreasing = FALSE, recursive = TRUE) {\n                        .Deprecated(\"Sort(node, ...)\")\n                        Sort(self, attribute, ..., decreasing = decreasing, recursive = recursive)  \n                      },\n                      \n                      \n                      #' @description Reverts the sort order of a \\code{Node}'s children.\n                      #' \n                      #' See also \\code{\\link{Revert}} for the equivalent function.\n                      #' \n                      #' \n                      #' @return returns the Node invisibly (for chaining)\n                      #'\n                      #' @seealso \\code{\\link{Node}}\n                      #' @seealso \\code{\\link{Sort}}\n                      #' @export\n                      Revert = function(recursive = TRUE) {\n                        .Deprecated(\"Revert(node, ...)\")\n                        Revert(self, recursive)\n                      },\n                      \n                      \n                      #' @description Prunes a tree. \n                      #' \n                      #' Pruning refers to removing entire subtrees. This function has side-effects, it modifies your data.tree structure!\n                      #' \n                      #' See also \\code{\\link{Prune}} for the equivalent function.\n                      #' \n                      #' @param pruneFun allows providing a a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \n                      #' If the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.\n                      #' @return the number of nodes removed\n                      #' \n                      #' @examples\n                      #' data(acme)\n                      #' acme$Do(function(x) x$cost <- Aggregate(x, \"cost\", sum))\n                      #' Prune(acme, function(x) x$cost > 700000)\n                      #' print(acme, \"cost\")\n                      #' \n                      Prune = function(pruneFun) {\n                        .Deprecated(\"Prune(node, ...)\")\n                        Prune(self, pruneFun = pruneFun)\n                      },\n                      \n                      \n                      # End Side Effects\n                      ###########################\n                      \n                      \n                      \n                      #' @description Climb a tree from parent to children, by provided criteria.\n                      #'\n                      #' @details \n                      #' This method lets you climb the tree, from crutch to crutch. On each \\code{Node}, the\n                      #' \\code{Climb} finds the first child having attribute value equal to the the provided argument.\n                      #' \n                      #' See also \\code{\\link{Climb}} and \\code{\\link{Navigate}}\n                      #'\n                      #' Climb(node, ...)\n                      #'\n                      #'\n                      #' @param node The root \\code{\\link{Node}} of the tree or subtree to climb\n                      #' @param ... an attribute-value pairlist to be searched. For brevity, you can also provide a character vector to search for names.\n                      #' @return the \\code{Node} having path \\code{...}, or \\code{NULL} if such a path does not exist\n                      #'\n                      #' @examples\n                      #' data(acme)\n                      #'\n                      #' #the following are all equivalent\n                      #' Climb(acme, 'IT', 'Outsource')\n                      #' Climb(acme, name = 'IT', name = 'Outsource')\n                      #' Climb(acme, 'IT')$Climb('Outsource')\n                      #' Navigate(acme, path = \"IT/Outsource\")\n                      #'\n                      #' Climb(acme, name = 'IT')\n                      #'\n                      #' Climb(acme, position = c(2, 1))\n                      #' #or, equivalent:\n                      #' Climb(acme, position = 2, position = 1)\n                      #' Climb(acme, name = \"IT\", cost = 250000)\n                      #'\n                      #' tree <- CreateRegularTree(5, 2)\n                      #' tree$Climb(c(\"1\", \"1\"), position = c(2, 2))$path\n                      #'\n                      #'\n                      Climb = function(...) {\n                        Climb(self, ...)\n                      },\n  \n                      \n                      #' @description Navigate to another node by relative path.\n                      #'\n                      #'\n                      #' @param node The starting \\code{\\link{Node}} to navigate\n                      #' @param path A string or a character vector describing the path to navigate\n                      #'\n                      #' @details The \\code{path} is always relative to the \\code{Node}. Navigation\n                      #' to the parent is defined by \\code{..}, whereas navigation to a child\n                      #' is defined via the child's name.\n                      #' If path is provided as a string, then the navigation steps are separated\n                      #' by '/'.\n                      #' \n                      #' See also \\code{\\link{Navigate}} and \\code{\\link{Climb}}\n                      #'\n                      #' @examples\n                      #' data(acme)\n                      #' Navigate(acme$Research, \"../IT/Outsource\")\n                      #' Navigate(acme$Research, c(\"..\", \"IT\", \"Outsource\"))\n                      #'\n                      Navigate = function(path) {\n                        .Deprecated(\"Navigate(node, ...)\")\n                        Navigate(self, path)\n                      },\n                      \n                      \n                      \n                      \n                      ##########################\n                      # Traversal\n                      \n                      \n                      #' @description Traverse a Tree and Collect Values\n                      #' \n                      #' @details \n                      #' The \\code{Get} method is one of the most important ones of the \\code{data.tree} package. It lets you traverse a tree\n                      #' and collect values along the way. Alternatively, you can call a method or a function on each \\code{\\link{Node}}.\n                      #' \n                      #' See also \\code{\\link{Get}}, \\code{\\link{Node}}, \\code{\\link{Set}}, \\code{\\link{Do}}, \\code{\\link{Traverse}}\n                      #' \n                      #' \n                      #' \n                      #' \n                      #' @param attribute determines what is collected. The \\code{attribute} can be\n                      #'       \\itemize{\n                      #'         \\item a.) the name of a \\bold{field} or a \\bold{property/active} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"p\")} or \\code{acme$Get(\"position\")}\n                      #'         \\item b.) the name of a \\bold{method} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"levelZeroBased\")}, where e.g. \\code{acme$levelZeroBased <- function() acme$level - 1}\n                      #'         \\item c.) a \\bold{function}, whose first argument must be a \\code{Node} e.g. \\code{acme$Get(function(node) node$cost * node$p)}\n                      #'        }\n                      #' @param ... in case the \\code{attribute} is a function or a method, the ellipsis is passed to it as additional arguments.\n                      #' @param format if \\code{FALSE} (the default), no formatting is being used. If \\code{TRUE}, then the first formatter (if any) found along the ancestor path is being used for formatting \n                      #' (see \\code{\\link{SetFormat}}). If \\code{format} is a function, then the collected value is passed to that function, and the result is returned.\n                      #' @param inheritFromAncestors if \\code{TRUE}, then the path above a \\code{Node} is searched to get the \\code{attribute} in case it is NULL.\n                      #' @param simplify same as \\code{\\link{sapply}}, i.e. TRUE, FALSE or \"array\". Additionally, you can specify \"regular\" if\n                      #' each returned value is of length > 1, and equally named. See below for an example.\n                      #'        \n                      #' @return a vector containing the \\code{atrributes} collected during traversal, in traversal order. \\code{NULL} is converted\n                      #' to NA, such that \\code{length(Node$Get) == Node$totalCount}\n                      #'  \n                      #'  \n                      #' @examples\n                      #' data(acme)\n                      #' acme$Get(\"level\")\n                      #' acme$Get(\"totalCount\")\n                      #'  \n                      #'\n                      #' acme$Get(function(node) node$cost * node$p,\n                      #'          filterFun = isLeaf)\n                      #' \n                      #' #This is equivalent:\n                      #' nodes <- Traverse(acme, filterFun = isLeaf)\n                      #' Get(nodes, function(node) node$cost * node$p)\n                      #' \n                      #'    \n                      #' #simplify = \"regular\" will preserve names\n                      #' acme$Get(function(x) c(position = x$position, level = x$level), simplify = \"regular\")\n                      #'  \n                      Get = function(attribute, \n                                     ..., \n                                     traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"),  \n                                     pruneFun = NULL,\n                                     filterFun = NULL, \n                                     format = FALSE,\n                                     inheritFromAncestors = FALSE,\n                                     simplify = c(TRUE, FALSE, \"array\", \"regular\")) {\n                        t <- Traverse(self, \n                                      traversal = traversal, \n                                      pruneFun = pruneFun,\n                                      filterFun = filterFun)\n                        Get(t, \n                            attribute, \n                            ...,  \n                            format = format, \n                            inheritFromAncestors = inheritFromAncestors,\n                            simplify = simplify)\n\n                      },\n                      \n                      \n                      \n                      #' @description Executes a function on a set of nodes\n                      #' \n                      #' @details \n                      #' See also \\code{\\link{Node}}, \\code{\\link{Get}}, \\code{\\link{Set}}, \\code{\\link{Traverse}}\n                      #' \n                      #' @param fun the function to execute. The function is expected to be either a Method, or to take a \n                      #' Node as its first argument\n                      #' \n                      #' @examples \n                      #' data(acme)\n                      #' acme$Do(function(node) node$expectedCost <- node$p * node$cost)\n                      #' print(acme, \"expectedCost\")\n                      #' \n                      Do = function( fun, \n                                     ..., \n                                     traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"),  \n                                     pruneFun = NULL,\n                                     filterFun = NULL \n                                     ) {\n                        \n                        t <- Traverse(self, \n                                      traversal = traversal, \n                                      pruneFun = pruneFun,\n                                      filterFun = filterFun)\n                        Do(t, fun, ...)\n                        \n                      },\n                      \n                      \n                      \n                      #' @description Traverse a Tree and Assign Values\n                      #' \n                      #' @details \n                      #' The method takes one or more vectors as an argument. It traverses the tree, whereby the values are picked\n                      #' from the vector. Also available as OO-style method on \\code{\\link{Node}}.\n                      #' \n                      #' See also \\code{\\link{Node}}, \\code{\\link{Get}}, \\code{\\link{Do}}, \\code{\\link{Traverse}}\n                      #' \n                      #' \n                      #' \n                      #' @param ... each argument can be a vector of values to be assigned. Recycled.\n                      #'\n                      #' @return invisibly returns the nodes (useful for chaining)  \n                      #'  \n                      #' @examples\n                      #' data(acme)\n                      #' acme$Set(departmentId = 1:acme$totalCount, openingHours = NULL, traversal = \"post-order\")\n                      #' acme$Set(head = c(\"Jack Brown\", \n                      #'                   \"Mona Moneyhead\", \n                      #'                   \"Dr. Frank N. Stein\", \n                      #'                   \"Eric Nerdahl\"\n                      #'                   ),\n                      #'          filterFun = function(x) !x$isLeaf\n                      #'         )\n                      #' print(acme, \"departmentId\", \"head\")\n                      #'  \n                      Set = function(..., \n                                     traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"),  \n                                     pruneFun = NULL,\n                                     filterFun = NULL) {\n                        t <- Traverse(self, \n                                      traversal = traversal, \n                                      pruneFun = pruneFun,\n                                      filterFun = filterFun)\n                        Set(t, ...)\n                        invisible (self)\n                      }\n                                \n                      # End Traversal\n                      #######################\n                           \n                      \n                      \n                    ),\n                \n                \n                    active = list(\n                      \n                      #' @field name Gets or sets the name of a \\code{Node}. For example \\code{Node$name <- \"Acme\"}.\n                      name = function(value) {\n                        if (missing(value)) return (private$p_name)\n                        else private$p_name <- changeName(self, private$p_name, value)\n                      },\n                      \n                      #' @field printFormatters gets or sets the formatters used to print a \\code{Node}.\n                      #' Set this as a list to a root node.\n                      #' The different formatters are h (horizontal), v (vertical), l (L), j (junction), and s (separator). \n                      #' For example, you can set the formatters to \\code{list(h = \"\\u2500\" , v = \"\\u2502\", l = \"\\u2514\",  j = \"\\u251C\", s = \" \")}\n                      #' to get a similar behavior as in \\code{fs::dir_tree()}.\n                      #' The defaults are: \\code{list(h = \"--\" , v = \"\\u00A6\", l = \"\\u00B0\", j = \"\\u00A6\", s = \" \")}\n                      printFormatters = function(value) {\n                        if (missing(value)) {\n                          # if private$p_print_formatters is not set, return default\n                          if (is.null(private$p_print_formatters)) {\n                            pf <- list(h = \"--\" , \n                                       v = \"\\u00A6\", \n                                       l = \"\\u00B0\", \n                                       j = \"\\u00A6\",\n                                       s = \" \"\n                                       )\n                          } else {\n                            pf <- private$p_print_formatters\n                          }\n                          \n                          return (pf)\n                        }\n                        private$p_print_formatters <- value\n                      },   \n                      \n\n                      #' @field parent Gets or sets the parent \\code{Node} of a \\code{Node}. Only set this if you know what you are doing, as you might mess up the tree structure!\n                      parent = function(value) {\n                        if (missing(value)) return (private$p_parent)\n                        if (!is.null(value) && !is(value, \"Node\")) stop(\"Cannot set the parent to a non-Node!\")\n                        private$p_parent <- value\n                      },\n                      \n                      #' @field children Gets or sets the children \\code{list} of a \\code{Node}. Only set this if you know what you are doing, as you might mess up the tree structure!\n                      children = function(value) {\n                        if (missing(value)) return (private$p_children)\n                        if (!is.null(value) && !is.list(value)) stop(\"Cannot set children to non-list!\")\n                        private$p_children <- value\n                      },\n                      \n                      #' @field isLeaf Returns \\code{TRUE} if the \\code{Node} is a leaf, \\code{FALSE} otherwise\n                      isLeaf = function() {\n                        isLeaf(self) \n                      },\n                      \n                      #' @field isRoot Returns \\code{TRUE} if the \\code{Node} is the root, \\code{FALSE} otherwise\n                      isRoot = function() {\n                        isRoot(self)\n                      },\n                      \n                      #' @field count Returns the number of children of a \\code{Node}\n                      count = function() {\n                        return (length(private$p_children))\n                      },\n                      \n                      #' @field totalCount Returns the total number of \\code{Node}s in the tree\n                      totalCount = function() {\n                        return (1 + sum(as.numeric(sapply(private$p_children, function(x) x$totalCount, simplify = TRUE, USE.NAMES = FALSE))))\n                      }, \n                      \n                      #' @field path Returns a vector of mode \\code{character} containing the names of the \\code{Node}s in the path from the root to this \\code{Node}\n                      path = function() {\n                        c(private$p_parent$path, self$name)\n                      }, \n                      \n                      #' @field pathString Returns a string representing the path to this \\code{Node}, separated by backslash\n                      pathString = function() {\n                        paste(self$path, collapse=\"/\")\n                      },\n                      \n                      #' @field position The position of a \\code{Node} within its siblings\n                      position = function() {\n                        if (isRoot(self)) return (1)\n                        \n                        result <- which(names(private$p_parent$children) == self$name)\n                        # match(self$name, names(private$p_parent$children))\n                        return (result)\n                      },\n                                    \n                      #' @field fields Will be deprecated, use \\code{attributes} instead\n                      fields = function() {\n                        .Deprecated(\"Node$attributes\", old = \"Node$fields\")\n                        return(self$attributes)\n                      },\n                      \n                      #' @field fieldsAll Will be deprecated, use \\code{attributesAll} instead\n                      fieldsAll = function() {\n                        .Deprecated(\"Node$attributesAll\", old = \"Node$fieldsAll\")\n                        return(self$attributesAll)\n                      },\n                      \n                      #' @field attributes The attributes defined on this specific node        \n                      attributes = function() {\n                        nms <- ls(self)\n                        nms <- nms[!(nms %in% NODE_RESERVED_NAMES_CONST)]\n                        nms <- nms[!(nms %in% names(private$p_children))]\n                        nms <- nms[!(stri_sub(nms, 1, 1) == '.')]\n                        return (nms)\n                      },\n                      \n                      #' @field attributesAll The distinct union of attributes defined on all the nodes in the tree spanned by this \\code{Node}\n                      attributesAll = function() {\n                        as.vector(na.omit(unique(unlist(Get(Traverse(self), \"attributes\", simplify = FALSE)))))\n                      },\n                      \n                      #' @field levelName Returns the name of the \\code{Node}, preceded by level times '*'. Useful for printing and not typically called by package users.\n                      levelName = function() {\n                        paste0(.separator(self), self$name)\n                      },\n                      \n                      \n                      #' @field leaves Returns a list containing all the leaf \\code{Node}s\n                      leaves = function() {\n                        if (self$isLeaf) {\n                          return (list(self))\n                        } else {\n                          unlist(sapply(private$p_children, function(x) x$leaves))\n                        }\n                      },\n                      \n                      #' @field leafCount Returns the number of leaves are below a \\code{Node}\n                      leafCount = function() {\n                        length(Traverse(self, filterFun = isLeaf))\n                      },\n                      \n                      #' @field level Returns an integer representing the level of a \\code{Node}. For example, the root has level 1.\n                      level = function() {\n                        if (isRoot(self)) {\n                          return (1)\n                        } else {\n                          return (1 + private$p_parent$level)\n                        }\n                      },\n                      \n                      #' @field height Returns max(level) of any of the \\code{Nodes} of the tree\n                      height = function() {\n                        if (isLeaf(self)) return (1)\n                        max(Get(Traverse(self, filterFun = function(x) isLeaf(x) && x$position == 1), \"level\")) - self$level + 1\n                      },\n                      \n                      #' @field isBinary Returns \\code{TRUE} if all \\code{Node}s in the tree (except the leaves) have \\code{count = 2}\n                      isBinary = function() {\n                        all(2 == Get(Traverse(self, filterFun = function(x) !x$isLeaf), \"count\"))\n                      },\n                      \n                      #' @field root Returns the root of a \\code{Node} in a tree.\n                      root = function() {\n                        if (isRoot(self)) {\n                          invisible (self)\n                        } else {\n                          invisible (private$p_parent$root)\n                        }\n                      },\n                      \n                      #' @field siblings Returns a \\code{list} containing all the siblings of this \\code{Node}\n                      siblings = function() {\n                        if (isRoot(self)) {\n                          return (list())\n                        } else {\n                          private$p_parent$children[names(private$p_parent$children) != self$name]\n                        }\n                      },\n                      \n                      #' @field averageBranchingFactor Returns the average number of crotches below this \\code{Node}\n                      averageBranchingFactor = function() {\n                        averageBranchingFactor(self)\n                      }\n                      \n                      \n                      \n                      \n                    ),\n                \n                    private = list(\n                      \n                      p_name = \"\",\n                      p_children = NULL,\n                      p_parent = NULL\n                      \n                    )\n                  )\n\n"
  },
  {
    "path": "R/node_actives.R",
    "content": "\n#' Check if a \\code{Node} is the root\n#'\n#' @param node The Node to test.\n#' @return TRUE if the Node is the root, FALSE otherwise\n#' @export\nisRoot <- function(node) {\n  is.null(node$parent)\n}\n\n\n#' Check if a \\code{Node} is not a root\n#'\n#' @param node The Node to test.\n#' @return FALSE if the Node is the root, TRUE otherwise\n#' @export\nisNotRoot <- function(node) {\n  !isRoot(node)\n}\n\n#' Check if a \\code{Node} is a leaf\n#'\n#' @param node The Node to test.\n#' @return TRUE if the Node is a leaf, FALSE otherwise\n#' @export\nisLeaf <- function(node) {\n  length(node$children) == 0\n}\n\n#' Check if a \\code{Node} is not a leaf\n#'\n#' @param node The Node to test.\n#' @return FALSE if the Node is a leaf, TRUE otherwise\n#' @export\nisNotLeaf <- function(node) {\n  !isLeaf(node)\n}\n\n\nchangeName <- function(node, oldName, newName) {\n  if(!isRoot(node)) {\n    rm(list = oldName, envir = node$parent)\n    names(node$parent$children)[node$position] <- newName\n    node$parent[[as.character(newName)]] <- node\n  }\n  return (newName)\n}\n\n#' @export\n.separator <- function(self) {\n  if (isRoot(self)) return(\"\")\n  if (self$position == self$parent$count) mySeparator <- paste0(self$root$printFormatters$s, self$root$printFormatters$l, self$root$printFormatters$h)\n  else mySeparator <- paste0(self$root$printFormatters$s, self$root$printFormatters$j, self$root$printFormatters$h)\n  return (paste0(.parentSeparator(self$parent), mySeparator))\n}\n\n#' @export\n.parentSeparator <- function(self) {\n  if (isRoot(self)) return(\"\")\n  \n  if (self$position == self$parent$count) mySeparator <- paste0(rep(self$root$printFormatters$s, 4), collapse = \"\")\n  else mySeparator <- paste0(self$root$printFormatters$s, self$root$printFormatters$v, self$root$printFormatters$s, self$root$printFormatters$s)\n  paste0(.parentSeparator(self$parent), mySeparator)\n  \n}\n\n#' Calculate the average number of branches each non-leaf has\n#'\n#' @param node The node to calculate the average branching factor for\n#' @export\naverageBranchingFactor <- function(node) {\n  t <- Traverse(node, filterFun = isNotLeaf)\n  if (length(t) == 0) return (0)\n  cnt <- Get(t, \"count\")\n  if (!is.numeric(cnt)) browser()\n  return (mean(cnt))\n}\n\n"
  },
  {
    "path": "R/node_conversion.R",
    "content": "\n\n\n#' Convert an object to a \\code{data.tree} data structure\n#' \n#' @param x The object to be converted\n#' @param ... Additional arguments\n#' \n#' @family as.Node\n#' \n#' @export\nas.Node <- function(x, ...) {\n  UseMethod(\"as.Node\")\n}\n\n\n  \n\n\n#' Write a \\code{data.tree} structure to Newick notation\n#' \n#' To read from Newick, you can use the \\code{ape} package, and convert the resulting \\code{phylo}\n#' object to a \\code{data.tree} structure.\n#' \n#' @param node The root \\code{Node} of a tree or sub-tree to be converted\n#' @param heightAttribute The attribute (field name, method, or function) storing or calculating the height for each \\code{Node}\n#' @param ... parameters that will be passed on the the heightAttributeName, in case it is a function\n#' \n#' @import stringi\n#' \n#' @examples\n#' data(acme)\n#' ToNewick(acme)\n#' ToNewick(acme, heightAttribute = NULL)\n#' ToNewick(acme, heightAttribute = function(x) DefaultPlotHeight(x, 200))\n#' ToNewick(acme, rootHeight = 200)\n#' \n#' @family Conversions from Node\n#' \n#' @keywords Newick\n#' \n#' @export \nToNewick <- function(node, heightAttribute = DefaultPlotHeight, ...) {\n\n  deparse <- function(x) {\n    name <- stri_replace_all_fixed(x$name, \" \", \"_\")\n    name <- stri_replace_all_fixed(name, \",\", \"\")\n    if(!isRoot(x) && length(heightAttribute) > 0) {\n      edge <- GetAttribute(x$parent, heightAttribute, ...) - GetAttribute(x, heightAttribute, ...) \n      me <- paste0(name, \":\", edge)\n    } else {\n      me <- name\n    }\n    return(me)\n  }\n  \n  Newick <- function(x) {\n    if(x$isLeaf) {\n      return (deparse(x))\n    }\n    chNewick <- sapply(x$children, Newick)\n    chNewickStr <- paste(chNewick, collapse = \",\")\n    res <- paste0(\"(\", chNewickStr, \")\", deparse(x))\n  }\n  \n  res <- Newick(node)\n  res <- paste0(res, \";\")\n  return (res)\n  \n}\n\n"
  },
  {
    "path": "R/node_conversion_ape.R",
    "content": "\n\n#' Convert a \\code{Node} to a phylo object from the ape package.\n#' \n#' This method requires the ape package to be installed and loaded.\n#' \n#' @param x The root \\code{Node} of the tree or sub-tree to be converted\n#' @param heightAttribute The attribute (field name or function) storing the height\n#' @param ... any other argument\n#' \n#' @examples\n#' library(ape)\n#' data(acme)\n#' acmephylo <- as.phylo(acme)\n#' #plot(acmephylo)\n#' \n#' \n#' @family ape phylo conversions\n#' \n#' @export\nas.phylo.Node <- function(x, heightAttribute = DefaultPlotHeight, ...) {\n  txt <- ToNewick(x, heightAttribute)\n  return (ape::read.tree(text = txt))\n}\n\n\n#' Convert a \\code{phylo} object from the ape package to a \\code{Node}\n#' \n#' @param x The phylo object to be converted\n#' @param heightName If the phylo contains edge lengths, then they will be converted\n#' to a height and stored in a field named according to this parameter (the default is \"height\")\n#' @param replaceUnderscores if TRUE (the default), then underscores in names are replaced with spaces\n#' @param namesNotUnique if TRUE, then the \\code{name} of the \\code{Node}s will be prefixed with a unique id.\n#' This is useful if the children of a parent have non-unique names.\n#' @param ... any other parameter to be passed to sub-implementations\n#' \n#' @examples\n#' #which bird familes have the max height?\n#' library(ape)\n#' data(bird.families)\n#' bf <- as.Node(bird.families)\n#' height <- bf$height\n#' t <- Traverse(bf, filterFun = function(x) x$level == 25)\n#' Get(t, \"name\")\n#' \n#' @family ape phylo conversions\n#' @family as.Node\n#' \n#' @export\nas.Node.phylo <- function(x, heightName = \"plotHeight\", replaceUnderscores = TRUE, namesNotUnique = FALSE, ...) {\n  \n  #find root node\n  rootNr <- unique(x$edge[,1][!x$edge[,1] %in% x$edge[,2]])\n  \n  #names\n  nodeNrs <- c(rootNr, unique(x$edge[,2]))\n  leafNrs <- 1:length(x$tip.label)\n  nms <- x$tip.label\n  names(nms) <- leafNrs\n  if(\"node.label\" %in% names(x)) {\n    nms2 <- x$node.label\n  } else {\n    nms2 <- (max(leafNrs) + 1):max(nodeNrs)\n  }\n  names(nms2) <- (max(leafNrs) + 1):max(nodeNrs)\n  nms <- c(nms2, nms)\n  root <- Node$new(rootNr)\n  for (i in 1:nrow(x$edge)) {\n    e <- x$edge[i,]\n    fifu <- function(x) x$name == as.character(e[1])\n    parent <- Traverse(root, filterFun = fifu)[[1]]\n    child <- parent$AddChild(as.character(e[2]))\n  }\n  if (length(x$edge.length) > 0) {\n    t <- Traverse(root, filterFun = isNotRoot)\n    Set(t, edgeLength = x$edge.length)\n    #try converting edge length to height\n    root[[heightName]] <- 0\n    ehf <- function(x) x[[heightName]] <- x$parent[[heightName]] - x$edgeLength \n    Do(t, ehf)\n    corr <- min(Get(t, heightName))\n    root$Do(function(x) x[[heightName]] <- x[[heightName]] - corr)\n    Do(t, function(x) rm(\"edgeLength\", envir = x))\n  }\n  \n  setName <- function(x) {\n    if (replaceUnderscores) nm <- stri_replace_all_fixed( nms[[x$name]], \"_\", \" \")\n    else nm <- nms[[x$name]]\n    if (namesNotUnique) x$name <- paste0(x$name, \": \", nm)\n    else x$name <- nm\n  }\n  root$Do(setName)\n  \n  return (root)\n  \n}\n\n\n\n\n#' Determine the number a \\code{Node} has after conversion to a phylo object\n#' \n#' Use this function when plotting a Node as a phylo, e.g. to set custom\n#' labels to plot.\n#' \n#' @param x The Node\n#' @param type Either \"node\" (the default) or \"edge\" (to get the number of the edge from \\code{x} to its parent)\n#' @return an integer representing the node\n#' \n#' @examples\n#' library(ape)\n#' library(data.tree)\n#' data(acme)\n#' ap <- as.phylo(acme)\n#' #plot(ap)\n#' #nodelabels(\"IT Dep.\", GetPhyloNr(Climb(acme, \"IT\")))\n#' #edgelabels(\"Good!\", GetPhyloNr(Climb(acme, \"IT\", \"Switch to R\"), \"edge\"))\n#' \n#' \n#' @family ape phylo conversions\n#' \n#' @export\nGetPhyloNr <- function(x, type = c(\"node\", \"edge\")) {\n  type <- type[1]\n  if (type == \"node\") {\n    t <- c(Traverse(x$root, filterFun = isLeaf), Traverse(x$root, filterFun = isNotLeaf))    \n  } else if (type == \"edge\") {\n    t <- Traverse(x$root, filterFun = isNotRoot)\n  } else {\n    stop(\"Only node or edge allowed as type\")\n  }\n  res <- which(sapply(t, function(z) identical(z, x)))\n  return (res)\n}\n"
  },
  {
    "path": "R/node_conversion_dataframe.R",
    "content": "#' Convert a \\code{data.tree} structure to a \\code{data.frame}\n#'\n#' If a node field contains data of length > 1, then that is converted into a string in the\n#' data.frame. \n#'\n#' @param x The root \\code{Node} of the tree or sub-tree to be convert to a data.frame\n#' @param ... the attributes to be added as columns of the data.frame. See \\code{\\link{Get}} for details.\n#' If a specific Node does not contain the attribute, \\code{NA} is added to the data.frame.\n#' @param traversal any of 'pre-order' (the default), 'post-order', 'in-order', 'level', or 'ancestor'. See \\code{\\link{Traverse}} for details.\n#' @param direction when converting to a network, should the edges point from root to children (\"climb\") or from child to parent (\"descend\")?\n#' @param type when converting type columns, the \\code{type} is the discriminator, i.e. an attribute (e.g. field name) of each node\n#' @param prefix when converting type columns, the prefix used for the column names. Can be NULL to omit prefixes.\n#' @param filterFun a function taking a \\code{Node} as an argument. See \\code{\\link{Traverse}} for details.\n#' @param format if \\code{FALSE} (the default), then no formatting will be applied. If \\code{TRUE}, then the first formatter (if any) along the ancestor\n#' path is used for formatting. \n#' @param inheritFromAncestors if FALSE, and if the attribute is a field or a method, then only a \\code{Node} itself is\n#' searched for the field/method. If TRUE, and if the \\code{Node} does not contain the attribute, then ancestors are also searched.\n#' @param row.names \\code{NULL} or a character vector giving the row names for the data frame.\n#' Missing values are not allowed.\n#' @param optional logical. If \\code{TRUE}, setting row names and converting column names\n#' (to syntactic names: see make.names) is optional.\n#'\n#'\n#' @examples\n#' data(acme)\n#' acme$attributesAll\n#' as.data.frame(acme, row.names = NULL, optional = FALSE, \"cost\", \"p\")\n#'\n#' ToDataFrameTree(acme, \"cost\", \"p\")\n#' ToDataFrameNetwork(acme, \"cost\", \"p\", direction = \"climb\")\n#' ToDataFrameTable(acme, \"cost\", \"p\")\n#' ToDataFrameTypeCol(acme)\n#'\n#' #use the pruneFun:\n#' acme$Do(function(x) x$totalCost <- Aggregate(x, \"cost\", sum), traversal = \"post-order\")\n#' ToDataFrameTree(acme, \"totalCost\", pruneFun = function(x) x$totalCost > 300000)\n#'\n#' #inherit\n#' acme$Set(floor = c(1, 2, 3), filterFun = function(x) x$level == 2)\n#' as.data.frame(acme, row.names = NULL, optional = FALSE, \"floor\", inheritFromAncestors = FALSE)\n#' as.data.frame(acme, row.names = NULL, optional = FALSE, \"floor\", inheritFromAncestors = TRUE)\n#'\n#' #using a function as an attribute:\n#' acme$Accounting$Head <- \"Mrs. Numright\"\n#' acme$Research$Head <- \"Mr. Stein\"\n#' acme$IT$Head <- \"Mr. Squarehead\"\n#' ToDataFrameTable(acme, department = function(x) x$parent$name, \"name\", \"Head\", \"cost\")\n#'\n#' #complex TypeCol\n#' acme$IT$Outsource$AddChild(\"India\")\n#' acme$IT$Outsource$AddChild(\"Poland\")\n#' acme$Set(type = c('company', 'department', 'project', 'project', 'department',\n#'                   'project', 'project', 'department', 'program', 'project',\n#'                   'project', 'project', 'project'\n#'                   )\n#'         )\n#' print(acme, 'type')\n#' ToDataFrameTypeCol(acme, type = 'type')\n#'\n#' @inheritParams Prune\n#'\n#' @export\nas.data.frame.Node <- function(x,\n                               row.names = NULL,\n                               optional = FALSE,\n                               ...,\n                               traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"),\n                               pruneFun = NULL,\n                               filterFun = NULL,\n                               format = FALSE,\n                               inheritFromAncestors = FALSE\n) {\n\n  traversal <- traversal[1]\n\n  if(!isRoot(x) || length(pruneFun) > 0) {\n    #clone s.t. x is root (for pretty level names)\n    x <- Clone(x, attributes = TRUE)\n    if (length(pruneFun) > 0) Prune(x, pruneFun)\n    x$parent <- NULL\n  }\n\n  t <- Traverse(x, traversal = traversal, filterFun = filterFun)\n\n  df <- data.frame( levelName = format(Get(t, 'levelName')),\n                    row.names = row.names,\n                    stringsAsFactors = FALSE)\n\n  cols <- list(...)\n\n  if(length(cols) == 0) return (df)\n  for (i in 1:length(cols)) {\n    col <- cols[[i]]\n    if (length(names(cols)) > 0 && nchar(names(cols)[i]) > 0) colName <- names(cols)[i]\n    else if (is.character(col)) colName <- col\n    else stop(paste0(\"Cannot infer column name for ... arg nr \", i))\n    if (length(col) > 1) {\n      it <- col\n    } else {\n      it <- Get(t, \n                col,\n                format = format, \n                inheritFromAncestors = inheritFromAncestors,\n                simplify = FALSE)\n      it <- lapply(it, \n                   function(el) {\n                          if (inherits(el, \"Node\")) return (\"\")\n                          else if (length(unlist(el)) > 1) return (toString(unlist(el)))\n                          else if (length(unlist(el)) == 0) return (NA)\n                          else return (el)\n                   }\n                )\n    }\n    df[colName] <- unlist(it)\n\n  }\n\n  return (df)\n\n}\n\n\n\n#' @rdname as.data.frame.Node\n#' @return ToDataFrameTree: a \\code{data.frame}, where each row represents a \\code{Node} in the tree or sub-tree\n#' spanned by \\code{x}, possibly pruned according to \\code{pruneFun}.\n#'\n#' @export\nToDataFrameTree <- function(x, ..., pruneFun = NULL) {\n  as.data.frame(x, row.names = NULL, optional = FALSE, ..., pruneFun = pruneFun)\n}\n\n#' @rdname as.data.frame.Node\n#'\n#'\n#' @return ToDataFrameTable: a \\code{data.frame}, where each row represents a leaf \\code{Node} in the tree or sub-tree\n#' spanned by \\code{x}, possibly pruned according to \\code{pruneFun}.\n#'\n#'\n#' @export\nToDataFrameTable <- function(x, ..., pruneFun = NULL) {\n  df <- as.data.frame(x, row.names = NULL, optional = FALSE, ..., filterFun = isLeaf, pruneFun = pruneFun, inheritFromAncestors = TRUE)\n  df[,-1]\n}\n\n\n\n#' @rdname as.data.frame.Node\n#'\n#' @return ToDataFrameNetwork: a \\code{data.frame}, where each row represents a \\code{Node} in the tree or sub-tree\n#' spanned by \\code{x}, possibly pruned according to \\code{pruneFun}. The first column is called 'from', while the\n#' second is called 'to', describing the parent to child edge (for direction \"climb\") or the child to parent edge (for direction \"descend\").\n#' If \\code{\\link{AreNamesUnique}} is TRUE, then the Network is\n#' based on the \\code{Node$name}, otherwise on the \\code{Node$pathString}\n#'\n#'\n#' @export\nToDataFrameNetwork <- function(x,\n                               ...,\n                               direction = c(\"climb\", \"descend\"),\n                               pruneFun = NULL,\n                               format = FALSE,\n                               inheritFromAncestors = FALSE) {\n  direction <- direction[1]\n  if(!AreNamesUnique(x)) GetName <- function(x) x$pathString\n  else GetName <- function(x) x$name\n  t <- Traverse(x, traversal = \"level\", pruneFun = pruneFun)\n  children <- Get(t, function(x) GetName(x))\n  parents <- Get(t, function(x) GetName(x$parent))\n\n  if (direction == \"descend\") df <- data.frame(from = children,\n                                             to = parents,\n                                             stringsAsFactors = FALSE)\n\n  else if(direction == \"climb\") df <- data.frame(from = parents,\n                                                  to = children,\n                                                  stringsAsFactors = FALSE)\n\n  else stop(paste0(\"direction \", direction, \" unknown. Must be either climb or descend.\"))\n\n  df2 <- ToDataFrameTree(x, ..., traversal = \"level\", pruneFun = pruneFun, format = format, inheritFromAncestors = inheritFromAncestors)[,-1, drop = FALSE]\n\n  df <- cbind(df, df2)\n  df <- df[-1,]\n  rownames(df) <- seq_len(nrow(df))\n  return (df)\n}\n\n\n\n#' @rdname as.data.frame.Node\n#'\n#' @return ToDataFrameTypeCol: a \\code{data.frame} in table format (i.e. where each row represents a leaf in the tree or sub-tree\n#' spanned by \\code{x}), possibly pruned according to \\code{pruneFun}. In addition to \\code{...}, each distinct\n#' \\code{type} is output to a column.\n#'\n#'\n#' @export\nToDataFrameTypeCol <- function(x,\n                               ...,\n                               type = 'level',\n                               prefix = type,\n                               pruneFun = NULL) {\n  cols <- unique(c(x$Get(type, filterFun = isNotLeaf), x$Get(type, filterFun = isLeaf)))\n\n\n  pathArgs <- GetPathArgV(cols, type)\n  if (is.null(prefix)) names(pathArgs) <- as.character(cols)\n  else names(pathArgs) <- paste0(prefix, '_', cols)\n  do.call(ToDataFrameTable, c(x, pathArgs, ...))\n}\n\n\nGetPathArg <- function(n, type) {\n  lvl <- force(n)\n  f <- function(leaf) {\n    path <- leaf$Get(type, traversal = 'ancestor')\n    name <- names(path[path == lvl])\n    if (length(name) == 0) name <- NA\n    return (name)\n  }\n  return (f)\n}\n\nGetPathArgV <- Vectorize(GetPathArg, vectorize.args = 'n')\n\n\n\n#' Convert a \\code{data.frame} to a \\code{data.tree} structure\n#'\n#' @param x The data.frame in the required format.\n#' @param ... Any other argument implementations of this might need\n#' @param mode Either \"table\" (if x is a data.frame in tree or table format) or \"network\"\n#' @param na.rm If \\code{TRUE}, then NA's are treated as NULL and values will not be set on nodes\n#'\n#' @return The root \\code{Node} of the \\code{data.tree} structure\n#'\n#' @examples\n#' data(acme)\n#'\n#' #Tree\n#' x <- ToDataFrameTree(acme, \"pathString\", \"p\", \"cost\")\n#' x\n#' xN <- as.Node(x)\n#' print(xN, \"p\", \"cost\")\n#'\n#' #Table\n#' x <- ToDataFrameTable(acme, \"pathString\", \"p\", \"cost\")\n#' x\n#' xN <- FromDataFrameTable(x)\n#' print(xN, \"p\", \"cost\")\n#'\n#' #More complex Table structure, using colLevels\n#' acme$Set(floor = c(1, 2, 3),  filterFun = function(x) x$level == 2)\n#' x <- ToDataFrameTable(acme, \"pathString\", \"floor\", \"p\", \"cost\")\n#' x\n#' xN <- FromDataFrameTable(x, colLevels = list(NULL, \"floor\", c(\"p\", \"cost\")), na.rm = TRUE)\n#' print(xN, \"floor\", \"p\", \"cost\")\n#'\n#' #Network\n#' x <- ToDataFrameNetwork(acme, \"p\", \"cost\", direction = \"climb\")\n#' x\n#' xN <- FromDataFrameNetwork(x)\n#' print(xN, \"p\", \"cost\")\n#'\n#' @seealso \\code{\\link{as.data.frame.Node}}\n#' @family as.Node\n#'\n#' @export\nas.Node.data.frame <- function(x,\n                               ...,\n                               mode = c(\"table\", \"network\"),\n                               pathName = 'pathString',\n                               pathDelimiter = '/',\n                               colLevels = NULL,\n                               na.rm = TRUE) {\n\n  mode <- mode[1]\n  if (mode == 'table') return (FromDataFrameTable(x, pathName, pathDelimiter, colLevels, na.rm))\n  else if (mode == 'network') return (FromDataFrameNetwork(x))\n  else stop(paste0(\"Mode \", mode, \" unknown.\"))\n\n}\n\n\n#' @rdname as.Node.data.frame\n#'\n#' @param table a \\code{data.frame} in table or tree format, i.e. having a row for each leaf (and optionally\n#' for additional nodes). There should be a column called \\code{pathName}, separated by \\code{pathDelimiter},\n#' describing the path of each row.\n#' @param pathName The name of the column in x containing the path of the row\n#' @param pathDelimiter The delimiter used to separate nodes in \\code{pathName}\n#' @param colLevels Nested list of column names, determining on what node levels the attributes are written to.\n#'\n#' @inheritParams CheckNameReservedWord\n#'\n#' @export\nFromDataFrameTable <- function(table,\n                               pathName = 'pathString',\n                               pathDelimiter = '/',\n                               colLevels = NULL,\n                               na.rm = TRUE,\n                               check = c(\"check\", \"no-warn\", \"no-check\")\n                               ) {\n  \n  if (!is(table, \"data.frame\")) stop(\"table must be a data.frame\")\n  #make sure tibble etc. work (#115)\n  table <- as.data.frame(table)\n  \n  table[[pathName]] <- as.character(table[[pathName]])\n  root <- NULL\n  mycols <- names(table)[ !(names(table) %in% c(NODE_RESERVED_NAMES_CONST, pathName)) ]\n  for (i in 1:nrow(table)) {\n    myrow <- table[ i, , drop = FALSE]\n    mypath <- myrow[[pathName]]\n    myvalues <- myrow[!colnames(myrow) == pathName]\n\n    #create node and ancestors if necessary (might already have been created)\n    paths <- strsplit(mypath, pathDelimiter, fixed = TRUE)[[1]]\n    paths <- paths[paths!=\"\"]\n    if (is.null(root)) root <- Node$new(paths[1], check)\n    mynode <- root\n    colsToSet <- mycols\n    colsToSetForLeaf <- mycols\n    for (path in paths[-1]) {\n\n      \n      path <- CheckNameReservedWord(path, check)\n\n      child <- Climb(mynode, path)\n\n      if( is.null(child)) {\n        mynode <- mynode$AddChild(path)\n      } else {\n        mynode <- child\n      }\n\n      if( length(colLevels) >= mynode$level ) {\n        colsToSet <- intersect(colLevels[[mynode$level]], mycols)\n\n        #fill values on appropriate level\n        for (mycol in colsToSet) {\n          if ( !( na.rm && is.na(myrow[[mycol]]) )) {\n            mynode[[mycol]] <- myrow[[mycol]]\n          }\n        }\n        colsToSetForLeaf <- colsToSetForLeaf[!(colsToSetForLeaf %in% colsToSet)]\n      }\n\n    }\n\n    #put the rest in the leaf\n    for (mycol in colsToSetForLeaf) {\n      if ( !( na.rm && is.na(myrow[[mycol]]) )) {\n        mynode[[mycol]] <- myrow[[mycol]]\n      }\n      #remove\n    }\n\n\n  }\n  return (root)\n\n}\n\n#' @rdname as.Node.data.frame\n#'\n#' @param network A \\code{data.frame} in network format, i.e.\n#' it must adhere to the following requirements:\n#' \\itemize{\n#'  \\item{It must contain as many rows as there are nodes (excluding the root, there is no row for the root)}\n#'  \\item{Its first and second columns contain the network relationships. This can be either climbing (from parent to children) or descending (from child to parent)}\n#'  \\item{Its subsequent columns contain the attributes to be set on the nodes}\n#'  \\item{It must contain a single root}\n#'  \\item{There are no cycles in the network}\n#' }\n#'\n#' @import methods\n#' \n#' @inheritParams CheckNameReservedWord\n#'\n#' @export\nFromDataFrameNetwork <- function(network, check = c(\"check\", \"no-warn\", \"no-check\")) {\n\n  if (!is(network, \"data.frame\")) stop(\"network must be a data.frame\")\n  #make sure tibble etc. work (#115)\n  network <- as.data.frame(network)\n  if (dim(network)[2] < 2) stop(\"network must hold the relationships in the first two columns\")\n\n  if (length(unique(network[ , 1])) > length(unique(network[ , 2]))) {\n    children <- network[ , 1]\n    parents <- network[ , 2]\n  } else {\n    children <- network[ , 2]\n    parents <- network[ , 1]\n  }\n\n  rootName <- unique(parents[!(parents %in% children)])\n  if (length(rootName) != 1) stop(\"Cannot find root name. network is not a tree!\")\n\n  root <- Node$new(rootName, check)\n  AddChildren <- function(node) {\n    childrenIdxs <- which(parents == node$name)\n    for (idx in childrenIdxs) {\n      nodeName <- children[idx]\n      child <- node$AddChild(nodeName)\n      if (dim(network)[2] > 2) {\n        for (j in 3:dim(network)[2]) {\n          vlu <- network[idx, j]\n          if (!is.na(vlu)) {\n            nm <- names(network)[j]\n            nm <- CheckNameReservedWord(nm, check)\n            if (!nm %in% NODE_RESERVED_NAMES_CONST) child[[nm]] <- network[idx, j]\n          }\n        }\n      }\n      AddChildren(child)\n    }\n  }\n  AddChildren(root)\n\n  return (root)\n}\n\n"
  },
  {
    "path": "R/node_conversion_dendrogram.R",
    "content": "\n\n#' Convert a \\code{\\link{dendrogram}} to a data.tree \\code{Node}\n#' \n#' @param x The dendrogram\n#' @param name The name of the root Node\n#' @param heightName The name under which the dendrogram's height is stored\n#' @param ... Additional parameters\n#' \n#' @return The root \\code{Node} of a \\code{data.tree}\n#' \n#' @examples\n#' hc <- hclust(dist(USArrests), \"ave\")\n#' dend1 <- as.dendrogram(hc)\n#' tree1 <- as.Node(dend1)\n#' tree1$attributesAll\n#' tree1$totalCount\n#' tree1$leafCount\n#' tree1$height\n#'   \n#' @family as.Node\n#' \n#' @inheritParams CheckNameReservedWord\n#' \n#' @export\nas.Node.dendrogram <- function(x, name = \"Root\", heightName = \"plotHeight\", check = c(\"check\", \"no-warn\", \"no-check\"),  ...) {\n  #str(unclass(dend1))\n  if (is.leaf(x)) {\n    name <- attr(x, 'label')\n  } else if(is.null(name) && is.null(attr(x, \"edgetext\"))) {\n    name <- tempfile(pattern = '', tmpdir = '')\n  } else if(!is.null(attr(x, \"edgetext\"))) {\n    name <- attr(x, \"edgetext\")\n  }\n  \n  n <- Node$new(name, check)\n  reserved <- c('label', 'class', 'comment', 'dim', 'dimnames', 'names', 'row.names', 'tsp', NODE_RESERVED_NAMES_CONST)\n  ats <- names(attributes(x))\n  for (a in ats[!(ats %in% reserved)]) {\n    n[[a]] <- attr(x, a)\n  }\n  n[[heightName]] <- attr(x, \"height\")\n  \n  if (!is.leaf(x)) {\n    for (i in 1:length(x)) {\n      childNode <- as.Node.dendrogram(x[[i]], name = NULL, ...)\n      n$AddChildNode(childNode)\n      if(!is.leaf(x[[i]])) {\n        name <- as.character(childNode$position)\n        childNode$name <- name\n      }\n    }\n  } else {\n    n$value <- as.vector(x)\n  }\n  return (n)\n  \n}\n\n\n#' Convert a \\code{Node} to a \\code{dendrogram}\n#' \n#' Convert a \\code{data.tree} structure to a \\code{\\link{dendrogram}}\n#' \n#' @param object The Node to convert\n#' @param heightAttribute The attribute (field name or function) storing the height\n#' @param edgetext If TRUE, then the for non-leaf nodes the node name is stored as the dendrogram's edge text.\n#' @param ... Additional parameters\n#' \n#' @return An object of class dendrogram\n#' \n#' @examples\n#' data(acme)\n#' acmed <- as.dendrogram(acme)\n#' plot(acmed, center = TRUE)\n#' \n#' #you can take an attribute for the height:\n#' acme$Do( function(x) x$myPlotHeight <- (10 - x$level))\n#' acmed <- as.dendrogram(acme, heightAttribute = \"myPlotHeight\")\n#' plot(acmed, center = TRUE)\n#' \n#' #or directly a function\n#' acmed <- as.dendrogram(acme, heightAttribute = function(x) 10 - x$level)\n#' plot(acmed)\n#' \n#' @family Conversions from Node\n#'\n#' @import stats\n#' @export\nas.dendrogram.Node <- function(object, heightAttribute = DefaultPlotHeight, edgetext = FALSE, ...) {\n  node <- object\n  \n  #strange: the original dendrogram will\n  # unclass the nested dendrograms as well,\n  # while ours won't?\n  #\n  # hc <- hclust(dist(USArrests), \"ave\")\n  # dend1 <-d as.dendrogram(hc)\n  # node <- as.Node(dend1)\n  # dend2 <- as.dendrogram(node)\n  # unclass(dend1)\n  # unclass(dend2)\n  \n  height <- as.vector(GetAttribute(node, heightAttribute))\n\n  if (node$isLeaf) {\n    res <- node$value\n    if (is.null(res)) res <- 0\n    res <- structure(res, \n                     label = node$name, \n                     members = 1,\n                     height = height,\n                     leaf = node$isLeaf,\n                     class = \"dendrogram\")\n    \n  } else {\n    #res <- list()\n    #class(res) <- \"dendrogram\"\n    res <- unname(lapply(node$children, FUN = function(x) as.dendrogram(x, heightAttribute, ...)))\n    res <- structure(res, \n                     members = node$leafCount,\n                     midpoint = node$midpoint,\n                     height = height,\n                     class = \"dendrogram\")\n    \n    if (edgetext) attr(res, \"edgetext\") <- node$name\n    \n  }\n  \n  return (res)\n  \n}\n"
  },
  {
    "path": "R/node_conversion_igraph.R",
    "content": "\n#' Convert a \\code{data.tree} structure to an igraph network\n#' \n#' This requires the igraph package to be installed.\n#' Also, this requires the names of the \\code{Nodes} to be unique within\n#' the \\code{data.tree} structure.\n#' \n#' @param x The root \\code{Node} to convert\n#' @param vertexAttributes A vector of strings, representing the attributes \n#' in the \\code{data.tree} structure to add as attributes to the vertices of the igraph\n#' @param edgeAttributes A vector of strings, representing the attributes\n#' in the \\code{data.tree} structure to add as edge attributes of the igraph\n#' @param ... Currently unused.\n#' \n#' @inheritParams igraph::graph_from_data_frame\n#' @inheritParams ToDataFrameNetwork\n#'\n#' @return an \\code{igraph} object\n#'   \n#' @examples\n#' data(acme)\n#' library(igraph)\n#' ig <- as.igraph(acme, \"p\", c(\"level\", \"isLeaf\"))\n#' plot(ig)\n#' \n#' @seealso AreNamesUnique\n#' \n#' @export\nas.igraph.Node <- function(x, vertexAttributes = character(), edgeAttributes = character(), directed = FALSE, direction = c(\"climb\", \"descend\"), ...) {\n  if (!AreNamesUnique(x)) stop(\"Node names must be unique within the tree\")\n  network <- do.call(\"ToDataFrameNetwork\", c(x, \"name\", vertexAttributes, edgeAttributes, direction = direction))\n  data <- network[,c(\"from\", \"to\", edgeAttributes)]\n  vert <- do.call(\"ToDataFrameTree\", c(x, \"name\", vertexAttributes))[,-1]\n  ig <- igraph::graph_from_data_frame(data, \n                                      directed = directed,\n                                      vertices = vert)\n  return (ig)\n}"
  },
  {
    "path": "R/node_conversion_list.R",
    "content": "#' Convert a nested \\code{list} structure to a \\code{data.tree} structure\n#' \n#' @param x The \\code{list} to be converted.\n#' @param mode How the list is structured. \"simple\" (the default) will interpret any list to be a child. \"explicit\" \n#' assumes that children are in a nested list called \\code{childrenName}\n#' @param nameName The name of the element in the list that should be used as the name, can be NULL if mode = explicit and\n#' the children lists are named, or if an automatic name (running number) should be assigned\n#' @param childrenName The name of the element that contains the child list (applies to mode 'explicit' only).\n#' @param nodeName A name suggestion for x, if the name cannot be deferred otherwise. This is for example the case for\n#' the root with mode explicit and named lists.\n#' @param interpretNullAsList If \\code{TRUE}, then \\code{NULL}-valued lists are interpreted as child nodes. Else, they are interpreted as attributes.\n#' This has only an effect if \\code{mode} is \"simple\".\n#' @param ... Any other argument to be passed to generic sub implementations\n#' \n#' @examples\n#' kingJosephs <- list(name = \"Joseph I\",\n#'                     spouse = \"Mary\",\n#'                     born = \"1818-02-23\",\n#'                     died = \"1839-08-29\",\n#'                     children = list(\n#'                                     list(name = \"Joseph II\",\n#'                                          spouse = \"Kathryn\",\n#'                                          born = \"1839-03-28\",\n#'                                          died = \"1865-12-19\"),\n#'                                     list(name = \"Helen\",\n#'                                          born = \"1840-17-08\",\n#'                                          died = \"1845-01-01\")\n#'                                     )\n#'                    )\n#' FromListExplicit(kingJosephs)\n#' \n#' kingJosephs <- list(head = \"Joseph I\",\n#'                     spouse = \"Mary\",\n#'                     born = \"1818-02-23\",\n#'                     died = \"1839-08-29\",\n#'                     list(head = \"Joseph II\",\n#'                          spouse = \"Kathryn\",\n#'                          born = \"1839-03-28\",\n#'                          died = \"1865-12-19\"),\n#'                     list(head = \"Helen\",\n#'                          born = \"1840-17-08\",\n#'                          died = \"1845-01-01\")       \n#'                    )\n#' FromListSimple(kingJosephs, nameName = \"head\")\n#' \n#' kingJosephs <- list(spouse = \"Mary\",\n#'                     born = \"1818-02-23\",\n#'                     died = \"1839-08-29\",\n#'                     `Joseph II` = list(spouse = \"Kathryn\",\n#'                                        born = \"1839-03-28\",\n#'                                        died = \"1865-12-19\"),\n#'                     Helen = list(born = \"1840-17-08\",\n#'                                  died = \"1845-01-01\")\n#'                                  \n#'                    )\n#' FromListSimple(kingJosephs, nodeName = \"Joseph I\")\n#'   \n#' @inheritParams CheckNameReservedWord\n#' @family as.Node\n#' \n#' @export\nas.Node.list <- function(x, mode = c(\"simple\", \"explicit\"), nameName = \"name\", childrenName = \"children\", nodeName = NULL, interpretNullAsList = FALSE, check = c(\"check\", \"no-warn\", \"no-check\"), ...) {\n  mode <- mode[1]\n  check <- check[1]\n  \n  #find my name\n  if (is.null(nameName) || !(nameName %in% names(x))) {\n    if (length(nodeName)==0) myName <- \"Root\"\n    else myName <- nodeName\n  } else {\n    myName <- x[[nameName]]\n  }\n  \n  n <- Node$new(as.character(myName), check = check)\n  \n  #set attributes\n  \n  #find attributes that need importing\n  attributes <- names(x)\n  \n  #capture attributes without names\n  if (is.null(attributes) && length(x) !=0) {\n    attributes <- rep(\"\", length(x))\n  }\n  field_nums <- seq_along(x)\n  unnamed_attributes <- attributes == \"\" & !vapply(x, is.list, logical(1))\n  \n  #exclude nameName\n  if(!is.null(nameName)) {\n    field_nums <- field_nums[attributes != nameName]\n    unnamed_attributes <- unnamed_attributes[attributes != nameName]\n    attributes <- attributes[attributes != nameName]\n    \n  }\n  #exclude childrenName if explicit\n  if (mode == \"explicit\") {\n    field_nums <- field_nums[attributes != childrenName]\n    unnamed_attributes <- unnamed_attributes[attributes != childrenName]\n    attributes <- attributes[attributes != childrenName]\n    \n  }\n  \n  attributes[unnamed_attributes] <- seq_along(which(unnamed_attributes))\n  \n  \n  if (check != \"no-check\") {\n    fieldNameIsReserved <- (attributes %in% NODE_RESERVED_NAMES_CONST) & !(attributes %in% c(nameName, childrenName))\n    if (any(fieldNameIsReserved) && (check != \"no-warn\")) warning(paste0(\"The following names are data.tree reserved words and will be appended with 2: \", paste(attributes[fieldNameIsReserved], sep = \", \"), \".\" ))\n  }\n  \n  for (i in seq_along(field_nums)) {\n    v <- x[[field_nums[i]]]\n    \n    if(mode == 'simple' && inherits(v, 'list')) {\n      #any list is interpreted as child, so don't store\n    } else {\n      fieldNm <- attributes[i]\n      if (fieldNm %in% NODE_RESERVED_NAMES_CONST) fieldNm <- paste0(fieldNm, \"2\")\n      n[[fieldNm]] <- v\n    }\n  }\n  \n  #children\n  if (is.character(x)) return (n)\n  if (mode == 'simple') {\n    if (interpretNullAsList) children <- x[vapply(x, function(y) is.list(y) || is.null(y), logical(1))]\n    else children <- x[vapply(x, is.list, logical(1))]\n  }\n  else if (mode == 'explicit') children <- x[[childrenName]]\n  \n  if (length(children) == 0) return (n)\n  \n  for (i in 1:length(children)) {\n    if (any(duplicated(names(children)))) {\n      childName <- \"\"\n    } else if (is.character(children)) {\n      childName <- children[i]\n    } else if (!is.null(names(children))) {\n      childName <- names(children)[i]\n    } else {\n      childName <- \"\"\n    }\n    if (nchar(childName) == 0) childName <- i\n    child <- children[[i]]\n    \n    childNode <- as.Node.list(child, mode, nameName, childrenName, nodeName = childName, interpretNullAsList = interpretNullAsList, check = check, ...)\n    n$AddChildNode(childNode)\n    \n  }\n  \n  \n  return (n)\n  \n}\n\n#' @rdname as.Node.list\n#' \n#' @param explicitList A \\code{list} in which children are in a separate nested list called \\code{childrenName}.\n#' \n#' @export\nFromListExplicit <- function(explicitList, nameName = \"name\", childrenName = \"children\", nodeName = NULL, check = c(\"check\", \"no-warn\", \"no-check\")) {\n  as.Node.list(explicitList, mode = \"explicit\", nameName = nameName, childrenName = childrenName, nodeName = nodeName, check = check)\n}\n\n\n#' @rdname as.Node.list\n#' \n#' @param simpleList A \\code{list} in which children are stored as nested list alongside other attributes. Any list is\n#' interpreted as a child \\code{Node}\n#' \n#' @export\nFromListSimple <- function(simpleList, nameName = \"name\", nodeName = NULL, interpretNullAsList = FALSE, check = c(\"check\", \"no-warn\", \"no-check\")) {\n  as.Node.list(simpleList, mode = \"simple\", nameName = nameName, nodeName = nodeName, interpretNullAsList = interpretNullAsList, check = check)\n}\n\n\n\n\n\n\n#' Convert a \\code{data.tree} structure to a list-of-list structure\n#' \n#' @param x The Node to convert\n#' @param mode How the list is structured. \"simple\" (the default) will add children directly as nested lists.\n#' \"explicit\" puts children in a separate nested list called \\code{childrenName}\n#' @param unname If TRUE, and if \\code{mode} is \"explicit\", then the nested children list will not have named arguments. This\n#' can be useful e.g. in the context of conversion to JSON, if you prefer the children to be\n#' an array rather than named objects.\n#' @param nameName The name that should be given to the name element\n#' @param childrenName The name that should be given to the children nested list\n#' @param rootName The name of the node. If provided, this overrides \\code{Node$name}\n#' @param keepOnly A character vector of attributes to include in the result. If \\code{NULL} (the default), all attributes are kept.\n#' @param ... Additional parameters passed to \\code{as.list.Node}\n#' \n#' @examples\n#' data(acme)\n#' \n#' str(ToListSimple(acme))\n#' str(ToListSimple(acme, keepOnly = \"cost\"))\n#' \n#' str(ToListExplicit(acme))\n#' str(ToListExplicit(acme, unname = TRUE))\n#' str(ToListExplicit(acme, unname = TRUE, nameName = \"id\", childrenName = \"descendants\"))\n#'\n#' @inheritParams Prune\n#' \n#' @export\nas.list.Node <- function(x, \n                         mode = c(\"simple\", \"explicit\"),\n                         unname = FALSE, \n                         nameName = ifelse(unname, \"name\", \"\"), \n                         childrenName = 'children',\n                         rootName = '',\n                         keepOnly = NULL,\n                         pruneFun = NULL,\n                         ...) {\n  mode <- mode[1]\n  self <- x\n  res <- list()\n  \n  myname <- if (nchar(rootName) != 0) rootName else x$name\n  \n  if (nchar(nameName) != 0 || nchar(rootName) != 0 || isRoot(x)) {\n    l_nameName <- nameName\n    if (nchar(nameName) == 0) l_nameName <- \"name\"\n    res[l_nameName] <- myname\n  }\n  \n  attributes <- self$attributes\n  attributes <- attributes[!is.function(attributes) && !is.environment(attributes)]\n  \n  if (!is.null(keepOnly) & !all(is.na(attributes))) attributes <- attributes[attributes %in% keepOnly]\n  \n  for (attributeName in attributes) res[[attributeName]] <- self[[attributeName]]\n  \n  if (!self$isLeaf) {\n    children <- self$children\n    if (length(pruneFun) > 0) {\n      filter <- unlist(lapply(children, pruneFun))\n      children <- children[filter]\n    }\n    kids <- lapply(children, FUN = function(x) as.list.Node(x, mode, unname, nameName, childrenName, keepOnly = keepOnly, pruneFun = pruneFun, ...))\n    if (mode == \"explicit\") {\n      res[[childrenName]] <- kids\n      if (unname) res[[childrenName]] <- unname(res[[childrenName]])\n    } else if (mode == \"simple\") {\n      res <- c(res, kids)\n    } else {\n      stop(paste0(\"Mode \", mode, \" unknown\"))\n    }\n  }\n  return(res)\n  \n}\n\n\n#' @rdname as.list.Node\n#' \n#' @export\nToListSimple <- function(x, nameName = \"name\", pruneFun = NULL, ...) {\n  as.list.Node(x, mode = \"simple\", nameName = nameName, pruneFun = pruneFun, ...)\n}\n\n\n#' @rdname as.list.Node\n#'  \n#'\n#' @export \nToListExplicit <- function(x, unname = FALSE, nameName = ifelse(unname, \"name\", \"\"), childrenName = 'children', pruneFun = NULL, ...) {\n  as.list.Node(x, mode = \"explicit\", unname = unname, nameName = nameName, childrenName = childrenName, pruneFun = pruneFun, ...) \n}\n"
  },
  {
    "path": "R/node_conversion_party.R",
    "content": "\n#' Convert a a \\code{SplitNode} from the party package to a \\code{data.tree} structure.\n#' \n#' @param x The BinaryTree\n#' @param ... additional arguments (unused)\n#' \n#' @examples \n#' library(party)\n#' airq <- subset(airquality, !is.na(Ozone))\n#' airct <- ctree(Ozone ~ ., data = airq, \n#'                controls = ctree_control(maxsurrogate = 3))\n#'                \n#' tree <- as.Node(airct)\n#' tree\n#' \n#' print(tree, \n#'       \"label\", \n#'       criterion = function(x) round(x$criterion$maxcriterion, 3),\n#'       statistic = function(x) round(max(x$criterion$statistic), 3)\n#'       )\n#' \n#' FindNode(tree, 6)$path\n#' \n#' \n#' @export\n#'  \nas.Node.BinaryTree <- function(x, ...) {\n  CreateNodeFromSplittingNode(x@tree)\n}\n\n\n\n\n\n\n\nCreateNodeFromSplittingNode <- function(splittingNode, left = TRUE) {\n  node <- Node$new(splittingNode$nodeID,\n                   weights = splittingNode$weights,\n                   criterion = splittingNode$criterion,\n                   psplit = splittingNode$psplit,\n                   ssplit = splittingNode$ssplit,\n                   label = GetSplittingNodeLabel(splittingNode, left))\n  \n  if (!splittingNode$terminal) {\n    node$AddChildNode( CreateNodeFromSplittingNode(splittingNode$left) )\n    node$AddChildNode( CreateNodeFromSplittingNode(splittingNode$right, left = FALSE) )\n  }\n  \n  return (node)\n}\n\n\nGetSplittingNodeLabel <- function(splittingNode, left) {\n  if( splittingNode$terminal ) {\n    paste0(\"weights = \", sum(splittingNode$weights))\n  } else {\n    as.character.orderedSplit(splittingNode$psplit, left)\n  }\n}\n\n\n\nas.character.orderedSplit <- function(x, left = TRUE, ...) \n{\n  if (!is.null(attr(x$splitpoint, \"levels\"))) {\n    sp <- attr(x$splitpoint, \"levels\")[x$splitpoint]\n  }\n  else {\n    sp <- x$splitpoint\n  }\n  if (!is.null(x$toleft)) \n    left <- as.logical(x$toleft) == left\n  if (left) {\n    res <- paste0(x$variableName, \" <= \", sp)\n  }\n  else {\n    res <- paste0(x$variableName, \" > \", sp)\n  }\n  return (res)\n}\n\n\n\n\n\n#' Convert a a \\code{party} from the partykit package to a \\code{data.tree} structure.\n#' \n#' @param x The party object\n#' @param ... other arguments (unused)\n#' \n#' @examples \n#' library(partykit)\n#' data(\"WeatherPlay\", package = \"partykit\")\n#' ### splits ###\n#' # split in overcast, humidity, and windy\n#' sp_o <- partysplit(1L, index = 1:3)\n#' sp_h <- partysplit(3L, breaks = 75)\n#' sp_w <- partysplit(4L, index = 1:2)\n#' \n#' ## query labels\n#' character_split(sp_o)\n#' \n#' ### nodes ###\n#' ## set up partynode structure\n#' pn <- partynode(1L, split = sp_o, kids = list(\n#'   partynode(2L, split = sp_h, kids = list(\n#'       partynode(3L, info = \"yes\"),\n#'       partynode(4L, info = \"no\"))),\n#'   partynode(5L, info = \"yes\"),\n#'   partynode(6L, split = sp_w, kids = list(\n#'       partynode(7L, info = \"yes\"),\n#'       partynode(8L, info = \"no\")))))\n#' pn\n#' ### tree ###\n#' ## party: associate recursive partynode structure with data\n#' py <- party(pn, WeatherPlay)\n#' tree <- as.Node(py)\n#' \n#' print(tree, \n#'       \"splitname\",\n#'       count = function(node) nrow(node$data), \n#'       \"splitLevel\")\n#' \n#' SetNodeStyle(tree, \n#'              label = function(node) paste0(node$name, \": \", node$splitname), \n#'              tooltip = function(node) paste0(nrow(node$data), \" observations\"),\n#'              fontname = \"helvetica\")\n#' SetEdgeStyle(tree, \n#'              arrowhead = \"none\", \n#'              label = function(node) node$splitLevel,\n#'              fontname = \"helvetica\",\n#'              penwidth = function(node) 12 * nrow(node$data)/nrow(node$root$data),\n#'              color = function(node) {\n#'                paste0(\"grey\", \n#'                       100 - as.integer( 100 * nrow(node$data)/nrow(node$root$data))\n#'                       )\n#'              }\n#'              )\n#' Do(tree$leaves, \n#'    function(node) {\n#'      SetNodeStyle(node, \n#'                   shape = \"box\", \n#'                   color = ifelse(node$splitname == \"yes\", \"darkolivegreen4\", \"lightsalmon4\"),\n#'                   fillcolor = ifelse(node$splitname == \"yes\", \"darkolivegreen1\", \"lightsalmon\"),\n#'                   style = \"filled,rounded\",\n#'                   penwidth = 2\n#'                   )\n#'    }\n#'    )\n#' \n#' plot(tree)\n#' \n#' \n#' @export\nas.Node.party <- function(x, ...) {\n  \n  tree <- FromParty(x, x$node)\n  tree$Do(function(node) node$splitLevel <- node$parent$splitlevels[node$position], filterFun = isNotRoot)\n  return (tree)\n}\n\n\n\nFromParty <- function(party, partynode) {\n  stopifnot(inherits(party, \"party\"))\n  node <- Node$new(partynode$id)\n  for (childnode in partynode$kids) {\n    childid <- childnode$id\n    childparty <- party[[as.character(childid)]]\n    node$AddChildNode(FromParty(childparty, childnode))\n  }\n  node$data <- party$data\n  node$fitted <- party$fitted\n  node$partyinfo <- party$info\n  node$nodeinfo <- partynode$info\n  node$terms <- party$terms\n  node$split <- partynode$split\n  formatInfo <- partykit::formatinfo_node(partynode)\n  if (length(partynode) > 0) {\n    csplit <- partykit::character_split(partynode$split, party$data)\n    node$splitlevels <- csplit$levels\n    node$splitname <- csplit$name\n  } else if (identical(nchar(formatInfo) > 0, TRUE)) {\n    node$splitname <- formatInfo\n  }\n  \n  \n  return (node)\n}\n"
  },
  {
    "path": "R/node_conversion_rpart.R",
    "content": "#' Convert an \\code{\\link{rpart}} object to a \\code{data.tree} structure\n#'\n#' @param x the \\code{rpart} object to be converted\n#' @param digits the number of digits to be used for numeric values in labels\n#' @param use.n logical. Add cases to labels, see \\code{\\link{text.rpart}} for further\n#'              information\n#' @param ... any other argument to be passed to generic sub implementations\n#'\n#' @return a \\code{data.tree} object. The tree contains a field \\code{rpart.id} which\n#'         references back to the original node id in the row names of the \\code{rpart} object.\n#' @export\n#'\n#' @examples\n#' if (require(rpart)) {\n#'    fit <- rpart(Kyphosis ~ Age + Number + Start, data = kyphosis)\n#'    as.Node(fit)\n#' }\n#' @family as.Node\nas.Node.rpart <- function(x, \n                          digits = getOption(\"digits\") - 3,\n                          use.n  = FALSE,\n                          ...) {\n  frame       <- x$frame\n  ylevels     <- attr(x, \"ylevels\")\n  nodes       <- as.numeric(rownames(frame))\n  leaves      <- frame$var == \"<leaf>\"\n  leaf_labels <- x$functions$text(\n    yval   = if (is.null(frame$yval2)) frame$yval[leaves] else frame$yval2[leaves, ], \n    dev    = frame$dev[leaves], \n    wt     = frame$wt[leaves], \n    ylevel = ylevels, \n    digits = digits, \n    n      = frame$n[leaves], \n    use.n  = use.n)\n  node_labels <- setNames(c(labels(x)[which(!leaves) + 1L],\n                            leaf_labels),\n                          c(nodes[!leaves], nodes[leaves]))\n  network_df  <- data.frame(from     = node_labels[as.character(floor(nodes[-1L] / 2L))],\n                            to       = node_labels[as.character(nodes[-1L])],\n                            rpart.id = nodes[-1L])\n  tree <- FromDataFrameNetwork(network_df)\n  tree$rpart.id <- nodes[1L]\n  tree\n}"
  },
  {
    "path": "R/node_methods.R",
    "content": "#\n# These are the methods that would normally sit on Node\n# However, to reduce the memory footprint of the Node object,\n# we only support traditional R methods.\n# The first argument of all these methods is node\n\n\n#' Print a \\code{Node} in a human-readable fashion.\n#'\n#' @param x The Node\n#' @param ... Node attributes to be printed. Can be either a character (i.e. the name of a Node field),\n#' a Node method, or a function taking a Node as a single argument. See \\code{Get} for details on\n#' the meaning of \\code{attribute}.\n#' @param pruneMethod The method can be used to prune for printing in a simple way. If NULL, the entire tree is displayed. If\n#' \"simple\", then only the first \\code{limit} nodes are displayed. If \"dist\", then Nodes are removed\n#' everywhere in the tree, according to their level. If pruneFun is provided, then pruneMethod is ignored.\n#' @param limit The maximum number of nodes to print. Can be \\code{NULL} if the\n#' entire tree should be printed.\n#' @param row.names If \\code{TRUE} (default), then the row names are printed out. Else, they are not.\n#'\n#' @inheritParams ToDataFrameTree\n#'\n#' @examples\n#' data(acme)\n#' print(acme, \"cost\", \"p\")\n#' print(acme, \"cost\", probability = \"p\")\n#' print(acme, expectedCost = function(x) x$cost * x$p)\n#' do.call(print, c(acme, acme$attributesAll))\n#' \n#' tree <- CreateRegularTree(4, 5)\n#' # print entire tree:\n#' print(tree, pruneMethod = NULL)\n#' # print first 20 nodes:\n#' print(tree, pruneMethod = \"simple\", limit = 20)\n#' # print 20 nodes, removing leafs first:\n#' print(tree, pruneMethod = \"dist\", limit = 20)\n#' # provide your own pruning function:\n#' print(tree, pruneFun = function(node) node$position != 2)\n#' \n#'\n#' @export\nprint.Node <- function(x, ..., pruneMethod = c(\"simple\", \"dist\", NULL), limit = 100, pruneFun = NULL, row.names = T) {\n  if (length(pruneFun) > 0) pruneMethod <- NULL\n  pruneMethod <- pruneMethod[1]\n  if (length(pruneMethod) > 0 && length(limit) > 0) {\n    if (pruneMethod == \"simple\") {\n      x <- PrintPruneSimple(x, limit = limit)\n    } else if (pruneMethod == \"dist\") {\n      x <- PrintPruneDist(x, limit = limit)\n    } else {\n      stop (paste0(\"Unknown pruneMethod \", pruneMethod, \"!\"))\n    }\n  } else if(!isRoot(x)) {\n      #clone s.t. x is root (for pretty level names)\n      x <- Clone(x, attributes = TRUE)\n      x$parent <- NULL\n  }\n\n  df <- ToDataFrameTree(x, format = TRUE, ..., pruneFun = pruneFun)\n  print(df, na.print = \"\", row.names = row.names)\n}\n\n\n\n\n\n#' Aggregate child values of a \\code{Node}, recursively.\n#'\n#' The \\code{Aggregate} method lets you fetch an attribute from a \\code{Node}'s children, and then aggregate them\n#' using \\code{aggFun}. For example, you can aggregate cost by summing costs of child \\code{Nodes}. This is especially useful in the\n#' context of tree traversal, when using post-order traversal mode.\n#'\n#' As with \\code{\\link{Get}}, the attribute can be a field, a method or a function. If the attribute on a child\n#' is \\code{NULL}, \\code{Aggregate} is called recursively on its children.\n#'\n#' @param node the \\code{Node} on which to aggregate\n#' @param aggFun the aggregation function to be applied to the children's \\code{attributes}\n#' @param ... any arguments to be passed on to attribute (in case it's a function)\n#'\n#' @inheritParams Get\n#'\n#' @examples\n#' data(acme)\n#'\n#' #Aggregate on a field\n#' Aggregate(acme, \"cost\", sum)\n#'\n#' #This is the same as:\n#' HomeRolledAggregate <- function(node) {\n#'   sum(sapply(node$children, function(child) {\n#'     if (!is.null(child$cost)) child$cost\n#'     else HomeRolledAggregate(child)\n#'   }))\n#' }\n#' HomeRolledAggregate(acme)\n#'\n#' #Aggregate using Get\n#' print(acme, \"cost\", minCost = acme$Get(Aggregate, \"cost\", min))\n#'\n#' #use Aggregate with a function:\n#' Aggregate(acme, function(x) x$cost * x$p, sum)\n#'\n#' #cache values along the way\n#' acme$Do(function(x) x$cost <- Aggregate(x, \"cost\", sum), traversal = \"post-order\")\n#' acme$IT$cost\n#'\n#' @seealso \\code{\\link{Node}}\n#'\n#' @export\nAggregate = function(node,\n                     attribute,\n                     aggFun,\n                     ...) {\n\n  if(\"cacheAttribute\" %in% names(list(...))) stop(\"cacheAttribute not supported anymore! Please use Do instead.\")\n\n  if (isLeaf(node)) return ( GetAttribute(node, attribute, ...) )\n  values <- sapply(node$children,\n                   function(x) {\n                     v <- GetAttribute(x, attribute, format = identity, ...)\n                     if (length(v) > 0 && !any(is.na(v))) return(v)\n                     Aggregate(x, attribute, aggFun, ...)\n                   })\n  result <- unname(aggFun(values))\n\n  return (result)\n}\n\n#' Cumulate values among siblings\n#'\n#' For example, you can sum up values of siblings before\n#' this \\code{Node}.\n#'\n#' @param node The node on which we want to cumulate\n#'\n#' @inheritParams Aggregate\n#' @inheritParams Get\n#'\n#' @examples\n#' data(acme)\n#' acme$Do(function(x) x$cost <- Aggregate(x, \"cost\", sum), traversal = \"post-order\")\n#' acme$Do(function(x) x$cumCost <- Cumulate(x, \"cost\", sum))\n#' print(acme, \"cost\", \"cumCost\")\n#'\n#' @export\nCumulate = function(node, attribute, aggFun, ...) {\n  if (\"cacheAttribute\" %in% names(list(...))) stop(\"cacheAttribute not supported anymore! Please use Do instead.\")\n  if (isRoot(node)) return (GetAttribute(node, attribute))\n  pos <- node$position\n  nodes <- node$parent$children[1:pos]\n  res <- aggFun(Get(nodes, attribute))\n\n  return (res)\n}\n\n#' Clone a tree (creates a deep copy)\n#'\n#' The method also clones object attributes (such as the formatters), if desired.\n#' If the method is called on a non-root, then the parent relationship is not cloned,\n#' and the resulting \\code{\\link{Node}} will be a root.\n#'\n#' @param node the root node of the tree or sub-tree to clone\n#' @param attributes if FALSE, then R class attributes (e.g. formatters and grViz styles)\n#' are not cloned. This makes the method faster.\n#' @return the clone of the tree or sub-tree\n#'\n#' @examples\n#' data(acme)\n#' acmeClone <- Clone(acme)\n#' acmeClone$name <- \"New Acme\"\n#' # acmeClone does not point to the same reference object anymore:\n#' acme$name\n#'\n#' #cloning a subtree\n#' data(acme)\n#' itClone <- Clone(acme$IT)\n#' itClone$isRoot\n#'\n#'\n#' @inheritParams Prune\n#'\n#' @seealso SetFormat\n#'\n#' @export\nClone <- function(node, pruneFun = NULL, attributes = FALSE) {\n  .Clone(node, pruneFun, attributes)\n}\n\n\n\n.Clone <- function(node, pruneFun = NULL, attributes = FALSE, firstCall = TRUE) {\n\n  myclone <- node$clone()\n  if (attributes) attributes(myclone) <- attributes(node)\n  if (!is.null(pruneFun) && length(node$children) > 0) {\n    keep <- sapply(node$children, pruneFun)\n    children <- node$children[keep]\n    rm(list = names(node$children)[!keep], envir = myclone)\n  } else children <- node$children\n  myclone$children <- lapply(children, function(x) .Clone(x, pruneFun, attributes, firstCall = FALSE))\n  for (child in myclone$children) {\n    myclone[[child$name]] <- child\n    child$parent <- myclone\n  }\n  if (length(myclone$children) == 0) myclone$children <- NULL\n  if (firstCall) myclone$parent <- NULL #myclone$RemoveAttribute(\"parent\", stopIfNotAvailable = FALSE)\n  return (myclone)\n}\n\n\n#' Navigate to another node by relative path.\n#'\n#' @usage Navigate(node, path)\n#'\n#' @param node The starting \\code{\\link{Node}} to navigate\n#' @param path A string or a character vector describing the path to navigate\n#'\n#' @details The \\code{path} is always relative to the \\code{node}. Navigation\n#' to the parent is defined by \\code{..}, whereas navigation to a child\n#' is defined via the child's name.\n#' If path is provided as a string, then the navigation steps are separated\n#' by '/'.\n#'\n#' @examples\n#' data(acme)\n#' Navigate(acme$Research, \"../IT/Outsource\")\n#' Navigate(acme$Research, c(\"..\", \"IT\", \"Outsource\"))\n#'\n#' @seealso \\code{\\link{Climb}}\n#'\n#' @export\nNavigate <- function(node, path) {\n  if (length(path) == 1) path <- strsplit(path, \"/\", fixed = TRUE)[[1]]\n  for (nxt in path) {\n    if (identical(\"..\", nxt)) {\n      node <- node$parent\n    } else if (identical(\".\", nxt)) {\n      #don't do anything\n    } else {\n      node <- node[[nxt]]\n    }\n  }\n  return (node)\n}\n\n\n\n\n#' Climb a tree from parent to children, by provided criteria.\n#'\n#'\n#' This method lets you climb the tree, from crutch to crutch. On each \\code{Node}, the\n#' \\code{Climb} finds the first child having attribute value equal to the the provided argument.\n#'\n#' @usage #node$Climb(...)\n#' Climb(node, ...)\n#'\n#'\n#' @param node The root \\code{\\link{Node}} of the tree or subtree to climb\n#' @param ... an attribute-value pairlist to be searched. For brevity, you can also provide a character vector to search for names.\n#' @return the \\code{Node} having path \\code{...}, or \\code{NULL} if such a path does not exist\n#'\n#' @examples\n#' data(acme)\n#'\n#' #the following are all equivalent\n#' Climb(acme, 'IT', 'Outsource')\n#' Climb(acme, name = 'IT', name = 'Outsource')\n#' Climb(acme, 'IT')$Climb('Outsource')\n#' Navigate(acme, path = \"IT/Outsource\")\n#'\n#' Climb(acme, name = 'IT')\n#'\n#' Climb(acme, position = c(2, 1))\n#' #or, equivalent:\n#' Climb(acme, position = 2, position = 1)\n#' Climb(acme, name = \"IT\", cost = 250000)\n#'\n#' tree <- CreateRegularTree(5, 2)\n#' tree$Climb(c(\"1\", \"1\"), position = c(2, 2))$path\n#'\n#' @seealso \\code{\\link{Node}}\n#' @seealso \\code{\\link{Navigate}}\n#'\n#' @export\nClimb <- function(node, ...) {\n\n  path <- list(...)\n  if (length(path) == 0) {\n    return (node)\n  } else {\n\n    #convert args to standard\n    #e.g. id = (3, 5), name = \"myname\"\n    #to\n    # id = 3, id = 5, name = \"mynam\"\n    # path <- list(id = c(3, 5), \"myname\", c(\"bla\", \"blo\"))\n    # path <- list(id = 3, id = 5, name = \"myname\")\n    # path <- c(\"IT\")\n    mpath <- NULL\n    for (i in 1:length(path)) names(path[[i]]) <- rep(names(path)[i], length(path[[i]]))\n    for (i in 1:length(path)) mpath <- c(mpath, as.list(path[[i]]))\n\n    attribute <- names(mpath)[[1]]\n    if (length(attribute) == 0 || is.na(attribute) || nchar(attribute) == 0) attribute <- \"name\"\n\n\n    value <- mpath[[1]]\n\n    if (attribute == \"name\") child <- node[[value]]\n    else {\n      getA <- Get(node$children, attribute)\n      child <- node$children[getA == value][[1]]\n    }\n\n\n    if (is.null(child)) {\n      return (NULL)\n    } else if (length(mpath) == 1) {\n      return (child)\n    } else {\n      return (do.call(Climb, c(node = child, mpath[-1])))\n    }\n  }\n\n}\n\n\n\n#' Find a node by name in the (sub-)tree\n#'\n#' Scans the entire sub-tree spanned by \\code{node} and returns the first \\code{\\link{Node}}\n#' having the \\code{name} specified. This is mainly useful for trees whose name is unique.\n#' If \\code{\\link{AreNamesUnique}} is \\code{FALSE}, i.e. if there is more than one \\code{Node}\n#' called \\code{name} in the tree, then it is undefined which one will be returned.\n#' Also note that this method is not particularly fast. See examples for a faster way to\n#' index large trees, if you need to do multiple searches. See \\code{\\link{Traverse}} if\n#' you need to find multiple \\code{Nodes}.\n#'\n#' @param node The root \\code{Node} of the tree or sub-tree to search\n#' @param name The name of the \\code{Node} to be returned\n#'\n#' @return The first \\code{Node} whose name matches, or \\code{NULL} if no such \\code{Node} is\n#' found.\n#'\n#' @examples\n#' data(acme)\n#' FindNode(acme, \"Outsource\")\n#'\n#' #re-usable hashed index for multiple searches:\n#' if(!AreNamesUnique(acme)) stop(\"Hashed index works for unique names only!\")\n#' trav <- Traverse(acme, \"level\")\n#' names(trav) <- Get(trav, \"name\")\n#' nameIndex <- as.environment(trav)\n#' #you could also use hash from package hash instead!\n#' #nameIndex <- hash(trav)\n#' nameIndex$Outsource\n#' nameIndex$IT\n#'\n#'\n#' @seealso AreNamesUnique, Traverse\n#'\n#' @export\nFindNode <- function(node, name) {\n  trav <- Traverse(node, filterFun = function(x) x$name == name)\n  if (length(trav) == 0) return(NULL)\n  return(trav[[1]])\n}\n\n\n\n#' Find the distance between two nodes of the same tree\n#' \n#' The distance is measured as the number of edges that\n#' need to be traversed to reach node2 when starting \n#' from node1.\n#' \n#' @param node1 the first node in the tree\n#' @param node2 the second node in the same tree\n#' \n#' @examples \n#' data(acme)\n#' Distance(FindNode(acme, \"Outsource\"), FindNode(acme, \"Research\"))\n#' \n#' @export\nDistance <- function(node1, node2) {\n  if(!identical(node1$root, node2$root)) stop(\"node1 and node2 must be in same tree!\")\n  path1 <- node1$path\n  path2 <- node2$path\n  i <- 1\n  maxi <- min(node1$level, node2$level)\n  while (path1[i] == path2[i] && i <= maxi) i <- i + 1\n  distance <- length(path1) + length(path2) - 2 * (i - 1)\n  return (distance)\n}\n\n\n#' Get an attribute from a Node.\n#'\n#' @param node The \\code{\\link{Node}} from which the \\code{attribute} should be fetched.\n#' @param nullAsNa If TRUE (the default), then NULL is returned as NA. Otherwise it is returned as NULL.\n#'\n#'\n#' @inheritParams Get\n#'\n#' @examples\n#' data(acme)\n#' GetAttribute(acme$IT$Outsource, \"cost\")\n#'\n#' @export\nGetAttribute <- function(node, attribute, ..., format = FALSE, inheritFromAncestors = FALSE, nullAsNa = TRUE) {\n  # for backwards compatibility:\n  if (is.null(format)) format <- TRUE\n  \n  if (is.function(attribute)) {\n    #function\n    v <- attribute(node, ...)\n  } else if(is.character(attribute) && length(attribute) == 1) {\n    #property\n    v <- node[[attribute]]\n    if (is.function(v)) {\n      if (is.null(formals(v))) v <- v()\n      else if (names(formals(v))[[1]] == \"self\") v <- v(self = node, ...) #allow storing functions whose first arg is self\n      else v <- v(...)\n    }\n  } else {\n    stop(\"attribute must be a function, the name of a public property, or the name of method\")\n  }\n\n  if (is.null(v) && inheritFromAncestors && !isRoot(node)) {\n    v <- GetAttribute(node$parent, attribute,\n                      ...,\n                      format = format,\n                      inheritFromAncestors = TRUE,\n                      nullAsNa = FALSE)\n  }\n\n  if (!nullAsNa && is.null(v)) return (NULL)\n  if (is.null(v)) v <- NA\n\n  if(is.logical(format) && format == TRUE && !is.function(attribute)) {\n\n    #get default formatter\n    format <- GetObjectAttribute(node, \"formatters\")[[attribute]]\n\n  }\n  if (is.function(format)) {\n    v <- format(v)\n  }\n\n  return (v)\n}\n\nGetObjectAttribute <- function(node, name) {\n  a <- attr(node, name)\n  ##try to speed up by avoiding isRoot call\n  prnt <- node$parent\n  if (length(a) > 0 || is.null(prnt)) return (a)\n  return ( GetObjectAttribute(prnt, name))\n}\n\n#' Set a formatter function on a specific node\n#'\n#' Formatter functions set on a Node act as a default formatter when printing and using\n#' the \\code{\\link{Get}} method. The formatter is inherited, meaning that whenever\n#' \\code{Get} fetches an attribute from a \\code{Node}, it checks on the \\code{Node} or\n#' on any of its ancestors whether a formatter is set.\n#'\n#' @param node The node on which to set the formatter\n#' @param name The attribute name for which to set the formatter\n#' @param formatFun The formatter, i.e. a function taking a value as an input, and formatting\n#' returning the formatted value\n#'\n#' @examples\n#' data(acme)\n#' acme$Set(id = 1:(acme$totalCount))\n#' SetFormat(acme, \"id\", function(x) FormatPercent(x, digits = 0))\n#' SetFormat(Climb(acme, \"IT\"), \"id\", FormatFixedDecimal)\n#' print(acme, \"id\")\n#' # Calling Get with an explicit formatter will overwrite the default set on the Node:\n#' print(acme, id = acme$Get(\"id\", format = function(x) paste0(\"id:\", x)))\n#'\n#' # Or, to avoid formatters, even though you set them on a Node:\n#' print(acme, id = acme$Get(\"id\", format = identity))\n#'\n#'\n#' @seealso Get\n#' @seealso print.Node\n#'\n#' @export\nSetFormat <- function(node, name, formatFun) {\n  if (length(attr(node, \"formatters\")) == 0) attr(node, \"formatters\") <- list()\n  attr(node, \"formatters\")[[name]] <- formatFun\n}\n\n\n\n\n\n#' Test whether all node names are unique.\n#'\n#' This can be useful for some conversions.\n#' @param node The root \\code{Node} of the \\code{data.tree} structure to test\n#'\n#' @return \\code{TRUE} if all \\code{Node$name == TRUE} for all nodes in the tree\n#'\n#' @examples\n#' data(acme)\n#' AreNamesUnique(acme)\n#' acme$name <- \"IT\"\n#' AreNamesUnique(acme)\n#'\n#' @seealso as.igraph.Node\n#' @export\nAreNamesUnique <- function(node) {\n  mynames <- node$Get(\"name\")\n  all(duplicated(mynames) == FALSE)\n}\n"
  },
  {
    "path": "R/node_methods_sideeffect.R",
    "content": "#\n# These are methods on Node which have side effects, meaning they\n# change a Node object or any of its descendants. To keep the \n# memory footprint of the Node object small, and to be able to \n# document them, they are implemented in traditional R style,\n# and their OO part is only a wrapper around the methods here.\n#\n# Requirements for side effect methods\n# 1. they are implement here\n# 2. their OO part in Node.R is a wrapper\n# 3. the Node documentation links to here\n# 4. the methods here are not exported\n# 5. the methods here are marked as internal, so a to have roxygen generate documentation\n#\n\n\n\n\n\n\n\n#' Sort children of a \\code{Node} or an entire \\code{data.tree} structure\n#' \n#' You can sort with respect to any argument of the tree. But note that sorting has\n#' side-effects, meaning that you modify the underlying, original data.tree object structure.\n#' \n#' @usage Sort(node, attribute, ..., decreasing = FALSE, recursive = TRUE)\n#' \n#' @param node The node whose children are to be sorted \n#' @param ... any parameters to be passed on the the attribute (in case it's a method or a \n#' function)\n#' @param decreasing sort order\n#' @param recursive if \\code{TRUE}, Sort will be called recursively on the \\code{Node}'s children. \n#' This allows sorting an entire tree.\n#' \n#' @inheritParams Get\n#' \n#' @return Returns the node on which Sort is called, invisibly. This can be useful to chain Node methods.\n#' \n#' @examples\n#' data(acme)\n#' acme$Do(function(x) x$totalCost <- Aggregate(x, \"cost\", sum), traversal = \"post-order\")\n#' Sort(acme, \"totalCost\", decreasing = FALSE)\n#' print(acme, \"totalCost\")\n#' \n#' @seealso \\code{\\link{Node}}\n#' @seealso \\code{\\link{Revert}}\n#' @export\nSort <- function(node, attribute, ..., decreasing = FALSE, recursive = TRUE) {\n  if (node$isLeaf) return()\n  ChildL <- sapply(node$children, function(x) GetAttribute(x, attribute, ...))\n  names(ChildL) <- names(node$children)\n  node$children <- node$children[names(sort(ChildL, decreasing = decreasing, na.last = TRUE))]\n  if (recursive) for(child in node$children) Sort(child, attribute, ..., decreasing = decreasing, recursive = recursive)\n  invisible (node)\n}\n\n\n#' Reverts the sort order of a \\code{Node}'s children.\n#' \n#' @usage Revert(node, recursive = TRUE)\n#' \n#' @param node the Node whose childrens' sort order is to be reverted\n#' @param recursive If \\code{TRUE}, then revert is called recursively on\n#' all children.\n#' \n#' @return returns the Node invisibly (for chaining)\n#'\n#' @seealso \\code{\\link{Node}}\n#' @seealso \\code{\\link{Sort}}\n#' @export\nRevert <- function(node, recursive = TRUE) {\n  \n  pf <- function(x) {\n    if (recursive) return (TRUE)\n    else return (x$level <= (node$level + 1))\n  }\n  \n  t <- Traverse(node, pruneFun = pf)\n  \n  Set(t, .tmp = 1:node$totalCount)\n  Sort(node, \".tmp\", decreasing = TRUE, recursive = recursive)\n  Do(t, function(x) rm(\".tmp\", envir = x))\n  invisible (node)\n}\n\n\n#' Prunes a tree. \n#' \n#' Pruning refers to removing entire subtrees. This function has side-effects, it modifies your data.tree structure!\n#' \n#' @usage Prune(node, pruneFun)\n#' \n#' @param node The root of the sub-tree to be pruned\n#' @param pruneFun allows providing a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \n#' If the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.\n#' @return the number of nodes removed\n#' \n#' @examples\n#' data(acme)\n#' acme$Do(function(x) x$cost <- Aggregate(x, \"cost\", sum))\n#' Prune(acme, function(x) x$cost > 700000)\n#' print(acme, \"cost\")\n#' \n#' @seealso \\code{\\link{Node}}\n#' \n#' @export\nPrune <- function(node, pruneFun) { \n  return (.Prune(node, pruneFun, TRUE))\n}\n\n\n.Prune <- function(node, pruneFun, isFirstCall = FALSE) { \n  if (isFirstCall) cnt <- node$totalCount\n  if ( node$isLeaf) return (0)\n  for( i in length(node$children):1 ) {\n    if (length(pruneFun(node$children[[i]]))==0){\n      stop(paste(\"pruneFun evaluated on node\",\n                 node$children[[i]]$name,\n                 \"evaluated to logical(0).\",\n                 \"Perhaps you should read nullAsNa in GetAttribute's help.\" ))\n    } else if ( !pruneFun(node$children[[i]]) ) {\n      rm(list = names(node$children)[i], envir = node)\n      node$children <- node$children[-i]\n    }\n  }\n  for( child in node$children) {\n    .Prune(child, pruneFun)\n  }\n  if (isFirstCall) return (cnt - node$totalCount)\n}\n\n"
  },
  {
    "path": "R/node_methods_traversal.R",
    "content": "#' Traverse a tree or a sub-tree\n#' \n#' Traverse takes the root of a tree or a sub-tree, and \"walks\" the tree in a specific order. It returns a list of\n#' \\code{\\link{Node}} objects, filtered and pruned by \\code{filterFun} and \\code{pruneFun}.\n#' \n#' @param node the root of a tree or a sub-tree that should be traversed\n#' @param traversal any of 'pre-order' (the default), 'post-order', 'in-order', 'level', 'ancestor', or a custom function (see details)\n#' @param filterFun allows providing a a filter, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}.\n#' Note that if filter returns \\code{FALSE}, then the node will be excluded from the result (but not the entire subtree).\n#'\n#' @return a list of \\code{Node}s\n#' \n#' @details\n#' The traversal order is as follows. (Note that these descriptions are not precise and complete. They are meant\n#' for quick reference only. See the data.tree vignette for a more detailed description). \n#' \\describe{\n#'    \\item{pre-order}{Go to first child, then to its first child, etc.}\n#'    \\item{post-order}{Go to the first branch's leaf, then to its siblings, and work your way back to the root}\n#'    \\item{in-order}{Go to the first branch's leaf, then to its parent, and only then to the leaf's sibling}\n#'    \\item{level}{Collect root, then level 2, then level 3, etc.}\n#'    \\item{ancestor}{Take a node, then the node's parent, then that node's parent in turn, etc. This ignores the \\code{pruneFun} }\n#'    \\item{function}{You can also provide a function, whose sole parameter is a \\code{\\link{Node}} object. The\n#'    function is expected to return the node's next node, a list of the node's next nodes, or NULL.}\n#' }\n#' \n#' \n#' @seealso \\code{\\link{Node}}\n#' @seealso \\code{\\link{Get}}\n#' @seealso \\code{\\link{Set}}\n#' @seealso \\code{\\link{Do}}\n#' \n#' @inheritParams Prune\n#' \n#' @export\nTraverse = function(node, \n                    traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"), \n                    pruneFun = NULL,\n                    filterFun = NULL) {\n  #traverses in various orders. See http://en.wikipedia.org/wiki/Tree_traversal\n  \n  nodes <- list()\n \n  if(length(traversal) > 1L) {\n    traversal <- traversal[1L]\n  }\n  if(is.function(traversal) || traversal == \"pre-order\" || traversal == \"post-order\") {\n    \n    if (length(pruneFun) == 0 || pruneFun(node)) {\n      \n      if (is.function(traversal)) {\n        children <- traversal(node)\n        if (is(children, \"Node\")) children <- list(children)\n        if (is.null(children)) children <- list()\n      } else children <- node$children\n      \n      for(child in children) {\n        nodes <- c(nodes, Traverse(child, traversal = traversal, pruneFun = pruneFun, filterFun = filterFun))\n      }\n      if(length(filterFun) == 0 || filterFun(node)) {\n        if(is.function(traversal) || traversal == \"pre-order\") nodes <- c(node, nodes)\n        else nodes <- c(nodes, node)\n      }\n    }\n    \n  } else if(traversal == \"in-order\") {\n    if(!node$isBinary) stop(\"traversal in-order valid only for binary trees\")\n    if(length(pruneFun) == 0 || pruneFun(node)) {\n      if(!node$isLeaf) {\n        n1 <- Traverse(node$children[[1]], traversal = traversal, pruneFun = pruneFun, filterFun = filterFun)\n        if(length(filterFun) == 0 || filterFun(node)) n2 <- node\n        else n2 <- list()\n        n3 <- Traverse(node$children[[2]], traversal = traversal, pruneFun = pruneFun, filterFun = filterFun)\n        nodes <- c(n1, n2, n3)\n      } else {\n        if(length(filterFun) == 0 || filterFun(node)) n2 <- node\n        else n2 <- list()\n        nodes <- c(nodes, n2)\n      }\n    }\n    \n  } else if (traversal == \"ancestor\") {\n    \n    \n    if (!isRoot(node)) {\n      nodes <- Traverse(node$parent, traversal = traversal, pruneFun = pruneFun, filterFun = filterFun)\n    }\n    \n    if(length(filterFun) == 0 || filterFun(node)) {\n      nodes <- c(node, nodes)\n    }\n    \n  } else if (traversal == \"level\") {\n    \n    nodes <- Traverse(node, filterFun = filterFun, pruneFun = pruneFun)\n    if (length(nodes) > 0) nodes <- nodes[order(Get(nodes, function(x) x$level))]\n    \n    \n  } else {\n    stop(\"traversal must be pre-order, post-order, in-order, ancestor, or level\")\n  }\n  return (nodes)\n}\n\n\n\n\n\n\n#' Traverse a Tree and Collect Values\n#' \n#' The \\code{Get} method is one of the most important ones of the \\code{data.tree} package. It lets you traverse a tree\n#' and collect values along the way. Alternatively, you can call a method or a function on each \\code{\\link{Node}}.\n#' \n#' @usage \n#' # OO-style:\n#' #node$Get(attribute, \n#' #        ..., \n#' #        traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"), \n#' #        pruneFun = NULL, \n#' #        filterFun = NULL, \n#' #        format = FALSE, \n#' #        inheritFromAncestors = FALSE)\n#'          \n#' # traditional:\n#' Get(nodes, \n#'     attribute, \n#'     ..., \n#'     format = FALSE, \n#'     inheritFromAncestors = FALSE, \n#'     simplify = c(TRUE, FALSE, \"array\", \"regular\"))\n#' \n#' \n#' @param nodes The nodes on which to perform the Get (typically obtained via \\code{\\link{Traverse}})\n#' @param attribute determines what is collected. The \\code{attribute} can be\n#'       \\itemize{\n#'         \\item a.) the name of a \\bold{field} or a \\bold{property/active} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"p\")} or \\code{acme$Get(\"position\")}\n#'         \\item b.) the name of a \\bold{method} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"levelZeroBased\")}, where e.g. \\code{acme$levelZeroBased <- function() acme$level - 1}\n#'         \\item c.) a \\bold{function}, whose first argument must be a \\code{Node} e.g. \\code{acme$Get(function(node) node$cost * node$p)}\n#'        }\n#' @param ... in case the \\code{attribute} is a function or a method, the ellipsis is passed to it as additional arguments.\n#' @param format if \\code{FALSE} (the default), no formatting is being used. If \\code{TRUE}, then the first formatter (if any) found along the ancestor path is being used for formatting \n#' (see \\code{\\link{SetFormat}}). If \\code{format} is a function, then the collected value is passed to that function, and the result is returned.\n#' @param inheritFromAncestors if \\code{TRUE}, then the path above a \\code{Node} is searched to get the \\code{attribute} in case it is NULL.\n#' @param simplify same as \\code{\\link{sapply}}, i.e. TRUE, FALSE or \"array\". Additionally, you can specify \"regular\" if\n#' each returned value is of length > 1, and equally named. See below for an example.\n#'        \n#' @return a vector containing the \\code{atrributes} collected during traversal, in traversal order. \\code{NULL} is converted\n#' to NA, such that \\code{length(Node$Get) == Node$totalCount}\n#'  \n#'  \n#' @examples\n#' data(acme)\n#' acme$Get(\"level\")\n#' acme$Get(\"totalCount\")\n#'  \n#'\n#' acme$Get(function(node) node$cost * node$p,\n#'          filterFun = isLeaf)\n#' \n#' #This is equivalent:\n#' nodes <- Traverse(acme, filterFun = isLeaf)\n#' Get(nodes, function(node) node$cost * node$p)\n#' \n#'    \n#' #simplify = \"regular\" will preserve names\n#' acme$Get(function(x) c(position = x$position, level = x$level), simplify = \"regular\")\n#'  \n#' @seealso \\code{\\link{Node}}\n#' @seealso \\code{\\link{Set}}\n#' @seealso \\code{\\link{Do}}\n#' @seealso \\code{\\link{Traverse}}\n#'  \n#' @import methods\n#'  \n#' @export\nGet = function(nodes, \n               attribute, \n               ..., \n               format = FALSE,\n               inheritFromAncestors = FALSE, \n               simplify = c(TRUE, FALSE, \"array\", \"regular\")) {\n  if (length(nodes) == 0) return(NULL)\n  if (!is(nodes, \"list\")) stop(\"nodes must be a list of Node objects!\")\n  simplify <- simplify[1]\n                 \n  nodes <- unname(nodes)\n  if (simplify == \"regular\") {\n    regular = TRUE\n    simplify = FALSE\n  } else regular = FALSE\n  res <- sapply(nodes, \n                function(x) GetAttribute(x, \n                                         attribute, \n                                         ...,\n                                         format = format, \n                                         inheritFromAncestors = inheritFromAncestors),\n                simplify = simplify\n  )\n  if (is.character(attribute) && attribute == \"name\") {\n    names(res) <- res\n  } else {\n    if(is.null(dim(res))){\n      names(res) <- Get(nodes, \"name\")\n    } else {\n      if(is.null(dimnames(res)))\n        dimnames(res) <- list()\n      dimnames(res)[[length(dim(res))]] <- Get(nodes, \"name\")\n    } \n  }\n  if (regular) {\n    res <- do.call(cbind, res)\n  }\n  \n  return (res)\n}\n\n#' Executes a function on a set of nodes\n#' \n#' @usage \n#' # OO-style:\n#' # node$Do(fun, \n#' #         ..., \n#' #         traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"), \n#' #         pruneFun = NULL, \n#' #         filterFun = NULL)\n#'          \n#' # traditional:\n#' Do(nodes, fun, ...)\n#' \n#' @param fun the function to execute. The function is expected to be either a Method, or to take a \n#' Node as its first argument\n#' @param ... any additional parameters to be passed on to fun\n#' \n#' @seealso \\code{\\link{Node}}\n#' @seealso \\code{\\link{Get}}\n#' @seealso \\code{\\link{Set}}\n#' @seealso \\code{\\link{Traverse}}\n#' \n#' @inheritParams Get\n#' \n#' @examples \n#' data(acme)\n#' traversal <- Traverse(acme)\n#' Do(traversal, function(node) node$expectedCost <- node$p * node$cost)\n#' print(acme, \"expectedCost\")\n#' \n#' @export\nDo <- function(nodes,\n               fun, \n               ...) {\n  if (length(nodes) == 0) invisible(nodes)\n  if (!is(nodes, \"list\")) stop(\"nodes must be a list of Node objects!\")\n      \n  for (node in nodes) fun(node, ...)\n  \n  invisible (nodes)\n}\n\n\n\n\n#' Traverse a Tree and Assign Values\n#' \n#' The method takes one or more vectors as an argument. It traverses the tree, whereby the values are picked\n#' from the vector. Also available as OO-style method on \\code{\\link{Node}}.\n#' \n#' @usage \n#' #OO-style:\n#' # node$Set(..., \n#' #          traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"),  \n#' #          pruneFun = NULL, \n#' #          filterFun = NULL)\n#' #traditional:\n#' Set(nodes, ...)\n#' \n#' \n#' @param ... each argument can be a vector of values to be assigned. Recycled.\n#'\n#' @return invisibly returns the nodes (useful for chaining)  \n#'  \n#' @examples\n#' data(acme)\n#' acme$Set(departmentId = 1:acme$totalCount, openingHours = NULL, traversal = \"post-order\")\n#' acme$Set(head = c(\"Jack Brown\", \n#'                   \"Mona Moneyhead\", \n#'                   \"Dr. Frank N. Stein\", \n#'                   \"Eric Nerdahl\"\n#'                   ),\n#'          filterFun = function(x) !x$isLeaf\n#'         )\n#' print(acme, \"departmentId\", \"head\")\n#'  \n#' @seealso \\code{\\link{Node}}\n#' @seealso \\code{\\link{Get}}\n#' @seealso \\code{\\link{Do}}\n#' @seealso \\code{\\link{Traverse}}\n#'  \n#' @inheritParams Get\n#'  \n#' @export\nSet <- function(nodes, \n                ...) {\n  \n  if (length(nodes) == 0) return(nodes)\n  if (!is(nodes, \"list\")) stop(\"nodes must be a list of Node objects!\")\n      \n  args <- list(...)\n  argsnames <- sapply(substitute(list(...))[-1], deparse)\n  gargsnames <- names(args)\n  if (is.null(gargsnames)) gargsnames <- vector(mode = \"character\", length = length(args))\n  gargsnames[nchar(gargsnames) == 0] <- argsnames[nchar(gargsnames) == 0]\n  names(args) <- gargsnames\n  \n  \n  \n  appFun <- function(x, arg, name) {\n    x[[name]] <- arg\n  }\n  \n  for(nme in names(args)) {\n    arg <- args[[nme]]\n    if (length(arg) == 0) arg <- vector(\"list\", 1)\n    mapply(appFun, nodes, arg, nme)\n  }\n  \n  invisible (nodes)\n  \n}\n"
  },
  {
    "path": "R/node_plot.R",
    "content": "\n#' @rdname ToDiagrammeRGraph\n#'\n#' @param x The root node of the data.tree structure to plot\n#' @inheritParams ToDataFrameNetwork\n#' @inheritParams DiagrammeR::render_graph\n#'\n#' @export\nplot.Node <- function(x, ..., direction = c(\"climb\", \"descend\"), pruneFun = NULL, output = \"graph\") {\n  if(!requireNamespace(\"DiagrammeR\", quietly = TRUE)) {\n    stop(\n      \"Package \\\"DiagrammeR\\\" is required to plot a `data.tree::Node`\",\n      \"object. Please install it.\"\n    )}\n\n  graph <- ToDiagrammeRGraph(x, direction, pruneFun)\n  DiagrammeR::render_graph(graph, output = output, ...)\n}\n\n\n#' Plot a graph, or get a graphviz dot representation of the tree\n#' \n#' Use these methods to style your graph, and to plot it. The functionality is built around the\n#' DiagrammeR package, so for anything that goes beyond simple plotting, it is recommended to read its \n#' documentation at http://rich-iannone.github.io/DiagrammeR/docs.html. Note that DiagrammeR is only suggested\n#' by data.tree, so `plot` only works if you have installed it on your system.\n#' \n#' Use \\code{SetNodeStyle} and \\code{SetEdgeStyle} to define the style of your plot. Use \\code{plot} to display a \n#' graphical representation of your tree.\n#' \n#' The most common styles that can be set on the nodes are:\n#' \\itemize{\n#'   \\item{\\code{color}}\n#'   \\item{\\code{fillcolor}}\n#'   \\item{\\code{fixedsize} true or false}\n#'   \\item{\\code{fontcolor}}\n#'   \\item{\\code{fontname}}\n#'   \\item{\\code{fontsize}}\n#'   \\item{\\code{height}}\n#'   \\item{\\code{penwidth}}\n#'   \\item{\\code{shape} box, ellipse, polygon, circle, box, etc.}\n#'   \\item{\\code{style}}\n#'   \\item{\\code{tooltip}}\n#'   \\item{\\code{width}}\n#'  }\n#' The most common styles that can be set on the edges are:\n#' \\itemize{\n#'   \\item{\\code{arrowhead} e.g. normal, dot, vee}\n#'   \\item{\\code{arrowsize}}\n#'   \\item{\\code{arrowtail}}\n#'   \\item{\\code{color}}\n#'   \\item{\\code{dir} forward, back, both, none}\n#'   \\item{\\code{fontcolor}}\n#'   \\item{\\code{fontname}}\n#'   \\item{\\code{fontsize}}\n#'   \\item{\\code{headport}}\n#'   \\item{\\code{label}}\n#'   \\item{\\code{minlen}}\n#'   \\item{\\code{penwidth}}\n#'   \\item{\\code{tailport}}\n#'   \\item{\\code{tooltip}}\n#'  }\n#' A good source to understand the attributes is http://graphviz.org/Documentation.php. Another good source\n#' is the DiagrammeR package documentation, or more specifically: http://rich-iannone.github.io/DiagrammeR/docs.html\n#'\n#' In addition to the standard GraphViz functionality, the \\code{data.tree} plotting infrastructure takes advantage\n#' of the fact that data.tree structure are always hierarchic. Thus, style attributes are inherited from parents\n#' to children on an individual basis. For example, you can set the fontcolor to red on a parent, and then all children\n#' will also have red font, except if you specifically disallow inheritance. Labels and tooltips are never inherited.\n#' \n#' Another feature concerns functions: Instead of setting a fixed value (e.g. \\code{SetNodeStyle(acme, label = \"Acme. Inc\"}), \n#' you can set a function (e.g. \\code{SetNodeStyle(acme, label = function(x) x$name)}). The function must take a \\code{\\link{Node}}\n#' as its single argument. Together with inheritance, this becomes a very powerful tool.\n#'   \n#' The \\code{GetDefaultTooltip} method is a utility method that can be used to print all attributes of a \\code{\\link{Node}}.\n#' \n#' There are some more examples in the 'applications' vignette, see \\code{vignette('applications', package = \"data.tree\")}\n#' \n#' @param root The root \\code{\\link{Node}} of the data.tree structure to visualize.\n#' @param node The \\code{\\link{Node}} of the data.tree structure on which you would like to set style attributes.\n#' @param ... For the SetStyle methods, this can be any stlyeName / value pair. See \n#' http://graphviz.org/Documentation.php for details. For the plot.Node generic method, this is not used.\n#' \n#' @inheritParams Prune\n#' \n#' @examples\n#' data(acme)\n#' SetGraphStyle(acme, rankdir = \"TB\")\n#' SetEdgeStyle(acme, arrowhead = \"vee\", color = \"blue\", penwidth = 2)\n#' #per default, Node style attributes will be inherited:\n#' SetNodeStyle(acme, style = \"filled,rounded\", shape = \"box\", fillcolor = \"GreenYellow\", \n#'              fontname = \"helvetica\", tooltip = GetDefaultTooltip)\n#' SetNodeStyle(acme$IT, fillcolor = \"LightBlue\", penwidth = \"5px\")\n#' #inheritance can be avoided:\n#' SetNodeStyle(acme$Accounting, inherit = FALSE, fillcolor = \"Thistle\", \n#'              fontcolor = \"Firebrick\", tooltip = \"This is the accounting department\")\n#' SetEdgeStyle(acme$Research$`New Labs`, \n#'              color = \"red\", \n#'              label = \"Focus!\", \n#'              penwidth = 3, \n#'              fontcolor = \"red\")\n#' #use Do to set style on specific nodes:\n#' Do(acme$leaves, function(node) SetNodeStyle(node, shape = \"egg\"))\n#' plot(acme)\n#' \n#' #print p as label, where available:\n#' SetNodeStyle(acme, label = function(node) node$p)\n#' plot(acme)\n#' \n#' @export\nToDiagrammeRGraph <- function(root, direction = c(\"climb\", \"descend\"), pruneFun = NULL) {\n  if(!requireNamespace(\"DiagrammeR\", quietly = TRUE)) {\n    stop(\n      \"Package \\\"DiagrammeR\\\" is required to convert a `data.tree::Node`\",\n      \"to a DiagrammeR graph. Please install it.\"\n    )}\n\n  #get unique node styles defined on tree\n\n  ns <- unique(unlist(sapply(root$Get(function(x) attr(x, \"nodeStyle\"), simplify = FALSE), names)))\n\n  # set tmp .id\n  tr <- Traverse(root, pruneFun = pruneFun)\n  Set(tr, `.id` = 1:length(tr))\n  \n  #create nodes df\n  myargs <- list()\n  if(!\"label\" %in% ns) ns <- c(ns, \"label\")\n  for (style in ns) {\n    myargs[[style]] <- Get(tr, function(x) {\n      myns <- GetStyle(x, style, \"node\")\n      if (style == \"label\" && length(myns) == 0) myns <- x$name\n      #if (is.null(myns)) myns <- \"\"\n      myns\n    })\n  }\n  \n  nodes <- do.call(DiagrammeR::create_node_df, c(n = length(tr), myargs))\n  \n  ## escape quotes in names to avoid problems with the gviz\n  nodes$label <- gsub(\"\\\"\", \"\\\\\\\\\\\"\", nodes$label)\n\n  # get unique edge styles\n  \n  es <- unique(unlist(sapply(root$Get(function(x) attr(x, \"edgeStyle\"), simplify = FALSE), names)))\n  \n  \n  myargs <- list()\n  #see http://stackoverflow.com/questions/19749923/function-factory-in-r\n  for (style in es) {\n    myargs[[style]] <- GetEdgeStyleFactory(style)\n  }\n  \n  \n  \n  edges <- do.call(\"ToDataFrameNetwork\", c(root, from = function(node) node$parent$`.id`, to = \".id\", myargs, direction = list(direction), pruneFun = pruneFun))[,-(1:2)]\n  if (nrow(edges) > 0) {\n    edges <- do.call(DiagrammeR::create_edge_df, as.list(edges))\n  }\n  \n  graph <- DiagrammeR::create_graph(nodes, edges, attr_theme = NULL)\n  \n  # global attributes\n  # (we'd prefer to set the default on the root as graphAttributes, but\n  # due to a DiagrammeR bug/feature this is not possible). So instead\n  # repeating styles redundantly\n  \n  graphAttributes <- attr(root, \"graphStyle\")\n  #if (is.null(graphAttributes)) graphAttributes <- \"\"\n  #nodeAttributes <- GetDefaultStyles(root, type = \"node\")\n  #edgeAttributes <- GetDefaultStyles(root, type = \"edge\")\n  nodeAttributes <- NULL\n  edgeAttributes <- NULL\n  \n  #graph <- set_global_graph_attrs(graph, \"layout\", \"dot\", \"graph\")\n  \n  graph <- DiagrammeR::add_global_graph_attrs(\n    graph,\n    attr = c(names(graphAttributes), names(nodeAttributes), names(edgeAttributes)),\n    value = c(graphAttributes, nodeAttributes, edgeAttributes),\n    attr_type = c(rep('graph', length(graphAttributes)), rep('node', length(nodeAttributes)), rep('edge', length(edgeAttributes)))\n  )\n  \n  return (graph)\n  \n}\n\n\n\nGetEdgeStyleFactory <- function(style) {\n  style <- force(style)\n  function(node = node, origNode = node) {\n    myes <- GetStyle(node, style, \"edge\")\n    #if (is.null(myes)) myes <- \"\"\n    myes\n  }\n}\n\n\n#' @param inherit If TRUE, then children will inherit this node's style. \n#' Otherwise they inherit from this node's parent. Note that the inherit \n#' always applies to the node, i.e. all style attributes of a node and not \n#' to a single style attribute.\n#' \n#' @param keepExisting If TRUE, then style attributes are added to possibly\n#' existing style attributes on the node. \n#' \n#' @rdname ToDiagrammeRGraph\n#' \n#' @export\nSetNodeStyle <- function(node, \n                         inherit = TRUE,\n                         keepExisting = FALSE,\n                         ...) {\n  SetStyle(node, \"node\", inherit, keepExisting, ...)\n}\n\n\n#' @rdname ToDiagrammeRGraph\n#' @export\nSetEdgeStyle <- function(node,\n                         inherit = TRUE,\n                         keepExisting = FALSE,\n                         ...) {\n  SetStyle(node, \"edge\", inherit, keepExisting, ...)\n}\n\nSetStyle <- function(node,\n                     type = c(\"node\", \"edge\"),\n                     inherit = TRUE,\n                     keepExisting = FALSE,\n                     ...) {\n  type <- type[1]\n  an <- paste0(type, \"Style\")\n  ain <- paste0(type, \"StyleInherit\")\n  if (keepExisting) {\n    ll <- attr(node, an)\n    ll <- c(ll, list(...))\n  } else ll <- list(...)\n  attr(node, an) <- ll\n  attr(node, ain) <- inherit\n}\n\n\n\n#' @rdname ToDiagrammeRGraph \n#' @export\nSetGraphStyle <- function(root,\n                          keepExisting = FALSE,\n                          ...) {\n  if (keepExisting) {\n    ll <- attr(root, \"graphStyle\")\n    ll <- c(ll, list(...))\n  } else ll <- list(...)\n  attr(root, \"graphStyle\") <- ll\n}\n\n\nGetStyle <- function(node, styleName, type = c(\"node\", \"edge\"), origNode = node) {\n  type <- type[1]\n  inh <- attr(node, paste0(type, \"StyleInherit\"))\n  res <- attr(node, paste0(type, \"Style\"))[[styleName]]\n  if (!is.null(res)) {\n    if (!isRoot(node)) {\n      if (identical(node, origNode) || (inh && !styleName %in% c(\"label\", \"tooltip\"))) {# either on myself or inheritable\n        if (is.function(res)) res <- res(origNode)\n        return (res)\n      }\n    } else {\n      #root\n      if (is.function(res)) res <- res(origNode)\n      return (res)\n    }\n  }\n  #recursion exit criteria\n  if (isRoot(node)) return (NULL)\n\n    #recursion\n  GetStyle(node$parent, styleName, type, origNode = origNode)\n  \n}\n\nGetDefaultStyles <- function(node, type = c(\"node\", \"edge\")) {\n  type <- type[1]\n  node <- node$root\n  inh <- attr(node, paste0(type, \"StyleInherit\"))\n  res <- attr(node, paste0(type, \"Style\"))\n  if (!is.null(res) && inh) {\n    res <- res[!names(res) %in% c(\"label\", \"tooltip\")]\n    isFun <- sapply(res, is.function)\n    res <- res[!isFun]\n    if (length(res) == 0) return (NULL)\n    #res <- paste(names(res), paste0(\"'\", res, \"'\"), sep = \" = \", collapse = \", \")\n    return (res) \n  } else return (NULL)\n}\n\n"
  },
  {
    "path": "R/register-s3.R",
    "content": "#' Register a method for a suggested dependency\n#'\n#' Code copied into data.tree from `vctrs` (authors Wickham H, Henry L,\n#' Vaughan D; https://github.com/r-lib/vctrs)\n#'\n#' Generally, the recommend way to register an S3 method is to use the\n#' `S3Method()` namespace directive (often generated automatically be the\n#' `@export` roxygen2 tag). However, this technique requires that the generic\n#' be in an imported package, and sometimes you want to suggest a package,\n#' and only provide a method when that package is loaded. `s3_register()`\n#' can be called from your package's `.onLoad()` to dynamically register\n#' a method only if the generic's package is loaded. (To avoid taking a\n#' dependency on vctrs for this one function, please feel free to copy\n#' and paste the function source into your own package.)\n#'\n#' For R 3.5.0 and later, `s3_register()` is also useful when demonstrating\n#' class creation in a vignette, since method lookup no longer always involves\n#' the lexical scope. For R 3.6.0 and later, you can achieve a similar effect\n#' by using \"delayed method registration\", i.e. placing the following in your\n#' `NAMESPACE` file:\n#'\n#' ```\n#' if (getRversion() >= \"3.6.0\") {\n#'   S3method(package::generic, class)\n#' }\n#' ```\n#'\n#' @param generic Name of the generic in the form `pkg::generic`.\n#' @param class Name of the class\n#' @param method Optionally, the implementation of the method. By default,\n#'   this will be found by looking for a function called `generic.class`\n#'   in the package environment.\n#'\n#'   Note that providing `method` can be dangerous if you use\n#'   devtools. When the namespace of the method is reloaded by\n#'   `devtools::load_all()`, the function will keep inheriting from\n#'   the old namespace. This might cause crashes because of dangling\n#'   `.Call()` pointers.\n#' @examples\n#' # A typical use case is to dynamically register tibble/pillar methods\n#' # for your class. That way you avoid creating a hard depedency on packages\n#' # that are not essential, while still providing finer control over\n#' # printing when they are used.\n#'\n#' .onLoad <- function(...) {\n#'   s3_register(\"pillar::pillar_shaft\", \"vctrs_vctr\")\n#'   s3_register(\"tibble::type_sum\", \"vctrs_vctr\")\n#' }\n#' @keywords internal\n# nocov start\ns3_register <- function(generic, class, method = NULL) {\n  stopifnot(is.character(generic), length(generic) == 1)\n  stopifnot(is.character(class), length(class) == 1)\n  \n  pieces <- strsplit(generic, \"::\")[[1]]\n  stopifnot(length(pieces) == 2)\n  package <- pieces[[1]]\n  generic <- pieces[[2]]\n  \n  caller <- parent.frame()\n  \n  get_method_env <- function() {\n    top <- topenv(caller)\n    if (isNamespace(top)) {\n      asNamespace(environmentName(top))\n    } else {\n      caller\n    }\n  }\n  get_method <- function(method, env) {\n    if (is.null(method)) {\n      get(paste0(generic, \".\", class), envir = get_method_env())\n    } else {\n      method\n    }\n  }\n  \n  method_fn <- get_method(method)\n  stopifnot(is.function(method_fn))\n  \n  # Always register hook in case package is later unloaded & reloaded\n  setHook(\n    packageEvent(package, \"onLoad\"),\n    function(...) {\n      ns <- asNamespace(package)\n      \n      # Refresh the method, it might have been updated by `devtools::load_all()`\n      method_fn <- get_method(method)\n      \n      registerS3method(generic, class, method_fn, envir = ns)\n    }\n  )\n  \n  # Avoid registration failures during loading (pkgload or regular)\n  if (!isNamespaceLoaded(package)) {\n    return(invisible())\n  }\n  \n  envir <- asNamespace(package)\n  \n  # Only register if generic can be accessed\n  if (exists(generic, envir)) {\n    registerS3method(generic, class, method_fn, envir = envir)\n  }\n  \n  invisible()\n}\n\n# nocov end"
  },
  {
    "path": "R/release.R",
    "content": "release_questions <- function() {\n  c(\n    \"Have you set the date in DESCRIPTION?\",\n    \"Have you updated NEWS?\",\n    \"Have you verified that the application vignette looks ok?\",\n    \"Have you verified that the data.tree vignette looks ok?\",\n    \"Have you read the Node documentation ?Node\",\n    \"Have you checked that all the reserved words are listed in Node?\"\n  )\n}"
  },
  {
    "path": "R/util.R",
    "content": "\n\n#' Format a Number as a Percentage\n#'\n#' This utility method can be used as a format function when converting trees to a \\code{data.frame}\n#'\n#' @param x A number\n#' @param digits The number of digits to print\n#' @param format The format to use\n#' @param ... Any other argument passed to formatC\n#' @return A string corresponding to x, suitable for printing\n#'\n#' @examples\n#' data(acme)\n#' print(acme, prob = acme$Get(\"p\", format = FormatPercent))\n#'\n#' @seealso formatC\n#' @export\nFormatPercent <- function(x, digits = 2, format = \"f\", ...) {\n  ifelse(is.null(x) || is.na(x), \"\", paste(formatC(100 * x, format = format, digits = digits, ...), \"%\"))\n}\n\n#' Format a Number as a Decimal\n#'\n#' Simple function that can be used as a format function when converting trees to a \\code{data.frame}\n#'\n#' @param x a numeric scalar or vector\n#' @param digits the number of digits to print after the decimal point\n#' @return A string corresponding to x, suitable for printing\n#'\n#' @examples\n#' data(acme)\n#' print(acme, prob = acme$Get(\"p\", format = function(x) FormatFixedDecimal(x, 4)))\n#'\n#' @export\nFormatFixedDecimal <- function(x, digits = 3) {\n  ifelse(is.null(x) || is.na(x), \"\", sprintf(paste0(\"%.\",digits, \"f\"),x))\n}\n\n\n\n\n\n#' Calculates the height of a \\code{Node} given the height of the root.\n#'\n#' This function puts leafs at the bottom (not hanging), and makes edges equally long.\n#' Useful for easy plotting with third-party packages, e.g. if you have no specific height\n#' attribute, e.g. with \\code{\\link{as.dendrogram.Node}}, \\code{\\link{ToNewick}},\n#' and \\code{\\link{as.phylo.Node}}\n#'\n#' @param node The node\n#' @param rootHeight The height of the root\n#'\n#' @examples\n#' data(acme)\n#' dacme <- as.dendrogram(acme, heightAttribute = function(x) DefaultPlotHeight(x, 200))\n#' plot(dacme, center = TRUE)\n#'\n#' @export\nDefaultPlotHeight <- function(node, rootHeight = 100) {\n  if (node$isRoot) return ( rootHeight )\n  if (node$isLeaf) return ( 0 )\n  h <- DefaultPlotHeight(node$parent, rootHeight) * (1 - 1 / node$height)\n  return (h)\n}\n\n\nSetHeight2 <- function(node, rootHeight = 100) {\n  Set(node$leaves, height2 = 1)\n  node$Do(function(x) x$height2 <- Aggregate(x, \"height2\", max) + 1, traversal = \"post-order\", filterFun = isNotLeaf)\n  node$plotHeight <- rootHeight\n  node$Do(function(x) x$plotHeight <- x$parent$plotHeight * (1 - 1 / x$height2), filterFun = isNotRoot)\n}\n\n\n#' Create a tree for demo and testing\n#'\n#' @param height the number of levels\n#' @param branchingFactor the number of children per node\n#' @param parent the parent node (for recursion)\n#'\n#' @export\nCreateRegularTree <- function(height = 5, branchingFactor = 3, parent = Node$new(\"1\")) {\n  if (height <= 1) return()\n  for (i in 1:branchingFactor) {\n    child <- parent$AddChild(paste(parent$name, i, sep = \".\"), check = FALSE)\n    CreateRegularTree(height - 1, branchingFactor, child)\n  }\n  return (parent)\n}\n\n\n\n\n\n#' Create a tree for demo and testing\n#'\n#' @param nodes The number of nodes to create\n#' @param root the previous node (for recursion, typically use default value)\n#' @param id The id (for recursion)\n#'\n#' @export\nCreateRandomTree <- function(nodes = 100, root = Node$new(\"1\"), id = 1) {\n  if (nodes == 0) return()\n  dpth <- root$height\n  lvl <- sample(1:dpth, 1, rep(1/dpth))\n  t <- Traverse(root, filterFun = function(x) x$level == lvl)\n  parent <- sample(t, 1)[[1]]\n  parent$AddChild(as.character(id + 1), check = FALSE)\n  CreateRandomTree(nodes - 1, root = root, id = id + 1)\n  return (root)\n}\n\n\n\nPrintPruneSimple <- function(x, limit) {\n  tc <- x$totalCount\n  toBeCropped <- tc - limit\n  if (toBeCropped < 1) {\n    if(!isRoot(x)) {\n      #clone s.t. x is root (for pretty level names)\n      x <- Clone(x, attributes = TRUE)\n      x$parent <- NULL\n    }\n    return (x)\n  }\n\n  x$Set(.id = 1:tc)\n\n  x$Do(function(x) {\n       x$.originalTotalCount <- ifelse(x$isLeaf,\n                                       1,\n                                       sum( sapply(x$children, function(x) x$.originalTotalCount)) + 1)\n       x$.originalCount <- x$count\n       },\n       traversal = \"post-order\"\n  )\n\n  xc <- Clone(x, pruneFun = function(x) x$.id < limit, attributes = TRUE)\n\n  xc$Do(function(x) {\n          if(x$count < x$.originalCount) {\n            nds <- x$.originalCount - x$count\n            sub <- x$.originalTotalCount - x$totalCount - nds\n            x$AddChild(paste0(\"... \", nds, \" nodes w/ \", sub, \" sub\"))\n          }\n        })\n\n  x <- xc\n\n}\n\n\n\n\n\nPrintPruneDist <- function(x, limit) {\n  tc <- x$totalCount\n  toBeCropped <- tc - limit\n  if (toBeCropped < 1) {\n    if(!isRoot(x)) {\n      #clone s.t. x is root (for pretty level names)\n      x <- Clone(x, attributes = TRUE)\n      x$parent <- NULL\n    }\n    return (x)\n  }\n\n  t <- Traverse(x, traversal = \"post-order\")\n\n  Do(t, function(x) {\n    x$.height <- ifelse(x$isLeaf, 1, x$children[[1]]$.height + 1)\n  })\n\n  Do(t, function(x) {\n    x$.originalTotalCount <- ifelse(x$isLeaf, 1, sum( sapply(x$children, function(x) x$.originalTotalCount)) + 1)\n  })\n\n\n  t <- Traverse(x)\n  Set(t, .id = 1:tc)\n  x$.level <- 1\n  Do(t, function(x) {\n    x$.originalCount <- length(x$children)\n    x$.level <- ifelse(isRoot(x), 1, x$parent$.level + 1)\n  })\n\n\n\n  t <- t[order(Get(t, \".level\"),\n               - Get(t, \".height\"),\n               Get(t, function(x) x$position > 2))]\n\n  keep <- c(rep(TRUE, limit), rep(FALSE, toBeCropped))\n\n  Set(t, .keep = keep)\n  #sapply(t, function(x) paste(x$.height, x$.level, x$name, sep = \".\"))\n  xc <- Clone(x, pruneFun = function(x) x$.keep, attributes = TRUE)\n\n  t <- Traverse(xc)\n\n  Do(t, function(x) {\n    if(x$count < x$.originalCount) {\n      nds <- x$.originalCount - x$count\n      sub <- x$.originalTotalCount - x$totalCount - nds\n      x$AddChild(paste0(\"... \", nds, \" nodes w/ \", sub, \" sub\"))\n    }\n  })\n\n  x <- xc\n\n}\n\n\n\n#' @rdname ToDiagrammeRGraph\n#' @export\nGetDefaultTooltip <- function(node) {\n\n\n  if (length(node$attributes) > 0) {\n    myattributes <- node$attributes\n  } else {\n    myattributes <- \"name\"\n  }\n  tt <- paste(sapply(myattributes, function(x) {\n    v <- node[[x]]\n    if (is.function(v)) v <- \"function\"\n    else v <- GetAttribute(node, x)\n    paste0(\"- \", x, \": \", v)\n  }), collapse = \"\\n\")\n\n  return (tt)\n}\n\n\n#' Checks whether \\code{name} is a reserved word, as defined in \\code{NODE_RESERVED_NAMES_CONST}.\n#' \n#' @param name the name to check\n#' @param check Either\n#' \\itemize{\n#'  \\item{\\code{\"check\"}: if the name conformance should be checked and warnings should be printed in case of non-conformance (the default)}\n#'  \\item{\\code{\"no-warn\"}: if the name conformance should be checked, but no warnings should be printed in case of non-conformance (if you expect non-conformance)}\n#'  \\item{\\code{\"no-check\" or FALSE}: if the name conformance should not be checked; use this if performance is critical. However, in case of non-conformance, expect cryptic follow-up errors}\n#' }\nCheckNameReservedWord <- function(name, check = c(\"check\", \"no-warn\", \"no-check\")) {\n  check <- check[1]\n  if (check == FALSE) return (name)\n  if (check == \"no-check\") return (name)\n  if (!(check == FALSE || check == \"no-check\")) {\n    if (name %in% NODE_RESERVED_NAMES_CONST) {\n      \n      name2 <- paste0(name, \"2\")\n      if (check != \"no-warn\") {\n        warning(paste0(\"Name '\", name, \"' is a reserved word as defined in NODE_RESERVED_NAMES_CONST. Using '\", name2, \"' instead.\"))\n      }\n      name <- name2\n      \n    }\n  }\n  return (name)\n}\n    \n"
  },
  {
    "path": "R/zzz.R",
    "content": "# nocov start\n.onLoad <- function(libname, pkgname) {\n  if(getRversion() >= \"3.6.0\") {\n    # register S3-methods from Suggested packages\n    s3_register(\"igraph::as.igraph\", \"Node\")\n    s3_register(\"ape::as.phylo\", \"Node\")\n  }\n  invisible()\n}\n# nocov end"
  },
  {
    "path": "README.md",
    "content": "CRAN: [![CRAN Version](http://www.r-pkg.org/badges/version/data.tree)](https://cran.r-project.org/package=data.tree/) [![CRAN downloads](http://cranlogs.r-pkg.org/badges/data.tree)](https://cran.r-project.org/package=data.tree/)\n\n\n<!-- badges: start -->\n[![R-CMD-check](https://github.com/gluc/data.tree/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/gluc/data.tree/actions/workflows/R-CMD-check.yaml)\n<!-- badges: end -->\n\n\n# data.tree\nAn R package to manage hierarchical data and tree structures\n\nHierarchical data is ubiquitous in statistics and programming (XML, search trees, family trees, classification, file system, etc.). However, no general-use *tree data structure* is available in base R. \nWhere tabular data has data.frame, hierarchical data is often modeled in lists of lists or similar makeshifts. These\nstructures are often difficult to manage.\nThis is where the data.tree package steps in. It lets you build trees of hierarchical\ndata for various uses: to print, plot and visualize, to generate breakdowns, to integrate with html widgets, to rapid prototype search algorithms, to test out new classification ideas, and much more.\n\nTree structures can be created programmatically, or by conversion. The package provides functionality to convert from and to various formats such as data.frames, list of lists, dendrograms, partykit, ape phylo, igraph, JSON, YAML, and more.\n\n# Learn More\n\nTo get started, you might want to read the [introduction vignette](https://CRAN.R-project.org/package=data.tree/vignettes/data.tree.html). There is also a vignette containing some [examples and applications](https://CRAN.R-project.org/package=data.tree/vignettes/applications.html).\n\nThe manual is [here](https://CRAN.R-project.org/package=data.tree/data.tree.pdf)\n\nFinally, you'll find more examples and background information on my [blog](http://ipub.com/data-tree).\n\n# NOTE:\nThe latest from github dev branch may have some breaking changes compared to CRAN. See [NEWS](https://github.com/gluc/data.tree/blob/dev/NEWS) for details.\n\n\n# Conventions:\n\nCoding Conventions: Google Style Guide, see https://google.github.io/styleguide/Rguide.xml\n\nVersioning Conventions: SemanticVersioning. See http://semver.org/ for details\n\nBranching Conventions: GitFlow. See https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow\n\nPull Requests: Very welcome! Please branch from the dev branch.\n"
  },
  {
    "path": "appveyor.yml",
    "content": "# DO NOT CHANGE the \"init\" and \"install\" sections below\n\n# Download script file from GitHub\ninit:\n  ps: |\n        $ErrorActionPreference = \"Stop\"\n        Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile \"..\\appveyor-tool.ps1\"\n        Import-Module '..\\appveyor-tool.ps1'\n\ninstall:\n  ps: Bootstrap\n\n# Adapt as necessary starting from here\n\n#in case of problems, you might want to comment this out to clean the cache\n#See here: https://www.appveyor.com/docs/build-cache/\ncache:\n  #- C:\\RLibrary\n\nenvironment:\n  global:\n    WARNINGS_ARE_ERRORS: 1\n\n  matrix:\n  - R_VERSION: devel\n    GCC_PATH: mingw_32\n\n  - R_VERSION: release\n    R_ARCH: x64\n\n  - R_VERSION: stable\n\n  - R_VERSION: patched\n\n\nbuild_script:\n  - travis-tool.sh install_deps\n\ntest_script:\n  - travis-tool.sh run_tests\n\non_failure:\n  - 7z a failure.zip *.Rcheck\\*\n  - appveyor PushArtifact failure.zip\n\nartifacts:\n  - path: '*.Rcheck\\**\\*.log'\n    name: Logs\n\n  - path: '*.Rcheck\\**\\*.out'\n    name: Logs\n\n  - path: '*.Rcheck\\**\\*.fail'\n    name: Logs\n\n  - path: '*.Rcheck\\**\\*.Rout'\n    name: Logs\n\n  - path: '\\*_*.tar.gz'\n    name: Bits\n\n  - path: '\\*_*.zip'\n    name: Bits\n"
  },
  {
    "path": "cran-comments.md",
    "content": "## General Comments\n\nThis release was done as requested by Kurt Hornik, because of a problem with roxygen2. I now used \"_PACKAGE\" and it should solvel the problem.\nAlso I added a few features and fixed a few bugs. Finally, I deprecated two functions, as anounced earlier ($fields and $fieldsAll).\n\nBest Regards, Christoph\n\n## Test environments\n\n* github -> (macos-latest release, windows-latest release, ubuntu-latest devel, ubuntu-latest release, ubuntu-latest oldrel-1) -> OK\n* rhub::check_for_cran -> NOTES\n\n## R CMD check results\n\nThere were no ERRORs or WARNINGs.\n\nI'm getting funny NOTES on rhub::check_for_cran:\n\n```\n* checking CRAN incoming feasibility ... [11s] NOTE\nMaintainer: 'Christoph Glur <christoph.glur@powerpartners.pro>'\n\nNew maintainer:\n  Christoph Glur <christoph.glur@powerpartners.pro>\nOld maintainer(s):\n  Christoph Glur <christoph.glur@ipub.com>\n* checking Rd files ... NOTE\ncheckRd: (-1) s3_register.Rd:46-48: Lost braces\n    46 | if (getRversion() >= \"3.6.0\") {\n       |                               ^\n* checking for non-standard things in the check directory ... NOTE\nFound the following files/directories:\n  ''NULL''\n* checking for detritus in the temp directory ... NOTE\nFound the following files/directories:\n  'lastMiKTeXException'\n```\n\nI couldn't reproduce this anywhere else, and I'm not sure if this is an issue with my code or with the check environment.\n\nLet me know if I was careless and there is anything for me to fix.\n\n\n## revdepcheck results\n\nWe checked 53 reverse dependencies (46 from CRAN + 7 from Bioconductor), comparing R CMD check results across CRAN and dev versions of this package.\n\n * We saw 3 new problems\n * We failed to check 0 packages\n\nIssues with CRAN packages are summarised below.\n\n### New problems\n(This reports the first line of each new failure)\n\n* collapsibleTree\n  checking examples ... WARNING\n\n* directotree\n  checking examples ... WARNING\n\n* forestry\n  checking examples ... WARNING\n  \n✔ behaviorchange 0.5.5                   ── E: 0     | W: 0     | N: 0  \n✖ collapsibleTree 0.1.7                  ── E: 0     | W: 0  +1 | N: 2   \n✔ covid19dbcand 0.1.1                    ── E: 0     | W: 0     | N: 0  \n✔ Cluster.OBeu 1.2.3                     ── E: 0     | W: 0     | N: 0   \n✔ CondCopulas 0.1.3                      ── E: 0     | W: 0     | N: 0   \n✖ directotree 1.0.0                      ── E: 0     | W: 0  +1 | N: 1    \n✔ CovRegRF 1.0.4                         ── E: 0     | W: 0     | N: 0   \n✔ echarty 1.6.2                          ── E: 0     | W: 0     | N: 0   \n✔ changepoints 1.1.0                     ── E: 0     | W: 0     | N: 0   \n✔ filterNHP 0.1.2                        ── E: 0     | W: 0     | N: 1    \n✖ forestry 0.1.0                         ── E: 0     | W: 0  +1 | N: 0   \n✔ echarts4r 0.4.5                        ── E: 0     | W: 0     | N: 0   \n✔ GE 0.4.0                               ── E: 0     | W: 0     | N: 0   \n✔ gimme 0.7.15                           ── E: 0     | W: 0     | N: 0   \n✔ galah 1.5.4                            ── E: 0     | W: 0     | N: 0   \n✔ icesTAF 4.2.0                          ── E: 0     | W: 0     | N: 0   \n✔ htetree 0.1.17                         ── E: 0     | W: 0     | N: 0  \n✔ justifier 0.2.6                        ── E: 0     | W: 0     | N: 0  \n✔ LinTInd 1.6.0                          ── E: 1     | W: 0     | N: 2  \n✔ cola 2.8.0                             ── E: 1     | W: 0     | N: 1   \n✔ nmarank 0.3.0                          ── E: 0     | W: 0     | N: 0   \n✔ LACE 2.6.0                             ── E: 0     | W: 0     | N: 1   \n✔ momentuHMM 1.5.5                       ── E: 1     | W: 0     | N: 0   \n✔ pmxTools 1.3                           ── E: 0     | W: 1     | N: 0   \n✔ nonlinearICP 0.1.2.1                   ── E: 0     | W: 0     | N: 0  \n✔ radiant.model 1.6.3                    ── E: 0     | W: 0     | N: 0  \n✔ Pi 2.14.0                              ── E: 0     | W: 0     | N: 1  \n✔ ranktreeEnsemble 0.22                  ── E: 0     | W: 0     | N: 0  \n✔ randomForestSRC 3.2.2                  ── E: 0     | W: 0     | N: 0 \n✔ RFpredInterval 1.0.7                   ── E: 0     | W: 0     | N: 0 \n✔ Rgff 0.1.6                             ── E: 0     | W: 0     | N: 1  \n✔ SACCR 3.2                              ── E: 0     | W: 0     | N: 0   \n✔ shinyTree 0.3.1                        ── E: 0     | W: 0     | N: 0  \n✔ ClassifyR 3.6.2                        ── E: 1     | W: 0     | N: 3  \n✔ rock 0.6.7                             ── E: 0     | W: 0     | N: 0  \n✔ scicomptools 1.0.0                     ── E: 0     | W: 0     | N: 0  \n✔ SoilTaxonomy 0.2.3                     ── E: 0     | W: 0     | N: 0  \n✔ rocTree 1.1.1                          ── E: 0     | W: 0     | N: 1   \n✔ styler 1.10.2                          ── E: 0     | W: 0     | N: 0   \n✔ supportR 1.2.0                         ── E: 0     | W: 0     | N: 0   \n✔ tidygraph 1.2.3                        ── E: 0     | W: 0     | N: 0   \n✔ starvz 0.7.1                           ── E: 0     | W: 0     | N: 0 \n✔ triversity 1.0                         ── E: 0     | W: 0     | N: 0 \n✔ TT 0.98                                ── E: 0     | W: 0     | N: 0  \n✔ VERSO 1.12.0                           ── E: 0     | W: 0     | N: 0  \n✔ voronoiTreemap 0.2.0                   ── E: 0     | W: 0     | N: 0  \n✔ TKCat 1.0.7                            ── E: 0     | W: 0     | N: 0  \n✔ webchem 1.3.0                          ── E: 0     | W: 0     | N: 0 \n✔ yum 0.1.0                              ── E: 0     | W: 0     | N: 0 \n✔ wrTopDownFrag 1.0.2                    ── E: 0     | W: 0     | N: 1 \n✔ scAnnotatR 1.8.0                       ── E: 0     | W: 0     | N: 0  \n✔ wrMisc 1.13.0                          ── E: 0     | W: 0     | N: 0 \n✔ UniprotR 2.3.0                         ── E: 0     | W: 0     | N: 0 \n\n### Problems Description\n\nAll three problems are a result of the deprecated functions.\nI notified the maintainers of the packages."
  },
  {
    "path": "data.tree.Rproj",
    "content": "Version: 1.0\n\nRestoreWorkspace: No\nSaveWorkspace: No\nAlwaysSaveHistory: No\n\nEnableCodeIndexing: Yes\nUseSpacesForTab: Yes\nNumSpacesForTab: 2\nEncoding: UTF-8\n\nRnwWeave: knitr\nLaTeX: pdfLaTeX\n\nBuildType: Package\nPackageUseDevtools: Yes\nPackageInstallArgs: --no-multiarch --with-keep.source\nPackageBuildArgs: --resave-data\nPackageBuildBinaryArgs: --resave-data\nPackageCheckArgs: --as-cran\nPackageRoxygenize: rd,collate,namespace\n"
  },
  {
    "path": "data_gen/acme.R",
    "content": "#Run this to generate data(acme)\n\n#library(data.tree)ac\nacme <- Node$new(\"Acme Inc.\")\naccounting <- acme$AddChild(\"Accounting\")\nsoftware <- accounting$AddChild(\"New Software\")\nstandards <- accounting$AddChild(\"New Accounting Standards\")\nresearch <- acme$AddChild(\"Research\")\nnewProductLine <- research$AddChild(\"New Product Line\")\nnewLabs <- research$AddChild(\"New Labs\")\nit <- acme$AddChild(\"IT\")\noutsource <- it$AddChild(\"Outsource\")\nagile <- it$AddChild(\"Go agile\")\ngoToR <- it$AddChild(\"Switch to R\")\n\n\nsoftware$cost <- 1000000\nstandards$cost <- 500000\nnewProductLine$cost <- 2000000\nnewLabs$cost <- 750000\noutsource$cost <- 400000\nagile$cost <- 250000\ngoToR$cost <- 50000\n\nsoftware$p <- 0.5\nstandards$p <- 0.75\nnewProductLine$p <- 0.25\nnewLabs$p <- 0.9\noutsource$p <- 0.2\nagile$p <- 0.05\ngoToR$p <- 1\n\nsave(acme, file = \"data/acme.rda\", compress = \"xz\")"
  },
  {
    "path": "data_gen/mushroom.R",
    "content": "color <- c('red', 'brown', 'brown', 'green', 'red')\nsize <- c('small', 'small', 'large', 'small', 'large')\npoints <- c('yes', 'no', 'yes', 'no', 'no')\nedible <- c('toxic', 'edible', 'edible', 'edible', 'edible')\nmushroom <- data.frame(color = color, size = size, points = points, edibility = edible)\nsave(mushroom, file = \"data/mushroom.rda\", compress = \"xz\")\n\n"
  },
  {
    "path": "getting-started-with-development.md",
    "content": "# Dev Guide\n\nTo develop on a new environment, you need to:\n\n1. pull from CRAN (dev branch)\n2. install R\n3. install RStudio\n4. install RTools (https://cran.rstudio.com/bin/windows/Rtools/)\n4. install tinytex\n  1. install.packages('tinytex')\n  2. tinytex::install_tinytex()\n  3. tinytex:::install_yihui_pkgs()\n5. re-start RStudio\n6. install devtools by running `install.packages(\"devtools\")`\n "
  },
  {
    "path": "inst/extdata/flare.json",
    "content": "{\n \"name\": \"flare\",\n \"children\": [\n  {\n   \"name\": \"analytics\",\n   \"children\": [\n    {\n     \"name\": \"cluster\",\n     \"children\": [\n      {\"name\": \"AgglomerativeCluster\", \"size\": 3938},\n      {\"name\": \"CommunityStructure\", \"size\": 3812},\n      {\"name\": \"HierarchicalCluster\", \"size\": 6714},\n      {\"name\": \"MergeEdge\", \"size\": 743}\n     ]\n    },\n    {\n     \"name\": \"graph\",\n     \"children\": [\n      {\"name\": \"BetweennessCentrality\", \"size\": 3534},\n      {\"name\": \"LinkDistance\", \"size\": 5731},\n      {\"name\": \"MaxFlowMinCut\", \"size\": 7840},\n      {\"name\": \"ShortestPaths\", \"size\": 5914},\n      {\"name\": \"SpanningTree\", \"size\": 3416}\n     ]\n    },\n    {\n     \"name\": \"optimization\",\n     \"children\": [\n      {\"name\": \"AspectRatioBanker\", \"size\": 7074}\n     ]\n    }\n   ]\n  },\n  {\n   \"name\": \"animate\",\n   \"children\": [\n    {\"name\": \"Easing\", \"size\": 17010},\n    {\"name\": \"FunctionSequence\", \"size\": 5842},\n    {\n     \"name\": \"interpolate\",\n     \"children\": [\n      {\"name\": \"ArrayInterpolator\", \"size\": 1983},\n      {\"name\": \"ColorInterpolator\", \"size\": 2047},\n      {\"name\": \"DateInterpolator\", \"size\": 1375},\n      {\"name\": \"Interpolator\", \"size\": 8746},\n      {\"name\": \"MatrixInterpolator\", \"size\": 2202},\n      {\"name\": \"NumberInterpolator\", \"size\": 1382},\n      {\"name\": \"ObjectInterpolator\", \"size\": 1629},\n      {\"name\": \"PointInterpolator\", \"size\": 1675},\n      {\"name\": \"RectangleInterpolator\", \"size\": 2042}\n     ]\n    },\n    {\"name\": \"ISchedulable\", \"size\": 1041},\n    {\"name\": \"Parallel\", \"size\": 5176},\n    {\"name\": \"Pause\", \"size\": 449},\n    {\"name\": \"Scheduler\", \"size\": 5593},\n    {\"name\": \"Sequence\", \"size\": 5534},\n    {\"name\": \"Transition\", \"size\": 9201},\n    {\"name\": \"Transitioner\", \"size\": 19975},\n    {\"name\": \"TransitionEvent\", \"size\": 1116},\n    {\"name\": \"Tween\", \"size\": 6006}\n   ]\n  },\n  {\n   \"name\": \"data\",\n   \"children\": [\n    {\n     \"name\": \"converters\",\n     \"children\": [\n      {\"name\": \"Converters\", \"size\": 721},\n      {\"name\": \"DelimitedTextConverter\", \"size\": 4294},\n      {\"name\": \"GraphMLConverter\", \"size\": 9800},\n      {\"name\": \"IDataConverter\", \"size\": 1314},\n      {\"name\": \"JSONConverter\", \"size\": 2220}\n     ]\n    },\n    {\"name\": \"DataField\", \"size\": 1759},\n    {\"name\": \"DataSchema\", \"size\": 2165},\n    {\"name\": \"DataSet\", \"size\": 586},\n    {\"name\": \"DataSource\", \"size\": 3331},\n    {\"name\": \"DataTable\", \"size\": 772},\n    {\"name\": \"DataUtil\", \"size\": 3322}\n   ]\n  },\n  {\n   \"name\": \"display\",\n   \"children\": [\n    {\"name\": \"DirtySprite\", \"size\": 8833},\n    {\"name\": \"LineSprite\", \"size\": 1732},\n    {\"name\": \"RectSprite\", \"size\": 3623},\n    {\"name\": \"TextSprite\", \"size\": 10066}\n   ]\n  },\n  {\n   \"name\": \"flex\",\n   \"children\": [\n    {\"name\": \"FlareVis\", \"size\": 4116}\n   ]\n  },\n  {\n   \"name\": \"physics\",\n   \"children\": [\n    {\"name\": \"DragForce\", \"size\": 1082},\n    {\"name\": \"GravityForce\", \"size\": 1336},\n    {\"name\": \"IForce\", \"size\": 319},\n    {\"name\": \"NBodyForce\", \"size\": 10498},\n    {\"name\": \"Particle\", \"size\": 2822},\n    {\"name\": \"Simulation\", \"size\": 9983},\n    {\"name\": \"Spring\", \"size\": 2213},\n    {\"name\": \"SpringForce\", \"size\": 1681}\n   ]\n  },\n  {\n   \"name\": \"query\",\n   \"children\": [\n    {\"name\": \"AggregateExpression\", \"size\": 1616},\n    {\"name\": \"And\", \"size\": 1027},\n    {\"name\": \"Arithmetic\", \"size\": 3891},\n    {\"name\": \"Average\", \"size\": 891},\n    {\"name\": \"BinaryExpression\", \"size\": 2893},\n    {\"name\": \"Comparison\", \"size\": 5103},\n    {\"name\": \"CompositeExpression\", \"size\": 3677},\n    {\"name\": \"Count\", \"size\": 781},\n    {\"name\": \"DateUtil\", \"size\": 4141},\n    {\"name\": \"Distinct\", \"size\": 933},\n    {\"name\": \"Expression\", \"size\": 5130},\n    {\"name\": \"ExpressionIterator\", \"size\": 3617},\n    {\"name\": \"Fn\", \"size\": 3240},\n    {\"name\": \"If\", \"size\": 2732},\n    {\"name\": \"IsA\", \"size\": 2039},\n    {\"name\": \"Literal\", \"size\": 1214},\n    {\"name\": \"Match\", \"size\": 3748},\n    {\"name\": \"Maximum\", \"size\": 843},\n    {\n     \"name\": \"methods\",\n     \"children\": [\n      {\"name\": \"add\", \"size\": 593},\n      {\"name\": \"and\", \"size\": 330},\n      {\"name\": \"average\", \"size\": 287},\n      {\"name\": \"count\", \"size\": 277},\n      {\"name\": \"distinct\", \"size\": 292},\n      {\"name\": \"div\", \"size\": 595},\n      {\"name\": \"eq\", \"size\": 594},\n      {\"name\": \"fn\", \"size\": 460},\n      {\"name\": \"gt\", \"size\": 603},\n      {\"name\": \"gte\", \"size\": 625},\n      {\"name\": \"iff\", \"size\": 748},\n      {\"name\": \"isa\", \"size\": 461},\n      {\"name\": \"lt\", \"size\": 597},\n      {\"name\": \"lte\", \"size\": 619},\n      {\"name\": \"max\", \"size\": 283},\n      {\"name\": \"min\", \"size\": 283},\n      {\"name\": \"mod\", \"size\": 591},\n      {\"name\": \"mul\", \"size\": 603},\n      {\"name\": \"neq\", \"size\": 599},\n      {\"name\": \"not\", \"size\": 386},\n      {\"name\": \"or\", \"size\": 323},\n      {\"name\": \"orderby\", \"size\": 307},\n      {\"name\": \"range\", \"size\": 772},\n      {\"name\": \"select\", \"size\": 296},\n      {\"name\": \"stddev\", \"size\": 363},\n      {\"name\": \"sub\", \"size\": 600},\n      {\"name\": \"sum\", \"size\": 280},\n      {\"name\": \"update\", \"size\": 307},\n      {\"name\": \"variance\", \"size\": 335},\n      {\"name\": \"where\", \"size\": 299},\n      {\"name\": \"xor\", \"size\": 354},\n      {\"name\": \"_\", \"size\": 264}\n     ]\n    },\n    {\"name\": \"Minimum\", \"size\": 843},\n    {\"name\": \"Not\", \"size\": 1554},\n    {\"name\": \"Or\", \"size\": 970},\n    {\"name\": \"Query\", \"size\": 13896},\n    {\"name\": \"Range\", \"size\": 1594},\n    {\"name\": \"StringUtil\", \"size\": 4130},\n    {\"name\": \"Sum\", \"size\": 791},\n    {\"name\": \"Variable\", \"size\": 1124},\n    {\"name\": \"Variance\", \"size\": 1876},\n    {\"name\": \"Xor\", \"size\": 1101}\n   ]\n  },\n  {\n   \"name\": \"scale\",\n   \"children\": [\n    {\"name\": \"IScaleMap\", \"size\": 2105},\n    {\"name\": \"LinearScale\", \"size\": 1316},\n    {\"name\": \"LogScale\", \"size\": 3151},\n    {\"name\": \"OrdinalScale\", \"size\": 3770},\n    {\"name\": \"QuantileScale\", \"size\": 2435},\n    {\"name\": \"QuantitativeScale\", \"size\": 4839},\n    {\"name\": \"RootScale\", \"size\": 1756},\n    {\"name\": \"Scale\", \"size\": 4268},\n    {\"name\": \"ScaleType\", \"size\": 1821},\n    {\"name\": \"TimeScale\", \"size\": 5833}\n   ]\n  },\n  {\n   \"name\": \"util\",\n   \"children\": [\n    {\"name\": \"Arrays\", \"size\": 8258},\n    {\"name\": \"Colors\", \"size\": 10001},\n    {\"name\": \"Dates\", \"size\": 8217},\n    {\"name\": \"Displays\", \"size\": 12555},\n    {\"name\": \"Filter\", \"size\": 2324},\n    {\"name\": \"Geometry\", \"size\": 10993},\n    {\n     \"name\": \"heap\",\n     \"children\": [\n      {\"name\": \"FibonacciHeap\", \"size\": 9354},\n      {\"name\": \"HeapNode\", \"size\": 1233}\n     ]\n    },\n    {\"name\": \"IEvaluable\", \"size\": 335},\n    {\"name\": \"IPredicate\", \"size\": 383},\n    {\"name\": \"IValueProxy\", \"size\": 874},\n    {\n     \"name\": \"math\",\n     \"children\": [\n      {\"name\": \"DenseMatrix\", \"size\": 3165},\n      {\"name\": \"IMatrix\", \"size\": 2815},\n      {\"name\": \"SparseMatrix\", \"size\": 3366}\n     ]\n    },\n    {\"name\": \"Maths\", \"size\": 17705},\n    {\"name\": \"Orientation\", \"size\": 1486},\n    {\n     \"name\": \"palette\",\n     \"children\": [\n      {\"name\": \"ColorPalette\", \"size\": 6367},\n      {\"name\": \"Palette\", \"size\": 1229},\n      {\"name\": \"ShapePalette\", \"size\": 2059},\n      {\"name\": \"SizePalette\", \"size\": 2291}\n     ]\n    },\n    {\"name\": \"Property\", \"size\": 5559},\n    {\"name\": \"Shapes\", \"size\": 19118},\n    {\"name\": \"Sort\", \"size\": 6887},\n    {\"name\": \"Stats\", \"size\": 6557},\n    {\"name\": \"Strings\", \"size\": 22026}\n   ]\n  },\n  {\n   \"name\": \"vis\",\n   \"children\": [\n    {\n     \"name\": \"axis\",\n     \"children\": [\n      {\"name\": \"Axes\", \"size\": 1302},\n      {\"name\": \"Axis\", \"size\": 24593},\n      {\"name\": \"AxisGridLine\", \"size\": 652},\n      {\"name\": \"AxisLabel\", \"size\": 636},\n      {\"name\": \"CartesianAxes\", \"size\": 6703}\n     ]\n    },\n    {\n     \"name\": \"controls\",\n     \"children\": [\n      {\"name\": \"AnchorControl\", \"size\": 2138},\n      {\"name\": \"ClickControl\", \"size\": 3824},\n      {\"name\": \"Control\", \"size\": 1353},\n      {\"name\": \"ControlList\", \"size\": 4665},\n      {\"name\": \"DragControl\", \"size\": 2649},\n      {\"name\": \"ExpandControl\", \"size\": 2832},\n      {\"name\": \"HoverControl\", \"size\": 4896},\n      {\"name\": \"IControl\", \"size\": 763},\n      {\"name\": \"PanZoomControl\", \"size\": 5222},\n      {\"name\": \"SelectionControl\", \"size\": 7862},\n      {\"name\": \"TooltipControl\", \"size\": 8435}\n     ]\n    },\n    {\n     \"name\": \"data\",\n     \"children\": [\n      {\"name\": \"Data\", \"size\": 20544},\n      {\"name\": \"DataList\", \"size\": 19788},\n      {\"name\": \"DataSprite\", \"size\": 10349},\n      {\"name\": \"EdgeSprite\", \"size\": 3301},\n      {\"name\": \"NodeSprite\", \"size\": 19382},\n      {\n       \"name\": \"render\",\n       \"children\": [\n        {\"name\": \"ArrowType\", \"size\": 698},\n        {\"name\": \"EdgeRenderer\", \"size\": 5569},\n        {\"name\": \"IRenderer\", \"size\": 353},\n        {\"name\": \"ShapeRenderer\", \"size\": 2247}\n       ]\n      },\n      {\"name\": \"ScaleBinding\", \"size\": 11275},\n      {\"name\": \"Tree\", \"size\": 7147},\n      {\"name\": \"TreeBuilder\", \"size\": 9930}\n     ]\n    },\n    {\n     \"name\": \"events\",\n     \"children\": [\n      {\"name\": \"DataEvent\", \"size\": 2313},\n      {\"name\": \"SelectionEvent\", \"size\": 1880},\n      {\"name\": \"TooltipEvent\", \"size\": 1701},\n      {\"name\": \"VisualizationEvent\", \"size\": 1117}\n     ]\n    },\n    {\n     \"name\": \"legend\",\n     \"children\": [\n      {\"name\": \"Legend\", \"size\": 20859},\n      {\"name\": \"LegendItem\", \"size\": 4614},\n      {\"name\": \"LegendRange\", \"size\": 10530}\n     ]\n    },\n    {\n     \"name\": \"operator\",\n     \"children\": [\n      {\n       \"name\": \"distortion\",\n       \"children\": [\n        {\"name\": \"BifocalDistortion\", \"size\": 4461},\n        {\"name\": \"Distortion\", \"size\": 6314},\n        {\"name\": \"FisheyeDistortion\", \"size\": 3444}\n       ]\n      },\n      {\n       \"name\": \"encoder\",\n       \"children\": [\n        {\"name\": \"ColorEncoder\", \"size\": 3179},\n        {\"name\": \"Encoder\", \"size\": 4060},\n        {\"name\": \"PropertyEncoder\", \"size\": 4138},\n        {\"name\": \"ShapeEncoder\", \"size\": 1690},\n        {\"name\": \"SizeEncoder\", \"size\": 1830}\n       ]\n      },\n      {\n       \"name\": \"filter\",\n       \"children\": [\n        {\"name\": \"FisheyeTreeFilter\", \"size\": 5219},\n        {\"name\": \"GraphDistanceFilter\", \"size\": 3165},\n        {\"name\": \"VisibilityFilter\", \"size\": 3509}\n       ]\n      },\n      {\"name\": \"IOperator\", \"size\": 1286},\n      {\n       \"name\": \"label\",\n       \"children\": [\n        {\"name\": \"Labeler\", \"size\": 9956},\n        {\"name\": \"RadialLabeler\", \"size\": 3899},\n        {\"name\": \"StackedAreaLabeler\", \"size\": 3202}\n       ]\n      },\n      {\n       \"name\": \"layout\",\n       \"children\": [\n        {\"name\": \"AxisLayout\", \"size\": 6725},\n        {\"name\": \"BundledEdgeRouter\", \"size\": 3727},\n        {\"name\": \"CircleLayout\", \"size\": 9317},\n        {\"name\": \"CirclePackingLayout\", \"size\": 12003},\n        {\"name\": \"DendrogramLayout\", \"size\": 4853},\n        {\"name\": \"ForceDirectedLayout\", \"size\": 8411},\n        {\"name\": \"IcicleTreeLayout\", \"size\": 4864},\n        {\"name\": \"IndentedTreeLayout\", \"size\": 3174},\n        {\"name\": \"Layout\", \"size\": 7881},\n        {\"name\": \"NodeLinkTreeLayout\", \"size\": 12870},\n        {\"name\": \"PieLayout\", \"size\": 2728},\n        {\"name\": \"RadialTreeLayout\", \"size\": 12348},\n        {\"name\": \"RandomLayout\", \"size\": 870},\n        {\"name\": \"StackedAreaLayout\", \"size\": 9121},\n        {\"name\": \"TreeMapLayout\", \"size\": 9191}\n       ]\n      },\n      {\"name\": \"Operator\", \"size\": 2490},\n      {\"name\": \"OperatorList\", \"size\": 5248},\n      {\"name\": \"OperatorSequence\", \"size\": 4190},\n      {\"name\": \"OperatorSwitch\", \"size\": 2581},\n      {\"name\": \"SortOperator\", \"size\": 2023}\n     ]\n    },\n    {\"name\": \"Visualization\", \"size\": 16540}\n   ]\n  }\n ]\n}"
  },
  {
    "path": "inst/extdata/jennylind.yaml",
    "content": "name: Jenny Lind\ntype: decision\nSign with Movie Company:\n  type: chance\n  Small Box Office:\n    type: terminal\n    p: 0.3\n    payoff: 200000\n  Medium Box Office:\n    type: terminal\n    p: 0.6\n    payoff: 1000000\n  Large Box Office:\n    type: terminal\n    p: 0.1\n    payoff: 3000000\nSign with TV Network:\n  type: chance\n  Small Box Office:\n    type: terminal\n    p: 0.3\n    payoff: 900000\n  Medium Box Office:\n    type: terminal\n    p: 0.6\n    payoff: 900000\n  Large Box Office:\n    type: terminal\n    p: 0.1\n    payoff: 900000\n"
  },
  {
    "path": "inst/extdata/portfolio.csv",
    "content": "ISIN,Name,Ccy,Type,Duration,Weight,AssetCategory,AssetClass,SubAssetClass\nLI0015327682,LGT Money Market Fund (CHF) - B,CHF,Fund,,0.0300,Cash,CHF,\nLI0214880598,CS (Lie) Money Market Fund EUR EB,EUR,Fund,,0.0600,Cash,EUR,\nLI0214880689,CS (Lie) Money Market Fund USD EB,USD,Fund,,0.0200,Cash,USD,\nLU0243957825,Invesco Euro Corporate Bond A EUR Acc,EUR,Fund,5.1,0.1200,Fixed Income,EUR,Sov. and Corp. Bonds\nLU0408877412,JPM Euro Gov Sh. Duration Bd A (acc)-EUR,EUR,Fund,2.45,0.0650,Fixed Income,EUR,Sov. and Corp. Bonds\nLU0376989207,Aberdeen Global Sel Emerg Mkt Bd A2 HEUR,EUR,Fund,6.8,0.0300,Fixed Income,EUR,Em. Mkts Bonds\nGB00B42R2118,Threadneedle European High Yield Bond Ret Grs EUR,EUR,Fund,3.4,0.0450,Fixed Income,EUR,High Yield Bonds\nLU0292585030,AXA IM FIIS US Short Dur HY F-C USD,USD,Fund,1.6,0.0250,Fixed Income,USD,High Yield Bonds\nCH0011037469,Syngenta AG,CHF,Stock,,0.0100,Equities,Switzerland,\nDE0008490145,DWS Zurich Invest Aktien Schweiz,EUR,Fund,,0.0500,Equities,Switzerland,\nNL0000303600,ING Grope NV,EUR,Stock,,0.0100,Equities,Euroland,\nIE00B60SWX25,Source EURO STOXX 50 UCITS ETF - A,EUR,ETF,,0.0800,Equities,Euroland,\nFR0000120271,TOTAL,EUR,Stock,,0.0140,Equities,Euroland,\nDE0008404005,Allianz SE,EUR,Stock,,0.0130,Equities,Euroland,\nIT0000072618,Intesa Sanpaolo S.p.A.,EUR,Stock,,0.0100,Equities,Euroland,\nBE0003793107,Anheuser-Busch INBEV,EUR,Stock,,0.0180,Equities,Euroland,\nUS4581401001,Intel Corp.,USD,Stock,,0.0100,Equities,US,\nUS0378331005,Apple Corp,USD,Stock,,0.0300,Equities,US,\nUS4370761029,Home Depot Inc.,USD,Stock,,0.0150,Equities,US,\nUS5949181045,Microsoft Corp.,USD,Stock,,0.0140,Equities,US,\nUS7427181091,Procter & Gamble Company,USD,Stock,,0.0120,Equities,US,\nGB00BH4HKS39,Vodafone Group PLC,GBP,Stock,,0.0090,Equities,UK,\nIE00B42Z5J44,iSHares MSCI Japan EUR Hedged,EUR,ETF,,0.0300,Equities,Japan,\nIE00B5377D42,iSHares MSCI Australia,USD,ETF,,0.0200,Equities,Australia,\nLU0040507039,Vontobel Emerging Markets Eq B,USD,Fund,,0.0550,Equities,Emerging Markets,\nLU0216734045,AXA WF Frm Europe Real Estate EUR,EUR,Fund,,0.0550,Alternative Investments,Real Estate,Eurozone\nLU0462954800,DB Platinum IV Systematic Alpha R1C-E,EUR,Fund,,0.1050,Alternative Investments,Hedge Funds,\nLU0239752628,UBS (LUX) Str. SICAV - Rogers Int. Com Idx (CHF),CHF,Fund,,0.0450,Alternative Investments,Commodities,\n"
  },
  {
    "path": "inst/extdata/useR15.csv",
    "content": "session,start,end,sessionName,room,seats,speaker,presentation\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Kaleidoscope 1,Aalborghallen,790,Federico Marini,flowcatchR: A user-friendly workflow solution for the analysis of time-lapse cell flow imaging data\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Kaleidoscope 1,Aalborghallen,790,Jonathan Clayden,Image processing and alignment with RNiftyReg and mmand\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Kaleidoscope 1,Aalborghallen,790,Carel F. W. Peeters,rags2ridges: Ridge estimation and graphical modeling for high-dimensional precision matrices\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Kaleidoscope 1,Aalborghallen,790,Henrik Tobias Madsen,dgRaph: Discrete factor graphs in R\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Ecology,Gæstesalen,149,Costas Varsos,Optimized R functions for analysis of ecological community data using the R virtual laboratory (Rvlab)\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Ecology,Gæstesalen,149,David L Miller,Building ecological models bit-by-bit\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Ecology,Gæstesalen,149,Andrew Dolman,\"Simulating ecological microcosms with systems of differential equations: tools for the scientific, technical and communication challenges\"\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Ecology,Gæstesalen,149,Marcel Austenfeld,\"A Graphical User Interface for R in an Integrated Development Environment for Ecological Modeling, Scientific Image Analysis and Statistical Analysis\"\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Networks,Musiksalen,160,Gergely Daroczi,fbRads: Analyzing and managing Facebook ads from R\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Networks,Musiksalen,160,Peter Meißner,Web scraping with R - A fast track overview.\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Networks,Musiksalen,160,Antonio Rivero Ostoic,multiplex: Analysis of Multiple Social Networks with Algebra\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Networks,Musiksalen,160,Gabor Csardi,What's new in igraph and networks\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Reproducibility,Det lille Teater,224,Karthik Ram,rOpenSci: A suite of reproducible research tools in R\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Reproducibility,Det lille Teater,224,Michael Lawrence,Enhancing reproducibility and collaboration via management of R package cohorts\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Reproducibility,Det lille Teater,224,Joshua R. Polanin & Emily A. Hennessy,A Review of Meta-Analysis Packages in R\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Reproducibility,Det lille Teater,224,David Smith,Simple reproducibility with the checkpoint package\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Interfacing,Radiosalen,216,Kasper D. Hansen,Some lessons relevant to including external libraries in your R package\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Interfacing,Radiosalen,216,Karl Millar,CXXR: Modernizing the R Interpreter\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Interfacing,Radiosalen,216,Matt P. Dziubinski,Naturally Sweet Rcpp with Modern C++ and Boost\nSession 1,01.07.2015 10:30,01.07.2015 12:00,Interfacing,Radiosalen,216,Dan Putler,Linking R to the Spark MLlib Machine Learning Library\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Kaleidoscope 2,Aalborghallen,790,Przemyslaw Biecek,\"archivist: Tools for Storing, Restoring and Searching for R Objects\"\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Kaleidoscope 2,Aalborghallen,790,Joseph B. Rickert,R User Groups\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Kaleidoscope 2,Aalborghallen,790,Richard M. Heiberger,Computational Precision and Floating-Point Arithmetic: A Teacher's Guide to Answering FAQ 7.31\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Kaleidoscope 2,Aalborghallen,790,Rasmus Bååth,\"Tiny Data, Approximate Bayesian Computation and the Socks of Karl Broman\"\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Case study,Gæstesalen,149,Johannes Breidenbach,Using R for small area estimation in the Norwegian National Forest Inventory\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Case study,Gæstesalen,149,Ivan Kasanický,Using R for natural gas market balancing in the Czech republic\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Case study,Gæstesalen,149,Jakob W. Messner,Heteroscedastic censored and truncated regression for weather forecasting\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Case study,Gæstesalen,149,Helle Sørensen,Multinomial functional regression with application to lameness detection for horses\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Clustering,Musiksalen,160,Anders Ellern Bilgrau,Unsupervised Clustering and Meta-Analysis using Gaussian Mixture Copula Models\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Clustering,Musiksalen,160,Claudia Beleites,Hierarchical Cluster Analysis of hyperspectral Raman images: a new point of view leads to 10000fold speedup\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Clustering,Musiksalen,160,Silvia Liverani,Dirichlet process Bayesian clustering with the R package PReMiuM\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Clustering,Musiksalen,160,Thomas Jagger,Examining the Environmental Characteristics of Tornado Outbreaks in the United States using Spatial Clustering\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Data Management,Det lille Teater,224,Filip Schouwenaars,Taking testing to another level: testwhat\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Data Management,Det lille Teater,224,Tony Fischetti,Failing fast and early: assertive/defensive programming for R data analysis pipelines\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Data Management,Det lille Teater,224,Hadley Wickham,Getting your data into R\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Data Management,Det lille Teater,224,Christoph Glur,A better way to manage hierarchical data\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Data Management,Det lille Teater,224,\"Indrajit Roy, Michael Lawrence\",A proposal for distributed data-structures in R\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Computational Performance,Radiosalen,216,E. James Harner,Running R+Hadoop using Docker Containers\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Computational Performance,Radiosalen,216,Matt P. Dziubinski,Algorithmic Differentiation for Extremum Estimation: An Introduction Using RcppEigen\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Computational Performance,Radiosalen,216,Kirill Müller,Improving computational performance with algorithm engineering\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Computational Performance,Radiosalen,216,Helena Kotthaus,Performance Analysis for Parallel R Programs: Towards Efficient Ressource Utilization\nSession 2,01.07.2015 13:30,01.07.2015 15:00,Computational Performance,Radiosalen,216,David Scott,Refactoring the xtable Package\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Kaleidoscope 3,Aalborghallen,790,Friedrich Schuster,Coding for the enterprise server - what does it mean for you?\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Kaleidoscope 3,Aalborghallen,790,Lukas Stadler,R as a citizen in a polyglot world - the promise of the Truffle framework\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Kaleidoscope 3,Aalborghallen,790,Tobias Verbeke,Architect. An IDE for Data Science and R\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Kaleidoscope 3,Aalborghallen,790,Balasubramanian Narasimhan,Distributed computing with R\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Business,Gæstesalen,149,Peter Baker,Statistical consulting using R: a DRY approach from the Australian outback\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Business,Gæstesalen,149,Stefan Milton Bache,Using R in Production\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Business,Gæstesalen,149,Giuseppe Bruno,Hedging and Risk Management of CDOs portfolio with R\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Business,Gæstesalen,149,Jim Porzak,Data Driven Customer Segmentation with R\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Spatial,Musiksalen,160,Ian Cook,Bringing Geospatial Tasks into the Mainstream of Business Analytics\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Spatial,Musiksalen,160,Jin Li,Novel hybrid spatial predictive methods of machine learning and geostatistics with applications to terrestrial and marine environments in Australia\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Spatial,Musiksalen,160,Matthias Eckardt,Graphical Modelling of Multivariate Spatial Point Patterns\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Spatial,Musiksalen,160,Virgilio Gomez-Rubio,Spatial Econometrics Models with R-INLA\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Spatial,Det lille Teater,224,Sebastian Meyer,Spatio-Temporal Analysis of Epidemic Phenomena Using the R Package surveillance\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Databases,Det lille Teater,224,Willem Ligtenberg,Rango - Databases made easy\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Databases,Det lille Teater,224,Hannes Mühleisen,Ad-Hoc User-Defined Functions for MonetDB with R\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Databases,Det lille Teater,224,Mateusz Zoltak,R database connectivity: what did we leave behind?\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Databases,Radiosalen,216,Jeroen Ooms,jsonlite and mongolite\nSession 3,01.07.2015 16:00,01.07.2015 17:30,Databases,Radiosalen,216,Michael Wurst,Using R Efficiently with Large Databases\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Kaleidoscope 4,Radiosalen,216,A. Jonathan R. Godfrey,While my base R gently weeps\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Kaleidoscope 4,Radiosalen,216,Amitai Golub,Rapid Deployment of Automatic Scoring Models to Hadoop Production Systems\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Kaleidoscope 4,Aalborghallen,790,Matt Dowle,\"Fast, stable and scalable true radix sorting\"\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Kaleidoscope 4,Aalborghallen,790,Arunkumar Srinivasan,\"Fast, flexible and memory efficient data manipulation using data.table\"\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Medicine,Gæstesalen,149,Marvin Steijaert,Phenotypic deconvolution: the next frontier in pharma\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Medicine,Gæstesalen,149,Lara Lusa,medplot: A Web Application for Dynamic Summary and Analysis of Longitudinal Medical Data Based on R and shiny\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Medicine,Gæstesalen,149,Paul Metcalfe,Using R and free software to improve the delivery of life changing medicine to patients\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Medicine,Gæstesalen,149,Heidi Seibold,Stratified medicine using the partykit package\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Regression,Musiksalen,160,Han Lin Shang,The ilc package\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Regression,Musiksalen,160,Andrew Bray,Approximately Exact Calculations for Linear Mixed Models\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Regression,Musiksalen,160,Alexandra Kuznetsova,Shiny application for analyzing consumer preference and sensory data in a mixed effects model framework: introducing SensMixed package\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Regression,Musiksalen,160,Chenjerai Kathy Mutambanengwe,Spatial regression of quantiles based on parametric distributions\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Regression,Det lille Teater,224,Helen Ogden,glmmsr: fitting GLMMs with sequential reduction\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Commercial Offerings,Det lille Teater,224,Michael Sannella,Supporting the Rapi C-language API in an R-compatible engine \nSession 4,02.07.2015 10:30,02.07.2015 11:00,Commercial Offerings,Det lille Teater,224,Woo J. Jung,Enabling R for Big Data with PL/R and PivotalR: Real World Examples on Hadoop & MPP Databases\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Commercial Offerings,Det lille Teater,224,Ron Pearson,The DataRobot R Package\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Commercial Offerings,Det lille Teater,224,Lou Bajuk-Yorgan,Applying the R Language in Streaming Applications and Business Intelligence\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Interactive graphics,Radiosalen,216,Monika Huhn,D3 and R Shiny - Making your graphs come to life\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Interactive graphics,Radiosalen,216,Michael Sachs,Interactive Graphics with ggplot2 and gridSVG\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Interactive graphics,Radiosalen,216,Joe Cheng,Interactive visualization using htmlwidgets and Shiny\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Interactive graphics,Radiosalen,216,Adrian Waddell,Interactive Data Visualization using the Loon package\nSession 4,02.07.2015 10:30,02.07.2015 11:00,Interactive graphics,Radiosalen,216,Wayne Oldford,New interactive visualization tools for exploring high dimensional data in R\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Kaleidoscope 5,Aalborghallen,790,Aimee Gott,Formalising R Development - ValidR Enterprise\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Kaleidoscope 5,Aalborghallen,790,Christoph Best,Integrating R with the Go programming language using interprocess communication\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Kaleidoscope 5,Aalborghallen,790,Jennifer Bryan,Fun times with R and Google Sheets\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Kaleidoscope 5,Aalborghallen,790,Jonathan Digby-North,A Comparative Study of Complex Estimation Software\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Kaleidoscope 5,Aalborghallen,790,Oliver Keyes,Software Standards in the R Community: An Analysis\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Teaching 1,Gæstesalen,149,Miranda Y Mortlock,SWOT analysis on using R for online training\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Teaching 1,Gæstesalen,149,Eric Hare,Manipulation of Discrete Random Variables in R with discreteRV\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Teaching 1,Gæstesalen,149,Matthias Gehrke,Teaching R in heterogeneous settings: Lessons learned\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Teaching 1,Gæstesalen,149,Chris Wild,Interactive applications written in R to accelerate statistical learning\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Teaching 1,Gæstesalen,149,James Curran,Classroom experiments\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Statistical Methodology 1,Musiksalen,160,Thomas Kiefer,TAM: An R Package for Item Response Modelling\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Statistical Methodology 1,Musiksalen,160,Genaro Sucarrat,gets: General-to-Specific (GETS) Modelling\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Statistical Methodology 1,Musiksalen,160,Thouvenot Vincent,R Package CASA: Component Automatic Selection in Additive models\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Statistical Methodology 1,Musiksalen,160,Christian Ritz,Dose-response analysis using R revisited\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Statistical Methodology 1,Musiksalen,160,Kaylea Haynes,Changepoints over a Range of Penalties using the changepoint package\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Machine Learning 1,Det lille Teater,224,\"Neda Daneshgar, Majid Sarmad\",Word Alignment tools in R\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Machine Learning 1,Det lille Teater,224,Markus Loecher,Rapid detection of spatiotemporal clusters\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Machine Learning 1,Det lille Teater,224,\"Arash Fard, Vishrut Gupta\",Scalable distributed random-forest in R\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Machine Learning 1,Det lille Teater,224,Marie Chavent,Multivariate analysis of mixed data: The PCAmixdata R package\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Machine Learning 1,Det lille Teater,224,Natalia da Silva,PPforest\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Visualisation 1,Radiosalen,216,Katrin Grimm,Reordering and selecting continuous variables for scatterplot matrices\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Visualisation 1,Radiosalen,216,Kirsten Van Hoorde,R-package to assess and visualize the calibration of multiclass risk predictions\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Visualisation 1,Radiosalen,216,Martijn Tennekes,tmap: creating thematic maps in a flexible way\nSession 5,02.07.2015 13:00,02.07.2015 14:30,Visualisation 1,Radiosalen,216,Tal Galili,\"The dendextend R package for manipulation of dendograms,visualization and comparison\"\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Kaleidoscope 6,Aalborghallen,790,Gabor Csardi,The METACRAN experiment\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Kaleidoscope 6,Aalborghallen,790,Pedro J. Aphalo,Using R in photobiology\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Kaleidoscope 6,Aalborghallen,790,Sven Jesper Knudsen,Industrial Big Data Analytics for Wind Turbines\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Kaleidoscope 6,Aalborghallen,790,Andrie de Vries,The Network Structure of R Packages\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Teaching 2,Gæstesalen,149,Gail Potter,Web Application Teaching Tools for Statistics Using Shiny and R\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Teaching 2,Gæstesalen,149,an online,Teaching R in\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Teaching 2,Gæstesalen,149,Jonathan Cornelissen,class\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Teaching 2,Gæstesalen,149,Colin Rundel,Teaching R using the github ecosystem\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Teaching 2,Musiksalen,160,Mine Cetinkaya-Rundel,\"Using R, RStudio, and Docker for introductory statistics teaching\"\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Statistical Methodology 2,Musiksalen,160,Christoph Sax,seasonal: An X-13 interface for seasonal adjustment\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Statistical Methodology 2,Musiksalen,160,Sören Möller,Estimating the Linfoot correlation in R\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Statistical Methodology 2,Musiksalen,160,Alexander Kowarik,Seasonal Adjustment with the R packages x12 and x12GUI\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Statistical Methodology 2,Det lille Teater,224,Il Do Ha,frailtyHL: R package for variable selection in general frailty models for various survival data\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Machine Learning 2,Det lille Teater,224,Jan Wijffels,Massive Online Data Stream Mining using R and MOA\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Machine Learning 2,Det lille Teater,224,Søren Havelund Welling,forestFloor: a package to visualize and comprehend the full curvature of random forests\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Machine Learning 2,Det lille Teater,224,Douglas Mason,Machine Learning for Internal Product Measurement\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Machine Learning 2,Det lille Teater,224,Erin LeDell,h2oEnsemble for Scalable Ensemble Learning in R\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Visualisation 2,Radiosalen,216,Thomas Levine,Plotting data as music videos in R\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Visualisation 2,Radiosalen,216,Eric Bonnet,NaviCell Web Service for Network-based Data Visualization\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Visualisation 2,Radiosalen,216,Laure Cougnaud,Easy visualizations of high-dimensional genomic data\nSession 6,02.07.2015 16:00,02.07.2015 17:30,Visualisation 2,Radiosalen,216,Paul Murrell,The gridGraphics Package"
  },
  {
    "path": "man/Aggregate.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods.R\n\\name{Aggregate}\n\\alias{Aggregate}\n\\title{Aggregate child values of a \\code{Node}, recursively.}\n\\usage{\nAggregate(node, attribute, aggFun, ...)\n}\n\\arguments{\n\\item{node}{the \\code{Node} on which to aggregate}\n\n\\item{attribute}{determines what is collected. The \\code{attribute} can be\n\\itemize{\n  \\item a.) the name of a \\bold{field} or a \\bold{property/active} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"p\")} or \\code{acme$Get(\"position\")}\n  \\item b.) the name of a \\bold{method} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"levelZeroBased\")}, where e.g. \\code{acme$levelZeroBased <- function() acme$level - 1}\n  \\item c.) a \\bold{function}, whose first argument must be a \\code{Node} e.g. \\code{acme$Get(function(node) node$cost * node$p)}\n }}\n\n\\item{aggFun}{the aggregation function to be applied to the children's \\code{attributes}}\n\n\\item{...}{any arguments to be passed on to attribute (in case it's a function)}\n}\n\\description{\nThe \\code{Aggregate} method lets you fetch an attribute from a \\code{Node}'s children, and then aggregate them\nusing \\code{aggFun}. For example, you can aggregate cost by summing costs of child \\code{Nodes}. This is especially useful in the\ncontext of tree traversal, when using post-order traversal mode.\n}\n\\details{\nAs with \\code{\\link{Get}}, the attribute can be a field, a method or a function. If the attribute on a child\nis \\code{NULL}, \\code{Aggregate} is called recursively on its children.\n}\n\\examples{\ndata(acme)\n\n#Aggregate on a field\nAggregate(acme, \"cost\", sum)\n\n#This is the same as:\nHomeRolledAggregate <- function(node) {\n  sum(sapply(node$children, function(child) {\n    if (!is.null(child$cost)) child$cost\n    else HomeRolledAggregate(child)\n  }))\n}\nHomeRolledAggregate(acme)\n\n#Aggregate using Get\nprint(acme, \"cost\", minCost = acme$Get(Aggregate, \"cost\", min))\n\n#use Aggregate with a function:\nAggregate(acme, function(x) x$cost * x$p, sum)\n\n#cache values along the way\nacme$Do(function(x) x$cost <- Aggregate(x, \"cost\", sum), traversal = \"post-order\")\nacme$IT$cost\n\n}\n\\seealso{\n\\code{\\link{Node}}\n}\n"
  },
  {
    "path": "man/AreNamesUnique.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods.R\n\\name{AreNamesUnique}\n\\alias{AreNamesUnique}\n\\title{Test whether all node names are unique.}\n\\usage{\nAreNamesUnique(node)\n}\n\\arguments{\n\\item{node}{The root \\code{Node} of the \\code{data.tree} structure to test}\n}\n\\value{\n\\code{TRUE} if all \\code{Node$name == TRUE} for all nodes in the tree\n}\n\\description{\nThis can be useful for some conversions.\n}\n\\examples{\ndata(acme)\nAreNamesUnique(acme)\nacme$name <- \"IT\"\nAreNamesUnique(acme)\n\n}\n\\seealso{\nas.igraph.Node\n}\n"
  },
  {
    "path": "man/CheckNameReservedWord.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/util.R\n\\name{CheckNameReservedWord}\n\\alias{CheckNameReservedWord}\n\\title{Checks whether \\code{name} is a reserved word, as defined in \\code{NODE_RESERVED_NAMES_CONST}.}\n\\usage{\nCheckNameReservedWord(name, check = c(\"check\", \"no-warn\", \"no-check\"))\n}\n\\arguments{\n\\item{name}{the name to check}\n\n\\item{check}{Either\n\\itemize{\n \\item{\\code{\"check\"}: if the name conformance should be checked and warnings should be printed in case of non-conformance (the default)}\n \\item{\\code{\"no-warn\"}: if the name conformance should be checked, but no warnings should be printed in case of non-conformance (if you expect non-conformance)}\n \\item{\\code{\"no-check\" or FALSE}: if the name conformance should not be checked; use this if performance is critical. However, in case of non-conformance, expect cryptic follow-up errors}\n}}\n}\n\\description{\nChecks whether \\code{name} is a reserved word, as defined in \\code{NODE_RESERVED_NAMES_CONST}.\n}\n"
  },
  {
    "path": "man/Climb.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods.R\n\\name{Climb}\n\\alias{Climb}\n\\title{Climb a tree from parent to children, by provided criteria.}\n\\usage{\n#node$Climb(...)\nClimb(node, ...)\n}\n\\arguments{\n\\item{node}{The root \\code{\\link{Node}} of the tree or subtree to climb}\n\n\\item{...}{an attribute-value pairlist to be searched. For brevity, you can also provide a character vector to search for names.}\n}\n\\value{\nthe \\code{Node} having path \\code{...}, or \\code{NULL} if such a path does not exist\n}\n\\description{\nThis method lets you climb the tree, from crutch to crutch. On each \\code{Node}, the\n\\code{Climb} finds the first child having attribute value equal to the the provided argument.\n}\n\\examples{\ndata(acme)\n\n#the following are all equivalent\nClimb(acme, 'IT', 'Outsource')\nClimb(acme, name = 'IT', name = 'Outsource')\nClimb(acme, 'IT')$Climb('Outsource')\nNavigate(acme, path = \"IT/Outsource\")\n\nClimb(acme, name = 'IT')\n\nClimb(acme, position = c(2, 1))\n#or, equivalent:\nClimb(acme, position = 2, position = 1)\nClimb(acme, name = \"IT\", cost = 250000)\n\ntree <- CreateRegularTree(5, 2)\ntree$Climb(c(\"1\", \"1\"), position = c(2, 2))$path\n\n}\n\\seealso{\n\\code{\\link{Node}}\n\n\\code{\\link{Navigate}}\n}\n"
  },
  {
    "path": "man/Clone.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods.R\n\\name{Clone}\n\\alias{Clone}\n\\title{Clone a tree (creates a deep copy)}\n\\usage{\nClone(node, pruneFun = NULL, attributes = FALSE)\n}\n\\arguments{\n\\item{node}{the root node of the tree or sub-tree to clone}\n\n\\item{pruneFun}{allows providing a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \nIf the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.}\n\n\\item{attributes}{if FALSE, then R class attributes (e.g. formatters and grViz styles)\nare not cloned. This makes the method faster.}\n}\n\\value{\nthe clone of the tree or sub-tree\n}\n\\description{\nThe method also clones object attributes (such as the formatters), if desired.\nIf the method is called on a non-root, then the parent relationship is not cloned,\nand the resulting \\code{\\link{Node}} will be a root.\n}\n\\examples{\ndata(acme)\nacmeClone <- Clone(acme)\nacmeClone$name <- \"New Acme\"\n# acmeClone does not point to the same reference object anymore:\nacme$name\n\n#cloning a subtree\ndata(acme)\nitClone <- Clone(acme$IT)\nitClone$isRoot\n\n\n}\n\\seealso{\nSetFormat\n}\n"
  },
  {
    "path": "man/CreateRandomTree.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/util.R\n\\name{CreateRandomTree}\n\\alias{CreateRandomTree}\n\\title{Create a tree for demo and testing}\n\\usage{\nCreateRandomTree(nodes = 100, root = Node$new(\"1\"), id = 1)\n}\n\\arguments{\n\\item{nodes}{The number of nodes to create}\n\n\\item{root}{the previous node (for recursion, typically use default value)}\n\n\\item{id}{The id (for recursion)}\n}\n\\description{\nCreate a tree for demo and testing\n}\n"
  },
  {
    "path": "man/CreateRegularTree.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/util.R\n\\name{CreateRegularTree}\n\\alias{CreateRegularTree}\n\\title{Create a tree for demo and testing}\n\\usage{\nCreateRegularTree(height = 5, branchingFactor = 3, parent = Node$new(\"1\"))\n}\n\\arguments{\n\\item{height}{the number of levels}\n\n\\item{branchingFactor}{the number of children per node}\n\n\\item{parent}{the parent node (for recursion)}\n}\n\\description{\nCreate a tree for demo and testing\n}\n"
  },
  {
    "path": "man/Cumulate.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods.R\n\\name{Cumulate}\n\\alias{Cumulate}\n\\title{Cumulate values among siblings}\n\\usage{\nCumulate(node, attribute, aggFun, ...)\n}\n\\arguments{\n\\item{node}{The node on which we want to cumulate}\n\n\\item{attribute}{determines what is collected. The \\code{attribute} can be\n\\itemize{\n  \\item a.) the name of a \\bold{field} or a \\bold{property/active} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"p\")} or \\code{acme$Get(\"position\")}\n  \\item b.) the name of a \\bold{method} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"levelZeroBased\")}, where e.g. \\code{acme$levelZeroBased <- function() acme$level - 1}\n  \\item c.) a \\bold{function}, whose first argument must be a \\code{Node} e.g. \\code{acme$Get(function(node) node$cost * node$p)}\n }}\n\n\\item{aggFun}{the aggregation function to be applied to the children's \\code{attributes}}\n\n\\item{...}{any arguments to be passed on to attribute (in case it's a function)}\n}\n\\description{\nFor example, you can sum up values of siblings before\nthis \\code{Node}.\n}\n\\examples{\ndata(acme)\nacme$Do(function(x) x$cost <- Aggregate(x, \"cost\", sum), traversal = \"post-order\")\nacme$Do(function(x) x$cumCost <- Cumulate(x, \"cost\", sum))\nprint(acme, \"cost\", \"cumCost\")\n\n}\n"
  },
  {
    "path": "man/DefaultPlotHeight.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/util.R\n\\name{DefaultPlotHeight}\n\\alias{DefaultPlotHeight}\n\\title{Calculates the height of a \\code{Node} given the height of the root.}\n\\usage{\nDefaultPlotHeight(node, rootHeight = 100)\n}\n\\arguments{\n\\item{node}{The node}\n\n\\item{rootHeight}{The height of the root}\n}\n\\description{\nThis function puts leafs at the bottom (not hanging), and makes edges equally long.\nUseful for easy plotting with third-party packages, e.g. if you have no specific height\nattribute, e.g. with \\code{\\link{as.dendrogram.Node}}, \\code{\\link{ToNewick}},\nand \\code{\\link{as.phylo.Node}}\n}\n\\examples{\ndata(acme)\ndacme <- as.dendrogram(acme, heightAttribute = function(x) DefaultPlotHeight(x, 200))\nplot(dacme, center = TRUE)\n\n}\n"
  },
  {
    "path": "man/Distance.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods.R\n\\name{Distance}\n\\alias{Distance}\n\\title{Find the distance between two nodes of the same tree}\n\\usage{\nDistance(node1, node2)\n}\n\\arguments{\n\\item{node1}{the first node in the tree}\n\n\\item{node2}{the second node in the same tree}\n}\n\\description{\nThe distance is measured as the number of edges that\nneed to be traversed to reach node2 when starting \nfrom node1.\n}\n\\examples{\ndata(acme)\nDistance(FindNode(acme, \"Outsource\"), FindNode(acme, \"Research\"))\n\n}\n"
  },
  {
    "path": "man/Do.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods_traversal.R\n\\name{Do}\n\\alias{Do}\n\\title{Executes a function on a set of nodes}\n\\usage{\n# OO-style:\n# node$Do(fun, \n#         ..., \n#         traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"), \n#         pruneFun = NULL, \n#         filterFun = NULL)\n         \n# traditional:\nDo(nodes, fun, ...)\n}\n\\arguments{\n\\item{nodes}{The nodes on which to perform the Get (typically obtained via \\code{\\link{Traverse}})}\n\n\\item{fun}{the function to execute. The function is expected to be either a Method, or to take a \nNode as its first argument}\n\n\\item{...}{any additional parameters to be passed on to fun}\n}\n\\description{\nExecutes a function on a set of nodes\n}\n\\examples{\ndata(acme)\ntraversal <- Traverse(acme)\nDo(traversal, function(node) node$expectedCost <- node$p * node$cost)\nprint(acme, \"expectedCost\")\n\n}\n\\seealso{\n\\code{\\link{Node}}\n\n\\code{\\link{Get}}\n\n\\code{\\link{Set}}\n\n\\code{\\link{Traverse}}\n}\n"
  },
  {
    "path": "man/FindNode.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods.R\n\\name{FindNode}\n\\alias{FindNode}\n\\title{Find a node by name in the (sub-)tree}\n\\usage{\nFindNode(node, name)\n}\n\\arguments{\n\\item{node}{The root \\code{Node} of the tree or sub-tree to search}\n\n\\item{name}{The name of the \\code{Node} to be returned}\n}\n\\value{\nThe first \\code{Node} whose name matches, or \\code{NULL} if no such \\code{Node} is\nfound.\n}\n\\description{\nScans the entire sub-tree spanned by \\code{node} and returns the first \\code{\\link{Node}}\nhaving the \\code{name} specified. This is mainly useful for trees whose name is unique.\nIf \\code{\\link{AreNamesUnique}} is \\code{FALSE}, i.e. if there is more than one \\code{Node}\ncalled \\code{name} in the tree, then it is undefined which one will be returned.\nAlso note that this method is not particularly fast. See examples for a faster way to\nindex large trees, if you need to do multiple searches. See \\code{\\link{Traverse}} if\nyou need to find multiple \\code{Nodes}.\n}\n\\examples{\ndata(acme)\nFindNode(acme, \"Outsource\")\n\n#re-usable hashed index for multiple searches:\nif(!AreNamesUnique(acme)) stop(\"Hashed index works for unique names only!\")\ntrav <- Traverse(acme, \"level\")\nnames(trav) <- Get(trav, \"name\")\nnameIndex <- as.environment(trav)\n#you could also use hash from package hash instead!\n#nameIndex <- hash(trav)\nnameIndex$Outsource\nnameIndex$IT\n\n\n}\n\\seealso{\nAreNamesUnique, Traverse\n}\n"
  },
  {
    "path": "man/FormatFixedDecimal.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/util.R\n\\name{FormatFixedDecimal}\n\\alias{FormatFixedDecimal}\n\\title{Format a Number as a Decimal}\n\\usage{\nFormatFixedDecimal(x, digits = 3)\n}\n\\arguments{\n\\item{x}{a numeric scalar or vector}\n\n\\item{digits}{the number of digits to print after the decimal point}\n}\n\\value{\nA string corresponding to x, suitable for printing\n}\n\\description{\nSimple function that can be used as a format function when converting trees to a \\code{data.frame}\n}\n\\examples{\ndata(acme)\nprint(acme, prob = acme$Get(\"p\", format = function(x) FormatFixedDecimal(x, 4)))\n\n}\n"
  },
  {
    "path": "man/FormatPercent.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/util.R\n\\name{FormatPercent}\n\\alias{FormatPercent}\n\\title{Format a Number as a Percentage}\n\\usage{\nFormatPercent(x, digits = 2, format = \"f\", ...)\n}\n\\arguments{\n\\item{x}{A number}\n\n\\item{digits}{The number of digits to print}\n\n\\item{format}{The format to use}\n\n\\item{...}{Any other argument passed to formatC}\n}\n\\value{\nA string corresponding to x, suitable for printing\n}\n\\description{\nThis utility method can be used as a format function when converting trees to a \\code{data.frame}\n}\n\\examples{\ndata(acme)\nprint(acme, prob = acme$Get(\"p\", format = FormatPercent))\n\n}\n\\seealso{\nformatC\n}\n"
  },
  {
    "path": "man/Get.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods_traversal.R\n\\name{Get}\n\\alias{Get}\n\\title{Traverse a Tree and Collect Values}\n\\usage{\n# OO-style:\n#node$Get(attribute, \n#        ..., \n#        traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"), \n#        pruneFun = NULL, \n#        filterFun = NULL, \n#        format = FALSE, \n#        inheritFromAncestors = FALSE)\n         \n# traditional:\nGet(nodes, \n    attribute, \n    ..., \n    format = FALSE, \n    inheritFromAncestors = FALSE, \n    simplify = c(TRUE, FALSE, \"array\", \"regular\"))\n}\n\\arguments{\n\\item{nodes}{The nodes on which to perform the Get (typically obtained via \\code{\\link{Traverse}})}\n\n\\item{attribute}{determines what is collected. The \\code{attribute} can be\n\\itemize{\n  \\item a.) the name of a \\bold{field} or a \\bold{property/active} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"p\")} or \\code{acme$Get(\"position\")}\n  \\item b.) the name of a \\bold{method} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"levelZeroBased\")}, where e.g. \\code{acme$levelZeroBased <- function() acme$level - 1}\n  \\item c.) a \\bold{function}, whose first argument must be a \\code{Node} e.g. \\code{acme$Get(function(node) node$cost * node$p)}\n }}\n\n\\item{...}{in case the \\code{attribute} is a function or a method, the ellipsis is passed to it as additional arguments.}\n\n\\item{format}{if \\code{FALSE} (the default), no formatting is being used. If \\code{TRUE}, then the first formatter (if any) found along the ancestor path is being used for formatting \n(see \\code{\\link{SetFormat}}). If \\code{format} is a function, then the collected value is passed to that function, and the result is returned.}\n\n\\item{inheritFromAncestors}{if \\code{TRUE}, then the path above a \\code{Node} is searched to get the \\code{attribute} in case it is NULL.}\n\n\\item{simplify}{same as \\code{\\link{sapply}}, i.e. TRUE, FALSE or \"array\". Additionally, you can specify \"regular\" if\neach returned value is of length > 1, and equally named. See below for an example.}\n}\n\\value{\na vector containing the \\code{atrributes} collected during traversal, in traversal order. \\code{NULL} is converted\nto NA, such that \\code{length(Node$Get) == Node$totalCount}\n}\n\\description{\nThe \\code{Get} method is one of the most important ones of the \\code{data.tree} package. It lets you traverse a tree\nand collect values along the way. Alternatively, you can call a method or a function on each \\code{\\link{Node}}.\n}\n\\examples{\ndata(acme)\nacme$Get(\"level\")\nacme$Get(\"totalCount\")\n \n\nacme$Get(function(node) node$cost * node$p,\n         filterFun = isLeaf)\n\n#This is equivalent:\nnodes <- Traverse(acme, filterFun = isLeaf)\nGet(nodes, function(node) node$cost * node$p)\n\n   \n#simplify = \"regular\" will preserve names\nacme$Get(function(x) c(position = x$position, level = x$level), simplify = \"regular\")\n \n}\n\\seealso{\n\\code{\\link{Node}}\n\n\\code{\\link{Set}}\n\n\\code{\\link{Do}}\n\n\\code{\\link{Traverse}}\n}\n"
  },
  {
    "path": "man/GetAttribute.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods.R\n\\name{GetAttribute}\n\\alias{GetAttribute}\n\\title{Get an attribute from a Node.}\n\\usage{\nGetAttribute(\n  node,\n  attribute,\n  ...,\n  format = FALSE,\n  inheritFromAncestors = FALSE,\n  nullAsNa = TRUE\n)\n}\n\\arguments{\n\\item{node}{The \\code{\\link{Node}} from which the \\code{attribute} should be fetched.}\n\n\\item{attribute}{determines what is collected. The \\code{attribute} can be\n\\itemize{\n  \\item a.) the name of a \\bold{field} or a \\bold{property/active} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"p\")} or \\code{acme$Get(\"position\")}\n  \\item b.) the name of a \\bold{method} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"levelZeroBased\")}, where e.g. \\code{acme$levelZeroBased <- function() acme$level - 1}\n  \\item c.) a \\bold{function}, whose first argument must be a \\code{Node} e.g. \\code{acme$Get(function(node) node$cost * node$p)}\n }}\n\n\\item{...}{in case the \\code{attribute} is a function or a method, the ellipsis is passed to it as additional arguments.}\n\n\\item{format}{if \\code{FALSE} (the default), no formatting is being used. If \\code{TRUE}, then the first formatter (if any) found along the ancestor path is being used for formatting \n(see \\code{\\link{SetFormat}}). If \\code{format} is a function, then the collected value is passed to that function, and the result is returned.}\n\n\\item{inheritFromAncestors}{if \\code{TRUE}, then the path above a \\code{Node} is searched to get the \\code{attribute} in case it is NULL.}\n\n\\item{nullAsNa}{If TRUE (the default), then NULL is returned as NA. Otherwise it is returned as NULL.}\n}\n\\description{\nGet an attribute from a Node.\n}\n\\examples{\ndata(acme)\nGetAttribute(acme$IT$Outsource, \"cost\")\n\n}\n"
  },
  {
    "path": "man/GetPhyloNr.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_ape.R\n\\name{GetPhyloNr}\n\\alias{GetPhyloNr}\n\\title{Determine the number a \\code{Node} has after conversion to a phylo object}\n\\usage{\nGetPhyloNr(x, type = c(\"node\", \"edge\"))\n}\n\\arguments{\n\\item{x}{The Node}\n\n\\item{type}{Either \"node\" (the default) or \"edge\" (to get the number of the edge from \\code{x} to its parent)}\n}\n\\value{\nan integer representing the node\n}\n\\description{\nUse this function when plotting a Node as a phylo, e.g. to set custom\nlabels to plot.\n}\n\\examples{\nlibrary(ape)\nlibrary(data.tree)\ndata(acme)\nap <- as.phylo(acme)\n#plot(ap)\n#nodelabels(\"IT Dep.\", GetPhyloNr(Climb(acme, \"IT\")))\n#edgelabels(\"Good!\", GetPhyloNr(Climb(acme, \"IT\", \"Switch to R\"), \"edge\"))\n\n\n}\n\\seealso{\nOther ape phylo conversions: \n\\code{\\link{as.Node.phylo}()},\n\\code{\\link{as.phylo.Node}()}\n}\n\\concept{ape phylo conversions}\n"
  },
  {
    "path": "man/NODE_RESERVED_NAMES_CONST.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node.R\n\\docType{data}\n\\name{NODE_RESERVED_NAMES_CONST}\n\\alias{NODE_RESERVED_NAMES_CONST}\n\\title{Names that are reserved by the Node class.}\n\\format{\nAn object of class \\code{character} of length 43.\n}\n\\usage{\nNODE_RESERVED_NAMES_CONST\n}\n\\description{\nThese are reserved by the Node class, you cannot use these as \nattribute names.\nNote also that all attributes starting with a . are reserved.\n}\n\\keyword{datasets}\n"
  },
  {
    "path": "man/Navigate.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods.R\n\\name{Navigate}\n\\alias{Navigate}\n\\title{Navigate to another node by relative path.}\n\\usage{\nNavigate(node, path)\n}\n\\arguments{\n\\item{node}{The starting \\code{\\link{Node}} to navigate}\n\n\\item{path}{A string or a character vector describing the path to navigate}\n}\n\\description{\nNavigate to another node by relative path.\n}\n\\details{\nThe \\code{path} is always relative to the \\code{node}. Navigation\nto the parent is defined by \\code{..}, whereas navigation to a child\nis defined via the child's name.\nIf path is provided as a string, then the navigation steps are separated\nby '/'.\n}\n\\examples{\ndata(acme)\nNavigate(acme$Research, \"../IT/Outsource\")\nNavigate(acme$Research, c(\"..\", \"IT\", \"Outsource\"))\n\n}\n\\seealso{\n\\code{\\link{Climb}}\n}\n"
  },
  {
    "path": "man/Node.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node.R\n\\docType{class}\n\\name{Node}\n\\alias{Node}\n\\title{Create a \\code{data.tree} Structure With \\code{Nodes}}\n\\format{\nAn \\code{\\link{R6Class}} generator object\n}\n\\usage{\n# n1 <- Node$new(\"Node 1\")\n}\n\\description{\n\\code{Node} is at the very heart of the \\code{data.tree} package. All trees are constructed\nby tying together \\code{Node} objects.\n}\n\\details{\nAssemble \\code{Node} objects into a \\code{data.tree}\nstructure and use the traversal methods to set, get, and perform operations on it. Typically, you construct larger tree \nstructures by converting from \\code{data.frame}, \\code{list}, or other formats.\n\nMost methods (e.g. \\code{node$Sort()}) also have a functional form (e.g. \\code{Sort(node)})\n}\n\\examples{\nlibrary(data.tree)\nacme <- Node$new(\"Acme Inc.\")\naccounting <- acme$AddChild(\"Accounting\")$\n              AddSibling(\"Research\")$\n              AddChild(\"New Labs\")$\n              parent$\n              AddSibling(\"IT\")$\n              AddChild(\"Outsource\")\nprint(acme)\n\n\n\n## ------------------------------------------------\n## Method `Node$new`\n## ------------------------------------------------\n\nnode <- Node$new(\"mynode\", x = 2, y = \"value of y\")\nnode$y\n\n\n## ------------------------------------------------\n## Method `Node$AddChild`\n## ------------------------------------------------\n\nroot <- Node$new(\"myroot\", myname = \"I'm the root\")\nroot$AddChild(\"child1\", myname = \"I'm the favorite child\")\nchild2 <- root$AddChild(\"child2\", myname = \"I'm just another child\")\nchild3 <- child2$AddChild(\"child3\", myname = \"Grandson of a root!\")\nprint(root, \"myname\")\n\n\n## ------------------------------------------------\n## Method `Node$AddChildNode`\n## ------------------------------------------------\n\nroot <- Node$new(\"myroot\")\nchild <- Node$new(\"mychild\")\nroot$AddChildNode(child)\n\n\n## ------------------------------------------------\n## Method `Node$AddSibling`\n## ------------------------------------------------\n\n#' root <- Node$new(\"myroot\")\nchild <- root$AddChild(\"child1\")\nsibling <- child$AddSibling(\"sibling1\")\n\n\n## ------------------------------------------------\n## Method `Node$AddSiblingNode`\n## ------------------------------------------------\n\nroot <- Node$new(\"myroot\")\nchild <- Node$new(\"mychild\")\nsibling <- Node$new(\"sibling\")\nroot$AddChildNode(child)$AddSiblingNode(sibling)\n\n\n## ------------------------------------------------\n## Method `Node$RemoveChild`\n## ------------------------------------------------\n\nnode <- Node$new(\"myroot\")$AddChild(\"mychild\")$root\nnode$RemoveChild(\"mychild\")\n\n\n## ------------------------------------------------\n## Method `Node$RemoveAttribute`\n## ------------------------------------------------\n\nnode <- Node$new(\"mynode\")\nnode$RemoveAttribute(\"age\", stopIfNotAvailable = FALSE)\nnode$age <- 27\nnode$RemoveAttribute(\"age\")\nnode\n\n\n## ------------------------------------------------\n## Method `Node$Sort`\n## ------------------------------------------------\n\ndata(acme)\nacme$Do(function(x) x$totalCost <- Aggregate(x, \"cost\", sum), traversal = \"post-order\")\nSort(acme, \"totalCost\", decreasing = FALSE)\nprint(acme, \"totalCost\")\n\n\n## ------------------------------------------------\n## Method `Node$Prune`\n## ------------------------------------------------\n\ndata(acme)\nacme$Do(function(x) x$cost <- Aggregate(x, \"cost\", sum))\nPrune(acme, function(x) x$cost > 700000)\nprint(acme, \"cost\")\n\n\n## ------------------------------------------------\n## Method `Node$Climb`\n## ------------------------------------------------\n\ndata(acme)\n\n#the following are all equivalent\nClimb(acme, 'IT', 'Outsource')\nClimb(acme, name = 'IT', name = 'Outsource')\nClimb(acme, 'IT')$Climb('Outsource')\nNavigate(acme, path = \"IT/Outsource\")\n\nClimb(acme, name = 'IT')\n\nClimb(acme, position = c(2, 1))\n#or, equivalent:\nClimb(acme, position = 2, position = 1)\nClimb(acme, name = \"IT\", cost = 250000)\n\ntree <- CreateRegularTree(5, 2)\ntree$Climb(c(\"1\", \"1\"), position = c(2, 2))$path\n\n\n\n## ------------------------------------------------\n## Method `Node$Navigate`\n## ------------------------------------------------\n\ndata(acme)\nNavigate(acme$Research, \"../IT/Outsource\")\nNavigate(acme$Research, c(\"..\", \"IT\", \"Outsource\"))\n\n\n## ------------------------------------------------\n## Method `Node$Get`\n## ------------------------------------------------\n\ndata(acme)\nacme$Get(\"level\")\nacme$Get(\"totalCount\")\n \n\nacme$Get(function(node) node$cost * node$p,\n         filterFun = isLeaf)\n\n#This is equivalent:\nnodes <- Traverse(acme, filterFun = isLeaf)\nGet(nodes, function(node) node$cost * node$p)\n\n   \n#simplify = \"regular\" will preserve names\nacme$Get(function(x) c(position = x$position, level = x$level), simplify = \"regular\")\n \n\n## ------------------------------------------------\n## Method `Node$Do`\n## ------------------------------------------------\n\ndata(acme)\nacme$Do(function(node) node$expectedCost <- node$p * node$cost)\nprint(acme, \"expectedCost\")\n\n\n## ------------------------------------------------\n## Method `Node$Set`\n## ------------------------------------------------\n\ndata(acme)\nacme$Set(departmentId = 1:acme$totalCount, openingHours = NULL, traversal = \"post-order\")\nacme$Set(head = c(\"Jack Brown\", \n                  \"Mona Moneyhead\", \n                  \"Dr. Frank N. Stein\", \n                  \"Eric Nerdahl\"\n                  ),\n         filterFun = function(x) !x$isLeaf\n        )\nprint(acme, \"departmentId\", \"head\")\n \n}\n\\seealso{\nFor more details see the \\code{\\link{data.tree}} documentations, or the \\code{data.tree} vignette: \\code{vignette(\"data.tree\")}\n\n\\code{\\link{Node}}\n\n\\code{\\link{Sort}}\n}\n\\section{Active bindings}{\n\\if{html}{\\out{<div class=\"r6-active-bindings\">}}\n\\describe{\n\\item{\\code{name}}{Gets or sets the name of a \\code{Node}. For example \\code{Node$name <- \"Acme\"}.}\n\n\\item{\\code{printFormatters}}{gets or sets the formatters used to print a \\code{Node}.\nSet this as a list to a root node.\nThe different formatters are h (horizontal), v (vertical), l (L), j (junction), and s (separator). \nFor example, you can set the formatters to \\code{list(h = \"\\u2500\" , v = \"\\u2502\", l = \"\\u2514\",  j = \"\\u251C\", s = \" \")}\nto get a similar behavior as in \\code{fs::dir_tree()}.\nThe defaults are: \\code{list(h = \"--\" , v = \"\\u00A6\", l = \"\\u00B0\", j = \"\\u00A6\", s = \" \")}}\n\n\\item{\\code{parent}}{Gets or sets the parent \\code{Node} of a \\code{Node}. Only set this if you know what you are doing, as you might mess up the tree structure!}\n\n\\item{\\code{children}}{Gets or sets the children \\code{list} of a \\code{Node}. Only set this if you know what you are doing, as you might mess up the tree structure!}\n\n\\item{\\code{isLeaf}}{Returns \\code{TRUE} if the \\code{Node} is a leaf, \\code{FALSE} otherwise}\n\n\\item{\\code{isRoot}}{Returns \\code{TRUE} if the \\code{Node} is the root, \\code{FALSE} otherwise}\n\n\\item{\\code{count}}{Returns the number of children of a \\code{Node}}\n\n\\item{\\code{totalCount}}{Returns the total number of \\code{Node}s in the tree}\n\n\\item{\\code{path}}{Returns a vector of mode \\code{character} containing the names of the \\code{Node}s in the path from the root to this \\code{Node}}\n\n\\item{\\code{pathString}}{Returns a string representing the path to this \\code{Node}, separated by backslash}\n\n\\item{\\code{position}}{The position of a \\code{Node} within its siblings}\n\n\\item{\\code{fields}}{Will be deprecated, use \\code{attributes} instead}\n\n\\item{\\code{fieldsAll}}{Will be deprecated, use \\code{attributesAll} instead}\n\n\\item{\\code{attributes}}{The attributes defined on this specific node}\n\n\\item{\\code{attributesAll}}{The distinct union of attributes defined on all the nodes in the tree spanned by this \\code{Node}}\n\n\\item{\\code{levelName}}{Returns the name of the \\code{Node}, preceded by level times '*'. Useful for printing and not typically called by package users.}\n\n\\item{\\code{leaves}}{Returns a list containing all the leaf \\code{Node}s}\n\n\\item{\\code{leafCount}}{Returns the number of leaves are below a \\code{Node}}\n\n\\item{\\code{level}}{Returns an integer representing the level of a \\code{Node}. For example, the root has level 1.}\n\n\\item{\\code{height}}{Returns max(level) of any of the \\code{Nodes} of the tree}\n\n\\item{\\code{isBinary}}{Returns \\code{TRUE} if all \\code{Node}s in the tree (except the leaves) have \\code{count = 2}}\n\n\\item{\\code{root}}{Returns the root of a \\code{Node} in a tree.}\n\n\\item{\\code{siblings}}{Returns a \\code{list} containing all the siblings of this \\code{Node}}\n\n\\item{\\code{averageBranchingFactor}}{Returns the average number of crotches below this \\code{Node}}\n}\n\\if{html}{\\out{</div>}}\n}\n\\section{Methods}{\n\\subsection{Public methods}{\n\\itemize{\n\\item \\href{#method-Node-new}{\\code{Node$new()}}\n\\item \\href{#method-Node-AddChild}{\\code{Node$AddChild()}}\n\\item \\href{#method-Node-AddChildNode}{\\code{Node$AddChildNode()}}\n\\item \\href{#method-Node-AddSibling}{\\code{Node$AddSibling()}}\n\\item \\href{#method-Node-AddSiblingNode}{\\code{Node$AddSiblingNode()}}\n\\item \\href{#method-Node-RemoveChild}{\\code{Node$RemoveChild()}}\n\\item \\href{#method-Node-RemoveAttribute}{\\code{Node$RemoveAttribute()}}\n\\item \\href{#method-Node-Sort}{\\code{Node$Sort()}}\n\\item \\href{#method-Node-Revert}{\\code{Node$Revert()}}\n\\item \\href{#method-Node-Prune}{\\code{Node$Prune()}}\n\\item \\href{#method-Node-Climb}{\\code{Node$Climb()}}\n\\item \\href{#method-Node-Navigate}{\\code{Node$Navigate()}}\n\\item \\href{#method-Node-Get}{\\code{Node$Get()}}\n\\item \\href{#method-Node-Do}{\\code{Node$Do()}}\n\\item \\href{#method-Node-Set}{\\code{Node$Set()}}\n\\item \\href{#method-Node-clone}{\\code{Node$clone()}}\n}\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-new\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-new}{}}}\n\\subsection{Method \\code{new()}}{\nCreate a new \\code{Node} object. This is often used to create the root of a tree when creating a tree programmatically.\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$new(name, check = c(\"check\", \"no-warn\", \"no-check\"), ...)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{name}}{the name of the node to be created}\n\n\\item{\\code{check}}{Either\n\\itemize{\n \\item{\\code{\"check\"}: if the name conformance should be checked and warnings should be printed in case of non-conformance (the default)}\n \\item{\\code{\"no-warn\"}: if the name conformance should be checked, but no warnings should be printed in case of non-conformance (if you expect non-conformance)}\n \\item{\\code{\"no-check\" or FALSE}: if the name conformance should not be checked; use this if performance is critical. However, in case of non-conformance, expect cryptic follow-up errors}\n}}\n\n\\item{\\code{...}}{A name-value mapping of node attributes}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Returns}{\nA new `Node` object\n}\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{node <- Node$new(\"mynode\", x = 2, y = \"value of y\")\nnode$y\n\n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-AddChild\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-AddChild}{}}}\n\\subsection{Method \\code{AddChild()}}{\nCreates a \\code{Node} and adds it as the last sibling as a child to the \\code{Node} on which this is called.\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$AddChild(name, check = c(\"check\", \"no-warn\", \"no-check\"), ...)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{name}}{the name of the node to be created}\n\n\\item{\\code{check}}{Either\n\\itemize{\n \\item{\\code{\"check\"}: if the name conformance should be checked and warnings should be printed in case of non-conformance (the default)}\n \\item{\\code{\"no-warn\"}: if the name conformance should be checked, but no warnings should be printed in case of non-conformance (if you expect non-conformance)}\n \\item{\\code{\"no-check\" or FALSE}: if the name conformance should not be checked; use this if performance is critical. However, in case of non-conformance, expect cryptic follow-up errors}\n}}\n\n\\item{\\code{...}}{A name-value mapping of node attributes}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Returns}{\nThe new \\code{Node} (invisibly)\n}\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{root <- Node$new(\"myroot\", myname = \"I'm the root\")\nroot$AddChild(\"child1\", myname = \"I'm the favorite child\")\nchild2 <- root$AddChild(\"child2\", myname = \"I'm just another child\")\nchild3 <- child2$AddChild(\"child3\", myname = \"Grandson of a root!\")\nprint(root, \"myname\")\n\n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-AddChildNode\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-AddChildNode}{}}}\n\\subsection{Method \\code{AddChildNode()}}{\nAdds a \\code{Node} as a child to this node.\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$AddChildNode(child)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{child}}{The child \\code{\"Node\"} to add.}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Returns}{\nthe child node added (this lets you chain calls)\n}\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{root <- Node$new(\"myroot\")\nchild <- Node$new(\"mychild\")\nroot$AddChildNode(child)\n\n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-AddSibling\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-AddSibling}{}}}\n\\subsection{Method \\code{AddSibling()}}{\nCreates a new \\code{Node} called \\code{name} and adds it after this \\code{Node} as a sibling.\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$AddSibling(name, check = c(\"check\", \"no-warn\", \"no-check\"), ...)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{name}}{the name of the node to be created}\n\n\\item{\\code{check}}{Either\n\\itemize{\n \\item{\\code{\"check\"}: if the name conformance should be checked and warnings should be printed in case of non-conformance (the default)}\n \\item{\\code{\"no-warn\"}: if the name conformance should be checked, but no warnings should be printed in case of non-conformance (if you expect non-conformance)}\n \\item{\\code{\"no-check\" or FALSE}: if the name conformance should not be checked; use this if performance is critical. However, in case of non-conformance, expect cryptic follow-up errors}\n}}\n\n\\item{\\code{...}}{A name-value mapping of node attributes}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Returns}{\nthe sibling node (this lets you chain calls)\n}\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{#' root <- Node$new(\"myroot\")\nchild <- root$AddChild(\"child1\")\nsibling <- child$AddSibling(\"sibling1\")\n\n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-AddSiblingNode\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-AddSiblingNode}{}}}\n\\subsection{Method \\code{AddSiblingNode()}}{\nAdds a \\code{Node} after this \\code{Node}, as a sibling.\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$AddSiblingNode(sibling)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{sibling}}{The \\code{\"Node\"} to add as a sibling.}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Returns}{\nthe added sibling node (this lets you chain calls, as in the examples)\n}\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{root <- Node$new(\"myroot\")\nchild <- Node$new(\"mychild\")\nsibling <- Node$new(\"sibling\")\nroot$AddChildNode(child)$AddSiblingNode(sibling)\n\n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-RemoveChild\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-RemoveChild}{}}}\n\\subsection{Method \\code{RemoveChild()}}{\nRemove the child \\code{Node} called \\code{name} from a \\code{Node} and returns it.\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$RemoveChild(name)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{name}}{the name of the node to be created}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Returns}{\nthe subtree spanned by the removed child.\n}\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{node <- Node$new(\"myroot\")$AddChild(\"mychild\")$root\nnode$RemoveChild(\"mychild\")\n\n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-RemoveAttribute\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-RemoveAttribute}{}}}\n\\subsection{Method \\code{RemoveAttribute()}}{\nRemoves attribute called \\code{name} from this \\code{Node}.\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$RemoveAttribute(name, stopIfNotAvailable = TRUE)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{name}}{the name of the node to be created}\n\n\\item{\\code{stopIfNotAvailable}}{Gives an error if \\code{stopIfNotAvailable} and the attribute does not exist.}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{node <- Node$new(\"mynode\")\nnode$RemoveAttribute(\"age\", stopIfNotAvailable = FALSE)\nnode$age <- 27\nnode$RemoveAttribute(\"age\")\nnode\n\n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-Sort\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-Sort}{}}}\n\\subsection{Method \\code{Sort()}}{\nSort children of a \\code{Node} or an entire \\code{data.tree} structure\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$Sort(attribute, ..., decreasing = FALSE, recursive = TRUE)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{attribute}}{determines what is collected. The \\code{attribute} can be\n\\itemize{\n  \\item a.) the name of a \\bold{field} or a \\bold{property/active} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"p\")} or \\code{acme$Get(\"position\")}\n  \\item b.) the name of a \\bold{method} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"levelZeroBased\")}, where e.g. \\code{acme$levelZeroBased <- function() acme$level - 1}\n  \\item c.) a \\bold{function}, whose first argument must be a \\code{Node} e.g. \\code{acme$Get(function(node) node$cost * node$p)}\n }}\n\n\\item{\\code{...}}{any parameters to be passed on the the attribute (in case it's a method or a \nfunction)}\n\n\\item{\\code{decreasing}}{sort order}\n\n\\item{\\code{recursive}}{if \\code{TRUE}, the method will be called recursively on the \\code{Node}'s children. This allows sorting an entire tree.}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Details}{\nYou can sort with respect to any argument of the tree. But note that sorting has\nside-effects, meaning that you modify the underlying, original data.tree object structure.\n\nSee also \\code{\\link{Sort}} for the equivalent function.\n}\n\n\\subsection{Returns}{\nReturns the node on which Sort is called, invisibly. This can be useful to chain Node methods.\n}\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{data(acme)\nacme$Do(function(x) x$totalCost <- Aggregate(x, \"cost\", sum), traversal = \"post-order\")\nSort(acme, \"totalCost\", decreasing = FALSE)\nprint(acme, \"totalCost\")\n\n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-Revert\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-Revert}{}}}\n\\subsection{Method \\code{Revert()}}{\nReverts the sort order of a \\code{Node}'s children.\n\nSee also \\code{\\link{Revert}} for the equivalent function.\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$Revert(recursive = TRUE)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{recursive}}{if \\code{TRUE}, the method will be called recursively on the \\code{Node}'s children. This allows sorting an entire tree.}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Returns}{\nreturns the Node invisibly (for chaining)\n}\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-Prune\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-Prune}{}}}\n\\subsection{Method \\code{Prune()}}{\nPrunes a tree. \n\nPruning refers to removing entire subtrees. This function has side-effects, it modifies your data.tree structure!\n\nSee also \\code{\\link{Prune}} for the equivalent function.\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$Prune(pruneFun)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{pruneFun}}{allows providing a a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \nIf the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Returns}{\nthe number of nodes removed\n}\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{data(acme)\nacme$Do(function(x) x$cost <- Aggregate(x, \"cost\", sum))\nPrune(acme, function(x) x$cost > 700000)\nprint(acme, \"cost\")\n\n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-Climb\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-Climb}{}}}\n\\subsection{Method \\code{Climb()}}{\nClimb a tree from parent to children, by provided criteria.\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$Climb(...)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{...}}{an attribute-value pairlist to be searched. For brevity, you can also provide a character vector to search for names.}\n\n\\item{\\code{node}}{The root \\code{\\link{Node}} of the tree or subtree to climb}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Details}{\nThis method lets you climb the tree, from crutch to crutch. On each \\code{Node}, the\n\\code{Climb} finds the first child having attribute value equal to the the provided argument.\n\nSee also \\code{\\link{Climb}} and \\code{\\link{Navigate}}\n\nClimb(node, ...)\n}\n\n\\subsection{Returns}{\nthe \\code{Node} having path \\code{...}, or \\code{NULL} if such a path does not exist\n}\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{data(acme)\n\n#the following are all equivalent\nClimb(acme, 'IT', 'Outsource')\nClimb(acme, name = 'IT', name = 'Outsource')\nClimb(acme, 'IT')$Climb('Outsource')\nNavigate(acme, path = \"IT/Outsource\")\n\nClimb(acme, name = 'IT')\n\nClimb(acme, position = c(2, 1))\n#or, equivalent:\nClimb(acme, position = 2, position = 1)\nClimb(acme, name = \"IT\", cost = 250000)\n\ntree <- CreateRegularTree(5, 2)\ntree$Climb(c(\"1\", \"1\"), position = c(2, 2))$path\n\n\n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-Navigate\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-Navigate}{}}}\n\\subsection{Method \\code{Navigate()}}{\nNavigate to another node by relative path.\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$Navigate(path)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{path}}{A string or a character vector describing the path to navigate}\n\n\\item{\\code{node}}{The starting \\code{\\link{Node}} to navigate}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Details}{\nThe \\code{path} is always relative to the \\code{Node}. Navigation\nto the parent is defined by \\code{..}, whereas navigation to a child\nis defined via the child's name.\nIf path is provided as a string, then the navigation steps are separated\nby '/'.\n\nSee also \\code{\\link{Navigate}} and \\code{\\link{Climb}}\n}\n\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{data(acme)\nNavigate(acme$Research, \"../IT/Outsource\")\nNavigate(acme$Research, c(\"..\", \"IT\", \"Outsource\"))\n\n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-Get\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-Get}{}}}\n\\subsection{Method \\code{Get()}}{\nTraverse a Tree and Collect Values\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$Get(\n  attribute,\n  ...,\n  traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"),\n  pruneFun = NULL,\n  filterFun = NULL,\n  format = FALSE,\n  inheritFromAncestors = FALSE,\n  simplify = c(TRUE, FALSE, \"array\", \"regular\")\n)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{attribute}}{determines what is collected. The \\code{attribute} can be\n\\itemize{\n  \\item a.) the name of a \\bold{field} or a \\bold{property/active} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"p\")} or \\code{acme$Get(\"position\")}\n  \\item b.) the name of a \\bold{method} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"levelZeroBased\")}, where e.g. \\code{acme$levelZeroBased <- function() acme$level - 1}\n  \\item c.) a \\bold{function}, whose first argument must be a \\code{Node} e.g. \\code{acme$Get(function(node) node$cost * node$p)}\n }}\n\n\\item{\\code{...}}{in case the \\code{attribute} is a function or a method, the ellipsis is passed to it as additional arguments.}\n\n\\item{\\code{traversal}}{defines the traversal order to be used. This can be\n\\describe{\n  \\item{pre-order}{Go to first child, then to its first child, etc.}\n  \\item{post-order}{Go to the first branch's leaf, then to its siblings, and work your way back to the root}\n  \\item{in-order}{Go to the first branch's leaf, then to its parent, and only then to the leaf's sibling}\n  \\item{level}{Collect root, then level 2, then level 3, etc.}\n  \\item{ancestor}{Take a node, then the node's parent, then that node's parent in turn, etc. This ignores the \\code{pruneFun} }\n  \\item{function}{You can also provide a function, whose sole parameter is a \\code{\\link{Node}} object. The function is expected to return the node's next node, a list of the node's next nodes, or NULL.}\n}\nRead the data.tree vignette for a detailed explanation of these traversal orders.}\n\n\\item{\\code{pruneFun}}{allows providing a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \nIf the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.}\n\n\\item{\\code{filterFun}}{allows providing a a filter, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}.\nNote that if filter returns \\code{FALSE}, then the node will be excluded from the result (but not the entire subtree).}\n\n\\item{\\code{format}}{if \\code{FALSE} (the default), no formatting is being used. If \\code{TRUE}, then the first formatter (if any) found along the ancestor path is being used for formatting \n(see \\code{\\link{SetFormat}}). If \\code{format} is a function, then the collected value is passed to that function, and the result is returned.}\n\n\\item{\\code{inheritFromAncestors}}{if \\code{TRUE}, then the path above a \\code{Node} is searched to get the \\code{attribute} in case it is NULL.}\n\n\\item{\\code{simplify}}{same as \\code{\\link{sapply}}, i.e. TRUE, FALSE or \"array\". Additionally, you can specify \"regular\" if\neach returned value is of length > 1, and equally named. See below for an example.}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Details}{\nThe \\code{Get} method is one of the most important ones of the \\code{data.tree} package. It lets you traverse a tree\nand collect values along the way. Alternatively, you can call a method or a function on each \\code{\\link{Node}}.\n\nSee also \\code{\\link{Get}}, \\code{\\link{Node}}, \\code{\\link{Set}}, \\code{\\link{Do}}, \\code{\\link{Traverse}}\n}\n\n\\subsection{Returns}{\na vector containing the \\code{atrributes} collected during traversal, in traversal order. \\code{NULL} is converted\nto NA, such that \\code{length(Node$Get) == Node$totalCount}\n}\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{data(acme)\nacme$Get(\"level\")\nacme$Get(\"totalCount\")\n \n\nacme$Get(function(node) node$cost * node$p,\n         filterFun = isLeaf)\n\n#This is equivalent:\nnodes <- Traverse(acme, filterFun = isLeaf)\nGet(nodes, function(node) node$cost * node$p)\n\n   \n#simplify = \"regular\" will preserve names\nacme$Get(function(x) c(position = x$position, level = x$level), simplify = \"regular\")\n \n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-Do\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-Do}{}}}\n\\subsection{Method \\code{Do()}}{\nExecutes a function on a set of nodes\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$Do(\n  fun,\n  ...,\n  traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"),\n  pruneFun = NULL,\n  filterFun = NULL\n)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{fun}}{the function to execute. The function is expected to be either a Method, or to take a \nNode as its first argument}\n\n\\item{\\code{...}}{A name-value mapping of node attributes}\n\n\\item{\\code{traversal}}{defines the traversal order to be used. This can be\n\\describe{\n  \\item{pre-order}{Go to first child, then to its first child, etc.}\n  \\item{post-order}{Go to the first branch's leaf, then to its siblings, and work your way back to the root}\n  \\item{in-order}{Go to the first branch's leaf, then to its parent, and only then to the leaf's sibling}\n  \\item{level}{Collect root, then level 2, then level 3, etc.}\n  \\item{ancestor}{Take a node, then the node's parent, then that node's parent in turn, etc. This ignores the \\code{pruneFun} }\n  \\item{function}{You can also provide a function, whose sole parameter is a \\code{\\link{Node}} object. The function is expected to return the node's next node, a list of the node's next nodes, or NULL.}\n}\nRead the data.tree vignette for a detailed explanation of these traversal orders.}\n\n\\item{\\code{pruneFun}}{allows providing a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \nIf the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.}\n\n\\item{\\code{filterFun}}{allows providing a a filter, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}.\nNote that if filter returns \\code{FALSE}, then the node will be excluded from the result (but not the entire subtree).}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Details}{\nSee also \\code{\\link{Node}}, \\code{\\link{Get}}, \\code{\\link{Set}}, \\code{\\link{Traverse}}\n}\n\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{data(acme)\nacme$Do(function(node) node$expectedCost <- node$p * node$cost)\nprint(acme, \"expectedCost\")\n\n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-Set\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-Set}{}}}\n\\subsection{Method \\code{Set()}}{\nTraverse a Tree and Assign Values\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$Set(\n  ...,\n  traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"),\n  pruneFun = NULL,\n  filterFun = NULL\n)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{...}}{each argument can be a vector of values to be assigned. Recycled.}\n\n\\item{\\code{traversal}}{defines the traversal order to be used. This can be\n\\describe{\n  \\item{pre-order}{Go to first child, then to its first child, etc.}\n  \\item{post-order}{Go to the first branch's leaf, then to its siblings, and work your way back to the root}\n  \\item{in-order}{Go to the first branch's leaf, then to its parent, and only then to the leaf's sibling}\n  \\item{level}{Collect root, then level 2, then level 3, etc.}\n  \\item{ancestor}{Take a node, then the node's parent, then that node's parent in turn, etc. This ignores the \\code{pruneFun} }\n  \\item{function}{You can also provide a function, whose sole parameter is a \\code{\\link{Node}} object. The function is expected to return the node's next node, a list of the node's next nodes, or NULL.}\n}\nRead the data.tree vignette for a detailed explanation of these traversal orders.}\n\n\\item{\\code{pruneFun}}{allows providing a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \nIf the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.}\n\n\\item{\\code{filterFun}}{allows providing a a filter, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}.\nNote that if filter returns \\code{FALSE}, then the node will be excluded from the result (but not the entire subtree).}\n}\n\\if{html}{\\out{</div>}}\n}\n\\subsection{Details}{\nThe method takes one or more vectors as an argument. It traverses the tree, whereby the values are picked\nfrom the vector. Also available as OO-style method on \\code{\\link{Node}}.\n\nSee also \\code{\\link{Node}}, \\code{\\link{Get}}, \\code{\\link{Do}}, \\code{\\link{Traverse}}\n}\n\n\\subsection{Returns}{\ninvisibly returns the nodes (useful for chaining)\n}\n\\subsection{Examples}{\n\\if{html}{\\out{<div class=\"r example copy\">}}\n\\preformatted{data(acme)\nacme$Set(departmentId = 1:acme$totalCount, openingHours = NULL, traversal = \"post-order\")\nacme$Set(head = c(\"Jack Brown\", \n                  \"Mona Moneyhead\", \n                  \"Dr. Frank N. Stein\", \n                  \"Eric Nerdahl\"\n                  ),\n         filterFun = function(x) !x$isLeaf\n        )\nprint(acme, \"departmentId\", \"head\")\n \n}\n\\if{html}{\\out{</div>}}\n\n}\n\n}\n\\if{html}{\\out{<hr>}}\n\\if{html}{\\out{<a id=\"method-Node-clone\"></a>}}\n\\if{latex}{\\out{\\hypertarget{method-Node-clone}{}}}\n\\subsection{Method \\code{clone()}}{\nThe objects of this class are cloneable with this method.\n\\subsection{Usage}{\n\\if{html}{\\out{<div class=\"r\">}}\\preformatted{Node$clone(deep = FALSE)}\\if{html}{\\out{</div>}}\n}\n\n\\subsection{Arguments}{\n\\if{html}{\\out{<div class=\"arguments\">}}\n\\describe{\n\\item{\\code{deep}}{Whether to make a deep clone.}\n}\n\\if{html}{\\out{</div>}}\n}\n}\n}\n"
  },
  {
    "path": "man/Prune.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods_sideeffect.R\n\\name{Prune}\n\\alias{Prune}\n\\title{Prunes a tree.}\n\\usage{\nPrune(node, pruneFun)\n}\n\\arguments{\n\\item{node}{The root of the sub-tree to be pruned}\n\n\\item{pruneFun}{allows providing a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \nIf the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.}\n}\n\\value{\nthe number of nodes removed\n}\n\\description{\nPruning refers to removing entire subtrees. This function has side-effects, it modifies your data.tree structure!\n}\n\\examples{\ndata(acme)\nacme$Do(function(x) x$cost <- Aggregate(x, \"cost\", sum))\nPrune(acme, function(x) x$cost > 700000)\nprint(acme, \"cost\")\n\n}\n\\seealso{\n\\code{\\link{Node}}\n}\n"
  },
  {
    "path": "man/Revert.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods_sideeffect.R\n\\name{Revert}\n\\alias{Revert}\n\\title{Reverts the sort order of a \\code{Node}'s children.}\n\\usage{\nRevert(node, recursive = TRUE)\n}\n\\arguments{\n\\item{node}{the Node whose childrens' sort order is to be reverted}\n\n\\item{recursive}{If \\code{TRUE}, then revert is called recursively on\nall children.}\n}\n\\value{\nreturns the Node invisibly (for chaining)\n}\n\\description{\nReverts the sort order of a \\code{Node}'s children.\n}\n\\seealso{\n\\code{\\link{Node}}\n\n\\code{\\link{Sort}}\n}\n"
  },
  {
    "path": "man/Set.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods_traversal.R\n\\name{Set}\n\\alias{Set}\n\\title{Traverse a Tree and Assign Values}\n\\usage{\n#OO-style:\n# node$Set(..., \n#          traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"),  \n#          pruneFun = NULL, \n#          filterFun = NULL)\n#traditional:\nSet(nodes, ...)\n}\n\\arguments{\n\\item{nodes}{The nodes on which to perform the Get (typically obtained via \\code{\\link{Traverse}})}\n\n\\item{...}{each argument can be a vector of values to be assigned. Recycled.}\n}\n\\value{\ninvisibly returns the nodes (useful for chaining)\n}\n\\description{\nThe method takes one or more vectors as an argument. It traverses the tree, whereby the values are picked\nfrom the vector. Also available as OO-style method on \\code{\\link{Node}}.\n}\n\\examples{\ndata(acme)\nacme$Set(departmentId = 1:acme$totalCount, openingHours = NULL, traversal = \"post-order\")\nacme$Set(head = c(\"Jack Brown\", \n                  \"Mona Moneyhead\", \n                  \"Dr. Frank N. Stein\", \n                  \"Eric Nerdahl\"\n                  ),\n         filterFun = function(x) !x$isLeaf\n        )\nprint(acme, \"departmentId\", \"head\")\n \n}\n\\seealso{\n\\code{\\link{Node}}\n\n\\code{\\link{Get}}\n\n\\code{\\link{Do}}\n\n\\code{\\link{Traverse}}\n}\n"
  },
  {
    "path": "man/SetFormat.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods.R\n\\name{SetFormat}\n\\alias{SetFormat}\n\\title{Set a formatter function on a specific node}\n\\usage{\nSetFormat(node, name, formatFun)\n}\n\\arguments{\n\\item{node}{The node on which to set the formatter}\n\n\\item{name}{The attribute name for which to set the formatter}\n\n\\item{formatFun}{The formatter, i.e. a function taking a value as an input, and formatting\nreturning the formatted value}\n}\n\\description{\nFormatter functions set on a Node act as a default formatter when printing and using\nthe \\code{\\link{Get}} method. The formatter is inherited, meaning that whenever\n\\code{Get} fetches an attribute from a \\code{Node}, it checks on the \\code{Node} or\non any of its ancestors whether a formatter is set.\n}\n\\examples{\ndata(acme)\nacme$Set(id = 1:(acme$totalCount))\nSetFormat(acme, \"id\", function(x) FormatPercent(x, digits = 0))\nSetFormat(Climb(acme, \"IT\"), \"id\", FormatFixedDecimal)\nprint(acme, \"id\")\n# Calling Get with an explicit formatter will overwrite the default set on the Node:\nprint(acme, id = acme$Get(\"id\", format = function(x) paste0(\"id:\", x)))\n\n# Or, to avoid formatters, even though you set them on a Node:\nprint(acme, id = acme$Get(\"id\", format = identity))\n\n\n}\n\\seealso{\nGet\n\nprint.Node\n}\n"
  },
  {
    "path": "man/Sort.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods_sideeffect.R\n\\name{Sort}\n\\alias{Sort}\n\\title{Sort children of a \\code{Node} or an entire \\code{data.tree} structure}\n\\usage{\nSort(node, attribute, ..., decreasing = FALSE, recursive = TRUE)\n}\n\\arguments{\n\\item{node}{The node whose children are to be sorted}\n\n\\item{attribute}{determines what is collected. The \\code{attribute} can be\n\\itemize{\n  \\item a.) the name of a \\bold{field} or a \\bold{property/active} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"p\")} or \\code{acme$Get(\"position\")}\n  \\item b.) the name of a \\bold{method} of each \\code{Node} in the tree, e.g. \\code{acme$Get(\"levelZeroBased\")}, where e.g. \\code{acme$levelZeroBased <- function() acme$level - 1}\n  \\item c.) a \\bold{function}, whose first argument must be a \\code{Node} e.g. \\code{acme$Get(function(node) node$cost * node$p)}\n }}\n\n\\item{...}{any parameters to be passed on the the attribute (in case it's a method or a \nfunction)}\n\n\\item{decreasing}{sort order}\n\n\\item{recursive}{if \\code{TRUE}, Sort will be called recursively on the \\code{Node}'s children. \nThis allows sorting an entire tree.}\n}\n\\value{\nReturns the node on which Sort is called, invisibly. This can be useful to chain Node methods.\n}\n\\description{\nYou can sort with respect to any argument of the tree. But note that sorting has\nside-effects, meaning that you modify the underlying, original data.tree object structure.\n}\n\\examples{\ndata(acme)\nacme$Do(function(x) x$totalCost <- Aggregate(x, \"cost\", sum), traversal = \"post-order\")\nSort(acme, \"totalCost\", decreasing = FALSE)\nprint(acme, \"totalCost\")\n\n}\n\\seealso{\n\\code{\\link{Node}}\n\n\\code{\\link{Revert}}\n}\n"
  },
  {
    "path": "man/ToDiagrammeRGraph.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_plot.R, R/util.R\n\\name{plot.Node}\n\\alias{plot.Node}\n\\alias{ToDiagrammeRGraph}\n\\alias{SetNodeStyle}\n\\alias{SetEdgeStyle}\n\\alias{SetGraphStyle}\n\\alias{GetDefaultTooltip}\n\\title{Plot a graph, or get a graphviz dot representation of the tree}\n\\usage{\n\\method{plot}{Node}(\n  x,\n  ...,\n  direction = c(\"climb\", \"descend\"),\n  pruneFun = NULL,\n  output = \"graph\"\n)\n\nToDiagrammeRGraph(root, direction = c(\"climb\", \"descend\"), pruneFun = NULL)\n\nSetNodeStyle(node, inherit = TRUE, keepExisting = FALSE, ...)\n\nSetEdgeStyle(node, inherit = TRUE, keepExisting = FALSE, ...)\n\nSetGraphStyle(root, keepExisting = FALSE, ...)\n\nGetDefaultTooltip(node)\n}\n\\arguments{\n\\item{x}{The root node of the data.tree structure to plot}\n\n\\item{...}{For the SetStyle methods, this can be any stlyeName / value pair. See \nhttp://graphviz.org/Documentation.php for details. For the plot.Node generic method, this is not used.}\n\n\\item{direction}{when converting to a network, should the edges point from root to children (\"climb\") or from child to parent (\"descend\")?}\n\n\\item{pruneFun}{allows providing a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \nIf the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.}\n\n\\item{output}{A string specifying the output type; \\code{graph} (the default)\nrenders the graph using the \\code{\\link[DiagrammeR:grViz]{grViz()}} function and \\code{visNetwork} renders the\ngraph using the \\code{\\link[DiagrammeR:visnetwork]{visnetwork()}} function.}\n\n\\item{root}{The root \\code{\\link{Node}} of the data.tree structure to visualize.}\n\n\\item{node}{The \\code{\\link{Node}} of the data.tree structure on which you would like to set style attributes.}\n\n\\item{inherit}{If TRUE, then children will inherit this node's style. \nOtherwise they inherit from this node's parent. Note that the inherit \nalways applies to the node, i.e. all style attributes of a node and not \nto a single style attribute.}\n\n\\item{keepExisting}{If TRUE, then style attributes are added to possibly\nexisting style attributes on the node.}\n}\n\\description{\nUse these methods to style your graph, and to plot it. The functionality is built around the\nDiagrammeR package, so for anything that goes beyond simple plotting, it is recommended to read its \ndocumentation at http://rich-iannone.github.io/DiagrammeR/docs.html. Note that DiagrammeR is only suggested\nby data.tree, so `plot` only works if you have installed it on your system.\n}\n\\details{\nUse \\code{SetNodeStyle} and \\code{SetEdgeStyle} to define the style of your plot. Use \\code{plot} to display a \ngraphical representation of your tree.\n\nThe most common styles that can be set on the nodes are:\n\\itemize{\n  \\item{\\code{color}}\n  \\item{\\code{fillcolor}}\n  \\item{\\code{fixedsize} true or false}\n  \\item{\\code{fontcolor}}\n  \\item{\\code{fontname}}\n  \\item{\\code{fontsize}}\n  \\item{\\code{height}}\n  \\item{\\code{penwidth}}\n  \\item{\\code{shape} box, ellipse, polygon, circle, box, etc.}\n  \\item{\\code{style}}\n  \\item{\\code{tooltip}}\n  \\item{\\code{width}}\n }\nThe most common styles that can be set on the edges are:\n\\itemize{\n  \\item{\\code{arrowhead} e.g. normal, dot, vee}\n  \\item{\\code{arrowsize}}\n  \\item{\\code{arrowtail}}\n  \\item{\\code{color}}\n  \\item{\\code{dir} forward, back, both, none}\n  \\item{\\code{fontcolor}}\n  \\item{\\code{fontname}}\n  \\item{\\code{fontsize}}\n  \\item{\\code{headport}}\n  \\item{\\code{label}}\n  \\item{\\code{minlen}}\n  \\item{\\code{penwidth}}\n  \\item{\\code{tailport}}\n  \\item{\\code{tooltip}}\n }\nA good source to understand the attributes is http://graphviz.org/Documentation.php. Another good source\nis the DiagrammeR package documentation, or more specifically: http://rich-iannone.github.io/DiagrammeR/docs.html\n\nIn addition to the standard GraphViz functionality, the \\code{data.tree} plotting infrastructure takes advantage\nof the fact that data.tree structure are always hierarchic. Thus, style attributes are inherited from parents\nto children on an individual basis. For example, you can set the fontcolor to red on a parent, and then all children\nwill also have red font, except if you specifically disallow inheritance. Labels and tooltips are never inherited.\n\nAnother feature concerns functions: Instead of setting a fixed value (e.g. \\code{SetNodeStyle(acme, label = \"Acme. Inc\"}), \nyou can set a function (e.g. \\code{SetNodeStyle(acme, label = function(x) x$name)}). The function must take a \\code{\\link{Node}}\nas its single argument. Together with inheritance, this becomes a very powerful tool.\n  \nThe \\code{GetDefaultTooltip} method is a utility method that can be used to print all attributes of a \\code{\\link{Node}}.\n\nThere are some more examples in the 'applications' vignette, see \\code{vignette('applications', package = \"data.tree\")}\n}\n\\examples{\ndata(acme)\nSetGraphStyle(acme, rankdir = \"TB\")\nSetEdgeStyle(acme, arrowhead = \"vee\", color = \"blue\", penwidth = 2)\n#per default, Node style attributes will be inherited:\nSetNodeStyle(acme, style = \"filled,rounded\", shape = \"box\", fillcolor = \"GreenYellow\", \n             fontname = \"helvetica\", tooltip = GetDefaultTooltip)\nSetNodeStyle(acme$IT, fillcolor = \"LightBlue\", penwidth = \"5px\")\n#inheritance can be avoided:\nSetNodeStyle(acme$Accounting, inherit = FALSE, fillcolor = \"Thistle\", \n             fontcolor = \"Firebrick\", tooltip = \"This is the accounting department\")\nSetEdgeStyle(acme$Research$`New Labs`, \n             color = \"red\", \n             label = \"Focus!\", \n             penwidth = 3, \n             fontcolor = \"red\")\n#use Do to set style on specific nodes:\nDo(acme$leaves, function(node) SetNodeStyle(node, shape = \"egg\"))\nplot(acme)\n\n#print p as label, where available:\nSetNodeStyle(acme, label = function(node) node$p)\nplot(acme)\n\n}\n"
  },
  {
    "path": "man/ToNewick.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion.R\n\\name{ToNewick}\n\\alias{ToNewick}\n\\title{Write a \\code{data.tree} structure to Newick notation}\n\\usage{\nToNewick(node, heightAttribute = DefaultPlotHeight, ...)\n}\n\\arguments{\n\\item{node}{The root \\code{Node} of a tree or sub-tree to be converted}\n\n\\item{heightAttribute}{The attribute (field name, method, or function) storing or calculating the height for each \\code{Node}}\n\n\\item{...}{parameters that will be passed on the the heightAttributeName, in case it is a function}\n}\n\\description{\nTo read from Newick, you can use the \\code{ape} package, and convert the resulting \\code{phylo}\nobject to a \\code{data.tree} structure.\n}\n\\examples{\ndata(acme)\nToNewick(acme)\nToNewick(acme, heightAttribute = NULL)\nToNewick(acme, heightAttribute = function(x) DefaultPlotHeight(x, 200))\nToNewick(acme, rootHeight = 200)\n\n}\n\\seealso{\nOther Conversions from Node: \n\\code{\\link{as.dendrogram.Node}()}\n}\n\\concept{Conversions from Node}\n\\keyword{Newick}\n"
  },
  {
    "path": "man/Traverse.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods_traversal.R\n\\name{Traverse}\n\\alias{Traverse}\n\\title{Traverse a tree or a sub-tree}\n\\usage{\nTraverse(\n  node,\n  traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"),\n  pruneFun = NULL,\n  filterFun = NULL\n)\n}\n\\arguments{\n\\item{node}{the root of a tree or a sub-tree that should be traversed}\n\n\\item{traversal}{any of 'pre-order' (the default), 'post-order', 'in-order', 'level', 'ancestor', or a custom function (see details)}\n\n\\item{pruneFun}{allows providing a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \nIf the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.}\n\n\\item{filterFun}{allows providing a a filter, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}.\nNote that if filter returns \\code{FALSE}, then the node will be excluded from the result (but not the entire subtree).}\n}\n\\value{\na list of \\code{Node}s\n}\n\\description{\nTraverse takes the root of a tree or a sub-tree, and \"walks\" the tree in a specific order. It returns a list of\n\\code{\\link{Node}} objects, filtered and pruned by \\code{filterFun} and \\code{pruneFun}.\n}\n\\details{\nThe traversal order is as follows. (Note that these descriptions are not precise and complete. They are meant\nfor quick reference only. See the data.tree vignette for a more detailed description). \n\\describe{\n   \\item{pre-order}{Go to first child, then to its first child, etc.}\n   \\item{post-order}{Go to the first branch's leaf, then to its siblings, and work your way back to the root}\n   \\item{in-order}{Go to the first branch's leaf, then to its parent, and only then to the leaf's sibling}\n   \\item{level}{Collect root, then level 2, then level 3, etc.}\n   \\item{ancestor}{Take a node, then the node's parent, then that node's parent in turn, etc. This ignores the \\code{pruneFun} }\n   \\item{function}{You can also provide a function, whose sole parameter is a \\code{\\link{Node}} object. The\n   function is expected to return the node's next node, a list of the node's next nodes, or NULL.}\n}\n}\n\\seealso{\n\\code{\\link{Node}}\n\n\\code{\\link{Get}}\n\n\\code{\\link{Set}}\n\n\\code{\\link{Do}}\n}\n"
  },
  {
    "path": "man/acme.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/data_doc.R\n\\docType{data}\n\\name{acme}\n\\alias{acme}\n\\title{Sample Data: A Simple Company with Departments}\n\\format{\nA data.tree root Node\n}\n\\usage{\ndata(acme)\n}\n\\description{\nacme's tree representation is accessed through its root, acme.\n}\n\\details{\n\\itemize{\n  \\item cost, only available for leaf nodes. Cost of the project.\n  \\item p probability that a project will be undertaken.\n}\n}\n\\keyword{datasets}\n"
  },
  {
    "path": "man/as.Node.BinaryTree.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_party.R\n\\name{as.Node.BinaryTree}\n\\alias{as.Node.BinaryTree}\n\\title{Convert a a \\code{SplitNode} from the party package to a \\code{data.tree} structure.}\n\\usage{\n\\method{as.Node}{BinaryTree}(x, ...)\n}\n\\arguments{\n\\item{x}{The BinaryTree}\n\n\\item{...}{additional arguments (unused)}\n}\n\\description{\nConvert a a \\code{SplitNode} from the party package to a \\code{data.tree} structure.\n}\n\\examples{\nlibrary(party)\nairq <- subset(airquality, !is.na(Ozone))\nairct <- ctree(Ozone ~ ., data = airq, \n               controls = ctree_control(maxsurrogate = 3))\n               \ntree <- as.Node(airct)\ntree\n\nprint(tree, \n      \"label\", \n      criterion = function(x) round(x$criterion$maxcriterion, 3),\n      statistic = function(x) round(max(x$criterion$statistic), 3)\n      )\n\nFindNode(tree, 6)$path\n\n\n}\n"
  },
  {
    "path": "man/as.Node.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion.R\n\\name{as.Node}\n\\alias{as.Node}\n\\title{Convert an object to a \\code{data.tree} data structure}\n\\usage{\nas.Node(x, ...)\n}\n\\arguments{\n\\item{x}{The object to be converted}\n\n\\item{...}{Additional arguments}\n}\n\\description{\nConvert an object to a \\code{data.tree} data structure\n}\n\\seealso{\nOther as.Node: \n\\code{\\link{as.Node.data.frame}()},\n\\code{\\link{as.Node.dendrogram}()},\n\\code{\\link{as.Node.list}()},\n\\code{\\link{as.Node.phylo}()},\n\\code{\\link{as.Node.rpart}()}\n}\n\\concept{as.Node}\n"
  },
  {
    "path": "man/as.Node.data.frame.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_dataframe.R\n\\name{as.Node.data.frame}\n\\alias{as.Node.data.frame}\n\\alias{FromDataFrameTable}\n\\alias{FromDataFrameNetwork}\n\\title{Convert a \\code{data.frame} to a \\code{data.tree} structure}\n\\usage{\n\\method{as.Node}{data.frame}(\n  x,\n  ...,\n  mode = c(\"table\", \"network\"),\n  pathName = \"pathString\",\n  pathDelimiter = \"/\",\n  colLevels = NULL,\n  na.rm = TRUE\n)\n\nFromDataFrameTable(\n  table,\n  pathName = \"pathString\",\n  pathDelimiter = \"/\",\n  colLevels = NULL,\n  na.rm = TRUE,\n  check = c(\"check\", \"no-warn\", \"no-check\")\n)\n\nFromDataFrameNetwork(network, check = c(\"check\", \"no-warn\", \"no-check\"))\n}\n\\arguments{\n\\item{x}{The data.frame in the required format.}\n\n\\item{...}{Any other argument implementations of this might need}\n\n\\item{mode}{Either \"table\" (if x is a data.frame in tree or table format) or \"network\"}\n\n\\item{pathName}{The name of the column in x containing the path of the row}\n\n\\item{pathDelimiter}{The delimiter used to separate nodes in \\code{pathName}}\n\n\\item{colLevels}{Nested list of column names, determining on what node levels the attributes are written to.}\n\n\\item{na.rm}{If \\code{TRUE}, then NA's are treated as NULL and values will not be set on nodes}\n\n\\item{table}{a \\code{data.frame} in table or tree format, i.e. having a row for each leaf (and optionally\nfor additional nodes). There should be a column called \\code{pathName}, separated by \\code{pathDelimiter},\ndescribing the path of each row.}\n\n\\item{check}{Either\n\\itemize{\n \\item{\\code{\"check\"}: if the name conformance should be checked and warnings should be printed in case of non-conformance (the default)}\n \\item{\\code{\"no-warn\"}: if the name conformance should be checked, but no warnings should be printed in case of non-conformance (if you expect non-conformance)}\n \\item{\\code{\"no-check\" or FALSE}: if the name conformance should not be checked; use this if performance is critical. However, in case of non-conformance, expect cryptic follow-up errors}\n}}\n\n\\item{network}{A \\code{data.frame} in network format, i.e.\nit must adhere to the following requirements:\n\\itemize{\n \\item{It must contain as many rows as there are nodes (excluding the root, there is no row for the root)}\n \\item{Its first and second columns contain the network relationships. This can be either climbing (from parent to children) or descending (from child to parent)}\n \\item{Its subsequent columns contain the attributes to be set on the nodes}\n \\item{It must contain a single root}\n \\item{There are no cycles in the network}\n}}\n}\n\\value{\nThe root \\code{Node} of the \\code{data.tree} structure\n}\n\\description{\nConvert a \\code{data.frame} to a \\code{data.tree} structure\n}\n\\examples{\ndata(acme)\n\n#Tree\nx <- ToDataFrameTree(acme, \"pathString\", \"p\", \"cost\")\nx\nxN <- as.Node(x)\nprint(xN, \"p\", \"cost\")\n\n#Table\nx <- ToDataFrameTable(acme, \"pathString\", \"p\", \"cost\")\nx\nxN <- FromDataFrameTable(x)\nprint(xN, \"p\", \"cost\")\n\n#More complex Table structure, using colLevels\nacme$Set(floor = c(1, 2, 3),  filterFun = function(x) x$level == 2)\nx <- ToDataFrameTable(acme, \"pathString\", \"floor\", \"p\", \"cost\")\nx\nxN <- FromDataFrameTable(x, colLevels = list(NULL, \"floor\", c(\"p\", \"cost\")), na.rm = TRUE)\nprint(xN, \"floor\", \"p\", \"cost\")\n\n#Network\nx <- ToDataFrameNetwork(acme, \"p\", \"cost\", direction = \"climb\")\nx\nxN <- FromDataFrameNetwork(x)\nprint(xN, \"p\", \"cost\")\n\n}\n\\seealso{\n\\code{\\link{as.data.frame.Node}}\n\nOther as.Node: \n\\code{\\link{as.Node.dendrogram}()},\n\\code{\\link{as.Node.list}()},\n\\code{\\link{as.Node.phylo}()},\n\\code{\\link{as.Node.rpart}()},\n\\code{\\link{as.Node}()}\n}\n\\concept{as.Node}\n"
  },
  {
    "path": "man/as.Node.dendrogram.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_dendrogram.R\n\\name{as.Node.dendrogram}\n\\alias{as.Node.dendrogram}\n\\title{Convert a \\code{\\link{dendrogram}} to a data.tree \\code{Node}}\n\\usage{\n\\method{as.Node}{dendrogram}(\n  x,\n  name = \"Root\",\n  heightName = \"plotHeight\",\n  check = c(\"check\", \"no-warn\", \"no-check\"),\n  ...\n)\n}\n\\arguments{\n\\item{x}{The dendrogram}\n\n\\item{name}{The name of the root Node}\n\n\\item{heightName}{The name under which the dendrogram's height is stored}\n\n\\item{check}{Either\n\\itemize{\n \\item{\\code{\"check\"}: if the name conformance should be checked and warnings should be printed in case of non-conformance (the default)}\n \\item{\\code{\"no-warn\"}: if the name conformance should be checked, but no warnings should be printed in case of non-conformance (if you expect non-conformance)}\n \\item{\\code{\"no-check\" or FALSE}: if the name conformance should not be checked; use this if performance is critical. However, in case of non-conformance, expect cryptic follow-up errors}\n}}\n\n\\item{...}{Additional parameters}\n}\n\\value{\nThe root \\code{Node} of a \\code{data.tree}\n}\n\\description{\nConvert a \\code{\\link{dendrogram}} to a data.tree \\code{Node}\n}\n\\examples{\nhc <- hclust(dist(USArrests), \"ave\")\ndend1 <- as.dendrogram(hc)\ntree1 <- as.Node(dend1)\ntree1$attributesAll\ntree1$totalCount\ntree1$leafCount\ntree1$height\n  \n}\n\\seealso{\nOther as.Node: \n\\code{\\link{as.Node.data.frame}()},\n\\code{\\link{as.Node.list}()},\n\\code{\\link{as.Node.phylo}()},\n\\code{\\link{as.Node.rpart}()},\n\\code{\\link{as.Node}()}\n}\n\\concept{as.Node}\n"
  },
  {
    "path": "man/as.Node.list.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_list.R\n\\name{as.Node.list}\n\\alias{as.Node.list}\n\\alias{FromListExplicit}\n\\alias{FromListSimple}\n\\title{Convert a nested \\code{list} structure to a \\code{data.tree} structure}\n\\usage{\n\\method{as.Node}{list}(\n  x,\n  mode = c(\"simple\", \"explicit\"),\n  nameName = \"name\",\n  childrenName = \"children\",\n  nodeName = NULL,\n  interpretNullAsList = FALSE,\n  check = c(\"check\", \"no-warn\", \"no-check\"),\n  ...\n)\n\nFromListExplicit(\n  explicitList,\n  nameName = \"name\",\n  childrenName = \"children\",\n  nodeName = NULL,\n  check = c(\"check\", \"no-warn\", \"no-check\")\n)\n\nFromListSimple(\n  simpleList,\n  nameName = \"name\",\n  nodeName = NULL,\n  interpretNullAsList = FALSE,\n  check = c(\"check\", \"no-warn\", \"no-check\")\n)\n}\n\\arguments{\n\\item{x}{The \\code{list} to be converted.}\n\n\\item{mode}{How the list is structured. \"simple\" (the default) will interpret any list to be a child. \"explicit\" \nassumes that children are in a nested list called \\code{childrenName}}\n\n\\item{nameName}{The name of the element in the list that should be used as the name, can be NULL if mode = explicit and\nthe children lists are named, or if an automatic name (running number) should be assigned}\n\n\\item{childrenName}{The name of the element that contains the child list (applies to mode 'explicit' only).}\n\n\\item{nodeName}{A name suggestion for x, if the name cannot be deferred otherwise. This is for example the case for\nthe root with mode explicit and named lists.}\n\n\\item{interpretNullAsList}{If \\code{TRUE}, then \\code{NULL}-valued lists are interpreted as child nodes. Else, they are interpreted as attributes.\nThis has only an effect if \\code{mode} is \"simple\".}\n\n\\item{check}{Either\n\\itemize{\n \\item{\\code{\"check\"}: if the name conformance should be checked and warnings should be printed in case of non-conformance (the default)}\n \\item{\\code{\"no-warn\"}: if the name conformance should be checked, but no warnings should be printed in case of non-conformance (if you expect non-conformance)}\n \\item{\\code{\"no-check\" or FALSE}: if the name conformance should not be checked; use this if performance is critical. However, in case of non-conformance, expect cryptic follow-up errors}\n}}\n\n\\item{...}{Any other argument to be passed to generic sub implementations}\n\n\\item{explicitList}{A \\code{list} in which children are in a separate nested list called \\code{childrenName}.}\n\n\\item{simpleList}{A \\code{list} in which children are stored as nested list alongside other attributes. Any list is\ninterpreted as a child \\code{Node}}\n}\n\\description{\nConvert a nested \\code{list} structure to a \\code{data.tree} structure\n}\n\\examples{\nkingJosephs <- list(name = \"Joseph I\",\n                    spouse = \"Mary\",\n                    born = \"1818-02-23\",\n                    died = \"1839-08-29\",\n                    children = list(\n                                    list(name = \"Joseph II\",\n                                         spouse = \"Kathryn\",\n                                         born = \"1839-03-28\",\n                                         died = \"1865-12-19\"),\n                                    list(name = \"Helen\",\n                                         born = \"1840-17-08\",\n                                         died = \"1845-01-01\")\n                                    )\n                   )\nFromListExplicit(kingJosephs)\n\nkingJosephs <- list(head = \"Joseph I\",\n                    spouse = \"Mary\",\n                    born = \"1818-02-23\",\n                    died = \"1839-08-29\",\n                    list(head = \"Joseph II\",\n                         spouse = \"Kathryn\",\n                         born = \"1839-03-28\",\n                         died = \"1865-12-19\"),\n                    list(head = \"Helen\",\n                         born = \"1840-17-08\",\n                         died = \"1845-01-01\")       \n                   )\nFromListSimple(kingJosephs, nameName = \"head\")\n\nkingJosephs <- list(spouse = \"Mary\",\n                    born = \"1818-02-23\",\n                    died = \"1839-08-29\",\n                    `Joseph II` = list(spouse = \"Kathryn\",\n                                       born = \"1839-03-28\",\n                                       died = \"1865-12-19\"),\n                    Helen = list(born = \"1840-17-08\",\n                                 died = \"1845-01-01\")\n                                 \n                   )\nFromListSimple(kingJosephs, nodeName = \"Joseph I\")\n  \n}\n\\seealso{\nOther as.Node: \n\\code{\\link{as.Node.data.frame}()},\n\\code{\\link{as.Node.dendrogram}()},\n\\code{\\link{as.Node.phylo}()},\n\\code{\\link{as.Node.rpart}()},\n\\code{\\link{as.Node}()}\n}\n\\concept{as.Node}\n"
  },
  {
    "path": "man/as.Node.party.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_party.R\n\\name{as.Node.party}\n\\alias{as.Node.party}\n\\title{Convert a a \\code{party} from the partykit package to a \\code{data.tree} structure.}\n\\usage{\n\\method{as.Node}{party}(x, ...)\n}\n\\arguments{\n\\item{x}{The party object}\n\n\\item{...}{other arguments (unused)}\n}\n\\description{\nConvert a a \\code{party} from the partykit package to a \\code{data.tree} structure.\n}\n\\examples{\nlibrary(partykit)\ndata(\"WeatherPlay\", package = \"partykit\")\n### splits ###\n# split in overcast, humidity, and windy\nsp_o <- partysplit(1L, index = 1:3)\nsp_h <- partysplit(3L, breaks = 75)\nsp_w <- partysplit(4L, index = 1:2)\n\n## query labels\ncharacter_split(sp_o)\n\n### nodes ###\n## set up partynode structure\npn <- partynode(1L, split = sp_o, kids = list(\n  partynode(2L, split = sp_h, kids = list(\n      partynode(3L, info = \"yes\"),\n      partynode(4L, info = \"no\"))),\n  partynode(5L, info = \"yes\"),\n  partynode(6L, split = sp_w, kids = list(\n      partynode(7L, info = \"yes\"),\n      partynode(8L, info = \"no\")))))\npn\n### tree ###\n## party: associate recursive partynode structure with data\npy <- party(pn, WeatherPlay)\ntree <- as.Node(py)\n\nprint(tree, \n      \"splitname\",\n      count = function(node) nrow(node$data), \n      \"splitLevel\")\n\nSetNodeStyle(tree, \n             label = function(node) paste0(node$name, \": \", node$splitname), \n             tooltip = function(node) paste0(nrow(node$data), \" observations\"),\n             fontname = \"helvetica\")\nSetEdgeStyle(tree, \n             arrowhead = \"none\", \n             label = function(node) node$splitLevel,\n             fontname = \"helvetica\",\n             penwidth = function(node) 12 * nrow(node$data)/nrow(node$root$data),\n             color = function(node) {\n               paste0(\"grey\", \n                      100 - as.integer( 100 * nrow(node$data)/nrow(node$root$data))\n                      )\n             }\n             )\nDo(tree$leaves, \n   function(node) {\n     SetNodeStyle(node, \n                  shape = \"box\", \n                  color = ifelse(node$splitname == \"yes\", \"darkolivegreen4\", \"lightsalmon4\"),\n                  fillcolor = ifelse(node$splitname == \"yes\", \"darkolivegreen1\", \"lightsalmon\"),\n                  style = \"filled,rounded\",\n                  penwidth = 2\n                  )\n   }\n   )\n\nplot(tree)\n\n\n}\n"
  },
  {
    "path": "man/as.Node.phylo.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_ape.R\n\\name{as.Node.phylo}\n\\alias{as.Node.phylo}\n\\title{Convert a \\code{phylo} object from the ape package to a \\code{Node}}\n\\usage{\n\\method{as.Node}{phylo}(\n  x,\n  heightName = \"plotHeight\",\n  replaceUnderscores = TRUE,\n  namesNotUnique = FALSE,\n  ...\n)\n}\n\\arguments{\n\\item{x}{The phylo object to be converted}\n\n\\item{heightName}{If the phylo contains edge lengths, then they will be converted\nto a height and stored in a field named according to this parameter (the default is \"height\")}\n\n\\item{replaceUnderscores}{if TRUE (the default), then underscores in names are replaced with spaces}\n\n\\item{namesNotUnique}{if TRUE, then the \\code{name} of the \\code{Node}s will be prefixed with a unique id.\nThis is useful if the children of a parent have non-unique names.}\n\n\\item{...}{any other parameter to be passed to sub-implementations}\n}\n\\description{\nConvert a \\code{phylo} object from the ape package to a \\code{Node}\n}\n\\examples{\n#which bird familes have the max height?\nlibrary(ape)\ndata(bird.families)\nbf <- as.Node(bird.families)\nheight <- bf$height\nt <- Traverse(bf, filterFun = function(x) x$level == 25)\nGet(t, \"name\")\n\n}\n\\seealso{\nOther ape phylo conversions: \n\\code{\\link{GetPhyloNr}()},\n\\code{\\link{as.phylo.Node}()}\n\nOther as.Node: \n\\code{\\link{as.Node.data.frame}()},\n\\code{\\link{as.Node.dendrogram}()},\n\\code{\\link{as.Node.list}()},\n\\code{\\link{as.Node.rpart}()},\n\\code{\\link{as.Node}()}\n}\n\\concept{ape phylo conversions}\n\\concept{as.Node}\n"
  },
  {
    "path": "man/as.Node.rpart.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_rpart.R\n\\name{as.Node.rpart}\n\\alias{as.Node.rpart}\n\\title{Convert an \\code{\\link{rpart}} object to a \\code{data.tree} structure}\n\\usage{\n\\method{as.Node}{rpart}(x, digits = getOption(\"digits\") - 3, use.n = FALSE, ...)\n}\n\\arguments{\n\\item{x}{the \\code{rpart} object to be converted}\n\n\\item{digits}{the number of digits to be used for numeric values in labels}\n\n\\item{use.n}{logical. Add cases to labels, see \\code{\\link{text.rpart}} for further\ninformation}\n\n\\item{...}{any other argument to be passed to generic sub implementations}\n}\n\\value{\na \\code{data.tree} object. The tree contains a field \\code{rpart.id} which\n        references back to the original node id in the row names of the \\code{rpart} object.\n}\n\\description{\nConvert an \\code{\\link{rpart}} object to a \\code{data.tree} structure\n}\n\\examples{\nif (require(rpart)) {\n   fit <- rpart(Kyphosis ~ Age + Number + Start, data = kyphosis)\n   as.Node(fit)\n}\n}\n\\seealso{\nOther as.Node: \n\\code{\\link{as.Node.data.frame}()},\n\\code{\\link{as.Node.dendrogram}()},\n\\code{\\link{as.Node.list}()},\n\\code{\\link{as.Node.phylo}()},\n\\code{\\link{as.Node}()}\n}\n\\concept{as.Node}\n"
  },
  {
    "path": "man/as.data.frame.Node.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_dataframe.R\n\\name{as.data.frame.Node}\n\\alias{as.data.frame.Node}\n\\alias{ToDataFrameTree}\n\\alias{ToDataFrameTable}\n\\alias{ToDataFrameNetwork}\n\\alias{ToDataFrameTypeCol}\n\\title{Convert a \\code{data.tree} structure to a \\code{data.frame}}\n\\usage{\n\\method{as.data.frame}{Node}(\n  x,\n  row.names = NULL,\n  optional = FALSE,\n  ...,\n  traversal = c(\"pre-order\", \"post-order\", \"in-order\", \"level\", \"ancestor\"),\n  pruneFun = NULL,\n  filterFun = NULL,\n  format = FALSE,\n  inheritFromAncestors = FALSE\n)\n\nToDataFrameTree(x, ..., pruneFun = NULL)\n\nToDataFrameTable(x, ..., pruneFun = NULL)\n\nToDataFrameNetwork(\n  x,\n  ...,\n  direction = c(\"climb\", \"descend\"),\n  pruneFun = NULL,\n  format = FALSE,\n  inheritFromAncestors = FALSE\n)\n\nToDataFrameTypeCol(x, ..., type = \"level\", prefix = type, pruneFun = NULL)\n}\n\\arguments{\n\\item{x}{The root \\code{Node} of the tree or sub-tree to be convert to a data.frame}\n\n\\item{row.names}{\\code{NULL} or a character vector giving the row names for the data frame.\nMissing values are not allowed.}\n\n\\item{optional}{logical. If \\code{TRUE}, setting row names and converting column names\n(to syntactic names: see make.names) is optional.}\n\n\\item{...}{the attributes to be added as columns of the data.frame. See \\code{\\link{Get}} for details.\nIf a specific Node does not contain the attribute, \\code{NA} is added to the data.frame.}\n\n\\item{traversal}{any of 'pre-order' (the default), 'post-order', 'in-order', 'level', or 'ancestor'. See \\code{\\link{Traverse}} for details.}\n\n\\item{pruneFun}{allows providing a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \nIf the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.}\n\n\\item{filterFun}{a function taking a \\code{Node} as an argument. See \\code{\\link{Traverse}} for details.}\n\n\\item{format}{if \\code{FALSE} (the default), then no formatting will be applied. If \\code{TRUE}, then the first formatter (if any) along the ancestor\npath is used for formatting.}\n\n\\item{inheritFromAncestors}{if FALSE, and if the attribute is a field or a method, then only a \\code{Node} itself is\nsearched for the field/method. If TRUE, and if the \\code{Node} does not contain the attribute, then ancestors are also searched.}\n\n\\item{direction}{when converting to a network, should the edges point from root to children (\"climb\") or from child to parent (\"descend\")?}\n\n\\item{type}{when converting type columns, the \\code{type} is the discriminator, i.e. an attribute (e.g. field name) of each node}\n\n\\item{prefix}{when converting type columns, the prefix used for the column names. Can be NULL to omit prefixes.}\n}\n\\value{\nToDataFrameTree: a \\code{data.frame}, where each row represents a \\code{Node} in the tree or sub-tree\nspanned by \\code{x}, possibly pruned according to \\code{pruneFun}.\n\nToDataFrameTable: a \\code{data.frame}, where each row represents a leaf \\code{Node} in the tree or sub-tree\nspanned by \\code{x}, possibly pruned according to \\code{pruneFun}.\n\nToDataFrameNetwork: a \\code{data.frame}, where each row represents a \\code{Node} in the tree or sub-tree\nspanned by \\code{x}, possibly pruned according to \\code{pruneFun}. The first column is called 'from', while the\nsecond is called 'to', describing the parent to child edge (for direction \"climb\") or the child to parent edge (for direction \"descend\").\nIf \\code{\\link{AreNamesUnique}} is TRUE, then the Network is\nbased on the \\code{Node$name}, otherwise on the \\code{Node$pathString}\n\nToDataFrameTypeCol: a \\code{data.frame} in table format (i.e. where each row represents a leaf in the tree or sub-tree\nspanned by \\code{x}), possibly pruned according to \\code{pruneFun}. In addition to \\code{...}, each distinct\n\\code{type} is output to a column.\n}\n\\description{\nIf a node field contains data of length > 1, then that is converted into a string in the\ndata.frame.\n}\n\\examples{\ndata(acme)\nacme$attributesAll\nas.data.frame(acme, row.names = NULL, optional = FALSE, \"cost\", \"p\")\n\nToDataFrameTree(acme, \"cost\", \"p\")\nToDataFrameNetwork(acme, \"cost\", \"p\", direction = \"climb\")\nToDataFrameTable(acme, \"cost\", \"p\")\nToDataFrameTypeCol(acme)\n\n#use the pruneFun:\nacme$Do(function(x) x$totalCost <- Aggregate(x, \"cost\", sum), traversal = \"post-order\")\nToDataFrameTree(acme, \"totalCost\", pruneFun = function(x) x$totalCost > 300000)\n\n#inherit\nacme$Set(floor = c(1, 2, 3), filterFun = function(x) x$level == 2)\nas.data.frame(acme, row.names = NULL, optional = FALSE, \"floor\", inheritFromAncestors = FALSE)\nas.data.frame(acme, row.names = NULL, optional = FALSE, \"floor\", inheritFromAncestors = TRUE)\n\n#using a function as an attribute:\nacme$Accounting$Head <- \"Mrs. Numright\"\nacme$Research$Head <- \"Mr. Stein\"\nacme$IT$Head <- \"Mr. Squarehead\"\nToDataFrameTable(acme, department = function(x) x$parent$name, \"name\", \"Head\", \"cost\")\n\n#complex TypeCol\nacme$IT$Outsource$AddChild(\"India\")\nacme$IT$Outsource$AddChild(\"Poland\")\nacme$Set(type = c('company', 'department', 'project', 'project', 'department',\n                  'project', 'project', 'department', 'program', 'project',\n                  'project', 'project', 'project'\n                  )\n        )\nprint(acme, 'type')\nToDataFrameTypeCol(acme, type = 'type')\n\n}\n"
  },
  {
    "path": "man/as.dendrogram.Node.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_dendrogram.R\n\\name{as.dendrogram.Node}\n\\alias{as.dendrogram.Node}\n\\title{Convert a \\code{Node} to a \\code{dendrogram}}\n\\usage{\n\\method{as.dendrogram}{Node}(\n  object,\n  heightAttribute = DefaultPlotHeight,\n  edgetext = FALSE,\n  ...\n)\n}\n\\arguments{\n\\item{object}{The Node to convert}\n\n\\item{heightAttribute}{The attribute (field name or function) storing the height}\n\n\\item{edgetext}{If TRUE, then the for non-leaf nodes the node name is stored as the dendrogram's edge text.}\n\n\\item{...}{Additional parameters}\n}\n\\value{\nAn object of class dendrogram\n}\n\\description{\nConvert a \\code{data.tree} structure to a \\code{\\link{dendrogram}}\n}\n\\examples{\ndata(acme)\nacmed <- as.dendrogram(acme)\nplot(acmed, center = TRUE)\n\n#you can take an attribute for the height:\nacme$Do( function(x) x$myPlotHeight <- (10 - x$level))\nacmed <- as.dendrogram(acme, heightAttribute = \"myPlotHeight\")\nplot(acmed, center = TRUE)\n\n#or directly a function\nacmed <- as.dendrogram(acme, heightAttribute = function(x) 10 - x$level)\nplot(acmed)\n\n}\n\\seealso{\nOther Conversions from Node: \n\\code{\\link{ToNewick}()}\n}\n\\concept{Conversions from Node}\n"
  },
  {
    "path": "man/as.igraph.Node.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_igraph.R\n\\name{as.igraph.Node}\n\\alias{as.igraph.Node}\n\\title{Convert a \\code{data.tree} structure to an igraph network}\n\\usage{\nas.igraph.Node(\n  x,\n  vertexAttributes = character(),\n  edgeAttributes = character(),\n  directed = FALSE,\n  direction = c(\"climb\", \"descend\"),\n  ...\n)\n}\n\\arguments{\n\\item{x}{The root \\code{Node} to convert}\n\n\\item{vertexAttributes}{A vector of strings, representing the attributes \nin the \\code{data.tree} structure to add as attributes to the vertices of the igraph}\n\n\\item{edgeAttributes}{A vector of strings, representing the attributes\nin the \\code{data.tree} structure to add as edge attributes of the igraph}\n\n\\item{directed}{Logical scalar, whether or not to create a directed graph.}\n\n\\item{direction}{when converting to a network, should the edges point from root to children (\"climb\") or from child to parent (\"descend\")?}\n\n\\item{...}{Currently unused.}\n}\n\\value{\nan \\code{igraph} object\n}\n\\description{\nThis requires the igraph package to be installed.\nAlso, this requires the names of the \\code{Nodes} to be unique within\nthe \\code{data.tree} structure.\n}\n\\examples{\ndata(acme)\nlibrary(igraph)\nig <- as.igraph(acme, \"p\", c(\"level\", \"isLeaf\"))\nplot(ig)\n\n}\n\\seealso{\nAreNamesUnique\n}\n"
  },
  {
    "path": "man/as.list.Node.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_list.R\n\\name{as.list.Node}\n\\alias{as.list.Node}\n\\alias{ToListSimple}\n\\alias{ToListExplicit}\n\\title{Convert a \\code{data.tree} structure to a list-of-list structure}\n\\usage{\n\\method{as.list}{Node}(\n  x,\n  mode = c(\"simple\", \"explicit\"),\n  unname = FALSE,\n  nameName = ifelse(unname, \"name\", \"\"),\n  childrenName = \"children\",\n  rootName = \"\",\n  keepOnly = NULL,\n  pruneFun = NULL,\n  ...\n)\n\nToListSimple(x, nameName = \"name\", pruneFun = NULL, ...)\n\nToListExplicit(\n  x,\n  unname = FALSE,\n  nameName = ifelse(unname, \"name\", \"\"),\n  childrenName = \"children\",\n  pruneFun = NULL,\n  ...\n)\n}\n\\arguments{\n\\item{x}{The Node to convert}\n\n\\item{mode}{How the list is structured. \"simple\" (the default) will add children directly as nested lists.\n\"explicit\" puts children in a separate nested list called \\code{childrenName}}\n\n\\item{unname}{If TRUE, and if \\code{mode} is \"explicit\", then the nested children list will not have named arguments. This\ncan be useful e.g. in the context of conversion to JSON, if you prefer the children to be\nan array rather than named objects.}\n\n\\item{nameName}{The name that should be given to the name element}\n\n\\item{childrenName}{The name that should be given to the children nested list}\n\n\\item{rootName}{The name of the node. If provided, this overrides \\code{Node$name}}\n\n\\item{keepOnly}{A character vector of attributes to include in the result. If \\code{NULL} (the default), all attributes are kept.}\n\n\\item{pruneFun}{allows providing a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \nIf the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.}\n\n\\item{...}{Additional parameters passed to \\code{as.list.Node}}\n}\n\\description{\nConvert a \\code{data.tree} structure to a list-of-list structure\n}\n\\examples{\ndata(acme)\n\nstr(ToListSimple(acme))\nstr(ToListSimple(acme, keepOnly = \"cost\"))\n\nstr(ToListExplicit(acme))\nstr(ToListExplicit(acme, unname = TRUE))\nstr(ToListExplicit(acme, unname = TRUE, nameName = \"id\", childrenName = \"descendants\"))\n\n}\n"
  },
  {
    "path": "man/as.phylo.Node.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_conversion_ape.R\n\\name{as.phylo.Node}\n\\alias{as.phylo.Node}\n\\title{Convert a \\code{Node} to a phylo object from the ape package.}\n\\usage{\nas.phylo.Node(x, heightAttribute = DefaultPlotHeight, ...)\n}\n\\arguments{\n\\item{x}{The root \\code{Node} of the tree or sub-tree to be converted}\n\n\\item{heightAttribute}{The attribute (field name or function) storing the height}\n\n\\item{...}{any other argument}\n}\n\\description{\nThis method requires the ape package to be installed and loaded.\n}\n\\examples{\nlibrary(ape)\ndata(acme)\nacmephylo <- as.phylo(acme)\n#plot(acmephylo)\n\n\n}\n\\seealso{\nOther ape phylo conversions: \n\\code{\\link{GetPhyloNr}()},\n\\code{\\link{as.Node.phylo}()}\n}\n\\concept{ape phylo conversions}\n"
  },
  {
    "path": "man/averageBranchingFactor.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_actives.R\n\\name{averageBranchingFactor}\n\\alias{averageBranchingFactor}\n\\title{Calculate the average number of branches each non-leaf has}\n\\usage{\naverageBranchingFactor(node)\n}\n\\arguments{\n\\item{node}{The node to calculate the average branching factor for}\n}\n\\description{\nCalculate the average number of branches each non-leaf has\n}\n"
  },
  {
    "path": "man/data.tree.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/data.tree-package.R\n\\docType{package}\n\\name{data.tree}\n\\alias{data.tree}\n\\alias{data.tree-package}\n\\title{data.tree: Hierarchical Data Structures}\n\\description{\n\\code{data.tree} is to hierarchical data what \\code{data.frame} is to tabular data: An extensible, general purpose structure to store, manipulate, \nand display hierarchical data.\n}\n\\section{Introduction}{\n\n\nHierarchical data is ubiquitous in statistics and programming (XML, search trees, family trees, classification, file system, etc.). However, no general-use \\bold{tree data structure} is available in R. \nWhere tabular data has \\code{data.frame}, hierarchical data is often modeled in lists of lists or similar makeshifts. These\nstructures are often difficult to manage.\nThis is where the \\code{data.tree} package steps in. It lets you build trees of hierarchical\ndata for various uses: to print, to rapid prototype search algorithms, to test out new classification algorithms, and much more.\n}\n\n\\section{Tree Traversal}{\n\n\n\\code{data.tree} allows to \\code{\\link{Traverse}} trees in various orders (pre-order, post-order, level, etc.), and it lets you run operations on \\code{\\link{Node}s} via\n\\code{\\link{Do}}. \nSimilarly, you can collect and store data while traversing a tree using the \\code{\\link{Get}} and the \\code{\\link{Set}} methods.\n}\n\n\\section{Methods}{\n\n\nThe package also contains utility functions to \\code{\\link{Sort}}, to \\code{\\link{Prune}}, to \\code{\\link{Aggregate}} and \\code{\\link{Cumulate}} \nand to \\code{\\link{print}} in custom formats.\n}\n\n\\section{Construction and Conversion}{\n\n\nThe package also contains many conversions from and to data.tree structures. Check out the see also section of \\code{\\link{as.Node}}.\n  \nYou can construct a tree from a \\code{data.frame} using \\code{\\link{as.Node.data.frame}}, and convert it back using \\code{\\link{as.data.frame.Node}}.\nSimilar options exist for list of lists. \nFor more specialized conversions, see \\code{\\link{as.dendrogram.Node}}, \\code{\\link{as.Node.dendrogram}}, \n\\code{\\link{as.phylo.Node}} and \\code{\\link{as.Node.phylo}}\n\nFinally, easy conversion options from and to list, dataframe, JSON, YAML, igraph, ape, rpart, party and more exist:\n\n\\itemize{\n \\item{list: both directions}\n \\item{dataframe: both directions}\n \\item{JSON, YAML: both directions, via lists}\n \\item{igraph: from igraph to data.tree}\n \\item{ape: both directions}\n \\item{rpart: from rpart to data.tree}\n \\item{party: from party to data.tree}\n}\n}\n\n\\section{Node and Reference Semantics}{\n\n \nThe entry point to the package is \\code{\\link{Node}}. Each tree is composed of a number of \\code{Node}s, referencing each other.\n\nOne of most important things to note about \\code{data.tree} is that it exhibits \\bold{reference semantics}. In a nutshell, this means that you can modify \nyour tree along the way, without having to reassign it to a variable after each modification. By and large, this is a rather exceptional behavior\nin R, where value-semantics is king most of the time.\n}\n\n\\section{Applications}{\n\n\n\\code{data.tree} is not optimised for computational speed, but for implementation speed. Namely, its memory\nfootprint is relatively large compared to traditional R data structures. However, it can easily handle trees with\nseveral thousand nodes, and once a tree is constructed, operations on it are relatively fast.\ndata.tree is always useful when\n\\itemize{\n \\item{you want to develop and test a new algorithm}\n \\item{you want to import and convert tree structures (it imports and exports to list-of-list, data.frame, yaml, json, igraph, dendrogram, phylo and more)}\n \\item{you want to play around with data, display it and get an understanding}\n \\item{you want to test another package, to compare it with your own results}\n \\item{you need to do homework}\n}\n\nFor a quick overview of the features, read the \\code{\\link{data.tree}} vignette by running \\code{vignette(\"data.tree\")}. For stylized\napplications, see \\code{vignette(\"applications\", package='data.tree')}\n}\n\n\\examples{\ndata(acme)\nprint(acme)\nacme$attributesAll\nacme$count\nacme$totalCount\nacme$isRoot\nacme$height\nprint(acme, \"p\", \"cost\")\n\noutsource <- acme$IT$Outsource\nclass(outsource)\nprint(outsource)\noutsource$attributes\noutsource$isLeaf\noutsource$level\noutsource$path\noutsource$p\noutsource$parent$name\noutsource$root$name\noutsource$expCost <- outsource$p * outsource$cost\nprint(acme, \"expCost\")\n\nacme$Get(\"p\")\nacme$Do(function(x) x$expCost <- x$p * x$cost)\nacme$Get(\"expCost\", filterFun = isLeaf)\n\nToDataFrameTable(acme, \"name\", \"p\", \"cost\", \"level\", \"pathString\")\nToDataFrameTree(acme, \"name\", \"p\", \"cost\", \"level\")\nToDataFrameNetwork(acme, \"p\", \"cost\")\n\n\n}\n\\seealso{\n\\code{\\link{Node}}\n\nFor more details, see the \\code{data.tree} vignette by running: \\code{vignette(\"data.tree\")}\n}\n\\author{\n\\strong{Maintainer}: Christoph Glur \\email{christoph.glur@powerpartners.pro} (R interface)\n\nOther contributors:\n\\itemize{\n  \\item Russ Hyde (improve dependencies) [contributor]\n  \\item Chris Hammill (improve getting) [contributor]\n  \\item Facundo Munoz (improve list conversion) [contributor]\n  \\item Markus Wamser (fixed some typos) [contributor]\n  \\item Pierre Formont (additional features) [contributor]\n  \\item Kent Russel (documentation) [contributor]\n  \\item Noam Ross (fixes) [contributor]\n  \\item Duncan Garmonsway (fixes) [contributor]\n}\n\n}\n\\keyword{internal}\n"
  },
  {
    "path": "man/isLeaf.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_actives.R\n\\name{isLeaf}\n\\alias{isLeaf}\n\\title{Check if a \\code{Node} is a leaf}\n\\usage{\nisLeaf(node)\n}\n\\arguments{\n\\item{node}{The Node to test.}\n}\n\\value{\nTRUE if the Node is a leaf, FALSE otherwise\n}\n\\description{\nCheck if a \\code{Node} is a leaf\n}\n"
  },
  {
    "path": "man/isNotLeaf.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_actives.R\n\\name{isNotLeaf}\n\\alias{isNotLeaf}\n\\title{Check if a \\code{Node} is not a leaf}\n\\usage{\nisNotLeaf(node)\n}\n\\arguments{\n\\item{node}{The Node to test.}\n}\n\\value{\nFALSE if the Node is a leaf, TRUE otherwise\n}\n\\description{\nCheck if a \\code{Node} is not a leaf\n}\n"
  },
  {
    "path": "man/isNotRoot.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_actives.R\n\\name{isNotRoot}\n\\alias{isNotRoot}\n\\title{Check if a \\code{Node} is not a root}\n\\usage{\nisNotRoot(node)\n}\n\\arguments{\n\\item{node}{The Node to test.}\n}\n\\value{\nFALSE if the Node is the root, TRUE otherwise\n}\n\\description{\nCheck if a \\code{Node} is not a root\n}\n"
  },
  {
    "path": "man/isRoot.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_actives.R\n\\name{isRoot}\n\\alias{isRoot}\n\\title{Check if a \\code{Node} is the root}\n\\usage{\nisRoot(node)\n}\n\\arguments{\n\\item{node}{The Node to test.}\n}\n\\value{\nTRUE if the Node is the root, FALSE otherwise\n}\n\\description{\nCheck if a \\code{Node} is the root\n}\n"
  },
  {
    "path": "man/mushroom.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/data_doc.R\n\\docType{data}\n\\name{mushroom}\n\\alias{mushroom}\n\\title{Sample Data: Data Used by the ID3 Vignette}\n\\format{\ndata.frame\n}\n\\usage{\ndata(mushroom)\n}\n\\description{\nmushroom contains attributes of mushrooms. We can use this data to predict a\nmushroom's toxicity based on its attributes.\nThe attributes available in the data set are:\n}\n\\details{\n\\itemize{\n  \\item color the color of a mushroom\n  \\item size whether a mushroom is small or large\n  \\item points whether a mushroom has points\n  \\item edibility whether a mushroom is edible or toxic\n}\n}\n\\keyword{datasets}\n"
  },
  {
    "path": "man/print.Node.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/node_methods.R\n\\name{print.Node}\n\\alias{print.Node}\n\\title{Print a \\code{Node} in a human-readable fashion.}\n\\usage{\n\\method{print}{Node}(\n  x,\n  ...,\n  pruneMethod = c(\"simple\", \"dist\", NULL),\n  limit = 100,\n  pruneFun = NULL,\n  row.names = T\n)\n}\n\\arguments{\n\\item{x}{The Node}\n\n\\item{...}{Node attributes to be printed. Can be either a character (i.e. the name of a Node field),\na Node method, or a function taking a Node as a single argument. See \\code{Get} for details on\nthe meaning of \\code{attribute}.}\n\n\\item{pruneMethod}{The method can be used to prune for printing in a simple way. If NULL, the entire tree is displayed. If\n\"simple\", then only the first \\code{limit} nodes are displayed. If \"dist\", then Nodes are removed\neverywhere in the tree, according to their level. If pruneFun is provided, then pruneMethod is ignored.}\n\n\\item{limit}{The maximum number of nodes to print. Can be \\code{NULL} if the\nentire tree should be printed.}\n\n\\item{pruneFun}{allows providing a prune criteria, i.e. a function taking a \\code{Node} as an input, and returning \\code{TRUE} or \\code{FALSE}. \nIf the pruneFun returns FALSE for a Node, then the Node and its entire sub-tree will not be considered.}\n\n\\item{row.names}{If \\code{TRUE} (default), then the row names are printed out. Else, they are not.}\n}\n\\description{\nPrint a \\code{Node} in a human-readable fashion.\n}\n\\examples{\ndata(acme)\nprint(acme, \"cost\", \"p\")\nprint(acme, \"cost\", probability = \"p\")\nprint(acme, expectedCost = function(x) x$cost * x$p)\ndo.call(print, c(acme, acme$attributesAll))\n\ntree <- CreateRegularTree(4, 5)\n# print entire tree:\nprint(tree, pruneMethod = NULL)\n# print first 20 nodes:\nprint(tree, pruneMethod = \"simple\", limit = 20)\n# print 20 nodes, removing leafs first:\nprint(tree, pruneMethod = \"dist\", limit = 20)\n# provide your own pruning function:\nprint(tree, pruneFun = function(node) node$position != 2)\n\n\n}\n"
  },
  {
    "path": "man/s3_register.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/register-s3.R\n\\name{s3_register}\n\\alias{s3_register}\n\\title{Register a method for a suggested dependency}\n\\usage{\ns3_register(generic, class, method = NULL)\n}\n\\arguments{\n\\item{generic}{Name of the generic in the form `pkg::generic`.}\n\n\\item{class}{Name of the class}\n\n\\item{method}{Optionally, the implementation of the method. By default,\n  this will be found by looking for a function called `generic.class`\n  in the package environment.\n\n  Note that providing `method` can be dangerous if you use\n  devtools. When the namespace of the method is reloaded by\n  `devtools::load_all()`, the function will keep inheriting from\n  the old namespace. This might cause crashes because of dangling\n  `.Call()` pointers.}\n}\n\\description{\nCode copied into data.tree from `vctrs` (authors Wickham H, Henry L,\nVaughan D; https://github.com/r-lib/vctrs)\n}\n\\details{\nGenerally, the recommend way to register an S3 method is to use the\n`S3Method()` namespace directive (often generated automatically be the\n`@export` roxygen2 tag). However, this technique requires that the generic\nbe in an imported package, and sometimes you want to suggest a package,\nand only provide a method when that package is loaded. `s3_register()`\ncan be called from your package's `.onLoad()` to dynamically register\na method only if the generic's package is loaded. (To avoid taking a\ndependency on vctrs for this one function, please feel free to copy\nand paste the function source into your own package.)\n\nFor R 3.5.0 and later, `s3_register()` is also useful when demonstrating\nclass creation in a vignette, since method lookup no longer always involves\nthe lexical scope. For R 3.6.0 and later, you can achieve a similar effect\nby using \"delayed method registration\", i.e. placing the following in your\n`NAMESPACE` file:\n\n```\nif (getRversion() >= \"3.6.0\") {\n  S3method(package::generic, class)\n}\n```\n}\n\\examples{\n# A typical use case is to dynamically register tibble/pillar methods\n# for your class. That way you avoid creating a hard depedency on packages\n# that are not essential, while still providing finer control over\n# printing when they are used.\n\n.onLoad <- function(...) {\n  s3_register(\"pillar::pillar_shaft\", \"vctrs_vctr\")\n  s3_register(\"tibble::type_sum\", \"vctrs_vctr\")\n}\n}\n\\keyword{internal}\n"
  },
  {
    "path": "publish-cheat-sheet.md",
    "content": "Before a release, do the following:\n1. Set date in DESCRIPTION\n2. Make sure NEWS is up to date\n3. make sure tests pass (by running devtools::test())\n4. review documentation, especially Node\n5. review vignettes (especially if png need updating). Run devtools::spell_check()\n6. Check build by running devtools::check()\n7. Commit to git, make sure travis and appveyor pass (in case it fails, you may want to clean cache)\n8. make sure we have adequate coverage\n9. Make sure devel passes, by running devtools::check_win_devel\n10. Make sure r-oldrel passes (easiest is to run it on local windows)\n11. Run devtools::check_rhub()\n12. Run rhub::check_for_cran()\n-> if any of these fail, go back to 6.!\n13. check reverse dependencies by running revdepcheck::revdep_check(, num_workers = 2, timeout = as.difftime(60, units=\"mins\")) (from github if not yet published to CRAN devtools::install_github(\"r-lib/revdepcheck\")\n14. update cran-comments.md\n15. merge into master and push\n16. create release on github in master, tag it as pre-release\n17. submit it to cran by calling devtools::release()\n18. once accepted by CRAN, remove the pre-release flag on github\n"
  },
  {
    "path": "tests/testthat/test-draw.R",
    "content": "context(\"plot\")\n\n\ntest_that(\"plot only works if DiagrammeR is installed\", {\n\n  # Given\n  # - an object of class \"Node\"--\"R6\"\n  # - in an R session where DiagrammeR is not installed\n  # When\n  # - the user tries to construct a DiagrammeR-based graph or plot\n  # Then\n  # - an error is thrown\n\n  skip_if_not_installed(\"mockery\")\n  data(acme)\n  mockery::stub(ToDiagrammeRGraph, \"requireNamespace\", FALSE, 1)\n  mockery::stub(plot.Node, \"requireNamespace\", FALSE, 1)\n\n  expect_error(\n    ToDiagrammeRGraph(acme),\n    info = \"ToDiagrammeRGraph should fail if DiagrammeR is not installed\")\n\n  expect_error(\n    plot(acme),\n    info = \"plot() should fail if DiagrammeR is not installed\")\n})\n\n\ntest_that(\"grViz\", {\n  testthat::skip_if_not_installed(\"DiagrammeR\", minimum_version = \"1.0.0\")\n\n  data(acme)  \n  \n  SetGraphStyle(acme, rankdir = \"TB\")\n  SetEdgeStyle(acme, arrowhead = \"vee\", color = \"grey35\", penwidth = 2)\n  #per default, Node style attributes will be inherited:\n  SetNodeStyle(acme, style = \"filled,rounded\", shape = \"box\", fillcolor = \"GreenYellow\", \n               fontname = \"helvetica\", tooltip = GetDefaultTooltip)\n  SetNodeStyle(acme$IT, fillcolor = \"LightBlue\", penwidth = \"5px\")\n  #inheritance can be avoided:\n  SetNodeStyle(acme$Accounting, inherit = FALSE, fillcolor = \"Thistle\", \n               fontcolor = \"Firebrick\", tooltip = \"This is the accounting department\")\n  #use Do to set style on specific nodes:\n  Do(acme$leaves, function(node) SetNodeStyle(node, shape = \"egg\"))\n  graph <- ToDiagrammeRGraph(acme, direction = \"descend\", pruneFun = function(x) x$level < 3)\n  gv <- DiagrammeR::generate_dot(graph)\n  expect_equal(substr(gv, 1, 9), \"digraph {\")\n})\n\n\n\ntest_that(\"grViz single attribute\", {\n  testthat::skip_if_not_installed(\"DiagrammeR\", minimum_version = \"1.0.0\")\n\n  data(acme)\n  SetNodeStyle(acme$Accounting, label = \"Mimi\")\n  \n  graph <- ToDiagrammeRGraph(acme)\n  gv <- DiagrammeR::generate_dot(graph)\n  \n  exp <- \"digraph {\n\n\n\n\n  '1' [label = 'Acme Inc.'] \n  '2' [label = 'Mimi'] \n  '3' [label = 'New Software'] \n  '4' [label = 'New Accounting Standards'] \n  '5' [label = 'Research'] \n  '6' [label = 'New Product Line'] \n  '7' [label = 'New Labs'] \n  '8' [label = 'IT'] \n  '9' [label = 'Outsource'] \n  '10' [label = 'Go agile'] \n  '11' [label = 'Switch to R'] \n  '1'->'2' \n  '1'->'5' \n  '1'->'8' \n  '2'->'3' \n  '2'->'4' \n  '5'->'6' \n  '5'->'7' \n  '8'->'9' \n  '8'->'10' \n  '8'->'11' \n}\"\n  \n  expect_equal(gv, exp)\n  \n})\n\n\ntest_that(\"grViz single attribute names not uniuqe\", {\n  testthat::skip_if_not_installed(\"DiagrammeR\", minimum_version = \"1.0.0\")\n\n  mytree <- CreateRegularTree(3, 3)\n  mytree$Do(function(x) x$name <- x$position)\n  SetNodeStyle(mytree, label = \"Root\")\n  SetNodeStyle(mytree$`1`, tooltip = \"L1\")\n  graph <- ToDiagrammeRGraph(mytree)\n  gv <- DiagrammeR::generate_dot(graph)\n  \n  exp <- \"digraph {\n\n\n\n\n  '1' [label = 'Root', tooltip = ''] \n  '2' [label = 'Root', tooltip = 'L1'] \n  '3' [label = 'Root', tooltip = ''] \n  '4' [label = 'Root', tooltip = ''] \n  '5' [label = 'Root', tooltip = ''] \n  '6' [label = 'Root', tooltip = ''] \n  '7' [label = 'Root', tooltip = ''] \n  '8' [label = 'Root', tooltip = ''] \n  '9' [label = 'Root', tooltip = ''] \n  '10' [label = 'Root', tooltip = ''] \n  '11' [label = 'Root', tooltip = ''] \n  '12' [label = 'Root', tooltip = ''] \n  '13' [label = 'Root', tooltip = ''] \n  '1'->'2' \n  '1'->'6' \n  '1'->'10' \n  '2'->'3' \n  '2'->'4' \n  '2'->'5' \n  '6'->'7' \n  '6'->'8' \n  '6'->'9' \n  '10'->'11' \n  '10'->'12' \n  '10'->'13' \n}\"\n  \n  expect_equal(gv, exp)\n  \n})\n\ntest_that(\"grViz names with quotes\", {\n  mytree <- Node$new(\"my_root\")\n  mytree$AddChild(\"A\")$AddChild(\"\\\"B\\\"\")$AddChild(\"\\\"C\\\"\")$AddChild(\"D\")\n  exp_lab <- c(\"my_root\", \"A\", \"\\\\\\\"B\\\\\\\"\", \"\\\\\\\"C\\\\\\\"\", \"D\")\n  expect_equal(ToDiagrammeRGraph(mytree)$nodes_df$label,\n               exp_lab)\n})\n\n"
  },
  {
    "path": "tests/testthat/test-treeConstruction.R",
    "content": "#library(data.tree)\ncontext(\"tree construction\")\n\ndata(acme)\n\ntest_that(\"isRoot\", {\n  data(acme)\n  \n  expect_equal(acme$isRoot, TRUE)\n  \n  expect_equal(acme$IT$isRoot, FALSE)\n  \n  expect_equal(acme$IT$`Go agile`$isRoot, FALSE)\n})\n\n\ntest_that(\"count\", {\n  expect_equal(acme$count, 3)\n})\n\ntest_that(\"totalCount\", {\n  \n  expect_equal(acme$totalCount, 11)\n})\n\ntest_that(\"Climb\", {\n  \n  \n  node <- Climb(acme, \"Accounting\", \"New Accounting Standards\")\n  expect_equal(node$name, \"New Accounting Standards\")\n  \n  node <- Climb(acme, \"Not existing node\")\n  expect_equal(node, NULL)\n  \n})\n\ntest_that(\"isLeaf\", {\n  \n  node <- Climb(acme, \"Accounting\", \"New Accounting Standards\")\n  expect_equal(node$isLeaf, TRUE)\n  \n})\n\n\ntest_that(\"level\", {\n  \n  expect_equal(acme$isLeaf, FALSE)\n  \n  accounting <- Climb(acme, \"Accounting\")\n  expect_equal(accounting$isLeaf, FALSE)\n  \n  node <- accounting$Climb(\"New Accounting Standards\")\n  expect_equal(node$isLeaf, TRUE)\n  \n})\n\n\n\n\n"
  },
  {
    "path": "tests/testthat/test-treeConversionApe.R",
    "content": "context(\"tree conversion ape\")\n\n\ntest_that(\"as.Node.phylo owls\", {\n  skip_if_not_installed(\"ape\")\n  txt <- \"owls(((Strix_aluco:4.2,Asio_otus:4.2):3.1,Athene_noctua:7.3):6.3,Tyto_alba:13.5);\"\n\n  p <- ape::read.tree(text = txt)\n  n <- as.Node(p, replaceUnderscore = F)\n  expect_equal(n$totalCount, 7)\n  expect_equal(as.vector(n$Get(\"name\")), c(\"5\", \"6\", \"7\", \"Strix_aluco\", \"Asio_otus\", \"Athene_noctua\", \"Tyto_alba\"))\n  expect_equal(as.vector(n$Get(\"level\")), c(1, 2, 3, 4, 4, 3, 2))\n  \n})\n\ntest_that(\"as.Node.phylo height\", {\n  skip_if_not_installed(\"ape\")\n  txt <- \"(A:5,B:5,(C:10,D:10)E:5):0;\"\n  \n  p <- ape::read.tree(text = txt)\n  n <- as.Node(p)\n  expect_equal(n$totalCount, 6)\n  expect_equal(as.vector(n$Get(\"name\")), c(\"\", \"A\", \"B\", \"E\", \"C\", \"D\"))\n  expect_equal(as.vector(n$Get(\"level\")), c(1, 2, 2, 2, 3, 3))\n  expect_equal(as.vector(n$Get(\"plotHeight\")), c(15, 10, 10, 10, 0, 0))\n})\n\ntest_that(\"as.Node.phylo no height\", {\n  skip_if_not_installed(\"ape\")\n  txt <- \"(A,B,(C,D)E)F;\"\n  \n  p <- ape::read.tree(text = txt)\n  n <- as.Node(p)\n  expect_equal(n$totalCount, 6)\n  expect_equal(as.vector(n$Get(\"name\")), c(\"F\", \"A\", \"B\", \"E\", \"C\", \"D\"))\n  expect_equal(as.vector(n$Get(\"level\")), c(1, 2, 2, 2, 3, 3))\n  expect_true(all(is.na(n$Get(\"edgeLength\"))))\n})\n\n\n\ntest_that(\"as.Node.phylo height non standard\", {\n  skip_if_not_installed(\"ape\")\n  txt <- \"(A:5,B:5,(C:10,D:10):5):0;\"\n  \n  p <- ape::read.tree(text = txt)\n  n <- as.Node(p, heightName = \"edge\")\n  expect_equal(n$totalCount, 6)\n  expect_equal(as.vector(n$Get(\"name\")), c(\"5\", \"A\", \"B\", \"6\", \"C\", \"D\"))\n  expect_equal(as.vector(n$Get(\"level\")), c(1, 2, 2, 2, 3, 3))\n  expect_equal(as.vector(n$Get(\"edge\")), c(15, 10, 10, 10, 0, 0))\n})\n\n\n\ntest_that(\"as.phylo.Node heightAttributeName\", {\n  skip_if_not_installed(\"ape\")\n\n  data(acme)\n  #needs explicit generics as library ape is not loaded\n  p <- as.phylo.Node(acme)\n  n <- as.Node(p)\n  \n  expect_equal(n$Get(\"name\"), acme$Get(\"name\"))\n  \n})\n\n\ntest_that(\"as.phylo.Node heightAttributeName\", {\n  skip_if_not_installed(\"ape\")\n  \n  data(acme)\n  height <- function(x) x$edgeHeight <- DefaultPlotHeight(x) + 1\n  acme$Do(height)\n  #needs explicit generics as library ape is not loaded\n  \n  p <- as.phylo.Node(acme, heightAttributeName = \"edgeHeight\")\n  n <- as.Node(p)\n  \n  expect_equal(n$Get(\"name\"), acme$Get(\"name\"))\n  gh <- function(x) {\n    if (x$isRoot) {\n      x$edgeHeight <- 0\n      return()\n    }\n    if (x$parent$isRoot) ph <- 0\n    else ph <- x$parent$edgeLength\n    x$edgeHeight <- x$edgeLength - ph\n  }\n  n$Do(gh)\n  expect_equal(n$Get(\"edgeLength\"), acme$Get(\"edgeLength\"))\n  \n})\n\n\ntest_that(\"GetPhyloNumber node\", {\n  data(acme)\n  acme$Do(function(x) x$phyloNr <- GetPhyloNr(x, \"node\"))\n  expect_equal(as.vector(acme$Get(\"phyloNr\")), c(8,9,1,2,10,3,4,11,5,6,7))\n})\n\ntest_that(\"GetPhyloNumber edge\", {\n  data(acme)\n  acme$Do(function(x) x$phyloNr <- GetPhyloNr(x, \"edge\"), filterFun = isNotRoot)\n  expect_equal(as.vector(acme$Get(\"phyloNr\")), c(NA, 1:10))\n})\n"
  },
  {
    "path": "tests/testthat/test-treeConversionDataFrame.R",
    "content": "context(\"tree conversion data.frame\")\n\ndata(acme)\n\n\n\ntest_that(\"as.Node.data.frame\", {\n  data(acme)\n  acmedf <- as.data.frame(acme, row.names = NULL, optional = FALSE, 'p', 'cost', 'pathString')\n  acme2 <- as.Node(acmedf, na.rm = TRUE)\n  expect_equal(as.list(acme), as.list(acme2))\n  expect_true(is.null(acme2$children[[1]]$p))\n  expect_equal(as.data.frame(acme, row.names = NULL, optional = FALSE, 'p', 'cost'), as.data.frame(acme2, row.names = NULL, optional = FALSE, 'p', 'cost'))\n  #test that if they are not different it fails\n  # acc2 <- acme2$Climb(\"Accounting\")\n  # acc2$newField <- 'new value'\n  # expect_equal(as.list(acme), as.list(acme2))\n  \n})\n\n\ntest_that(\"FromDataFrameTable no extra column\", {\n  \n  pathString <- c(\"a/b/c/d\", \"a/b/c/e\", \"a/f\")\n\n  \n  df <- data.frame(pathString)\n  tree <- FromDataFrameTable(df)\n\n  expect_equal(Get(tree$leaves, \"name\"), c(d = \"d\", e = \"e\", f = \"f\"))\n  \n})\n\n\ntest_that(\"FromDataFrameTable reserved words\", {\n\n  pathString <- c(\"a/b/c/d\", \"a/b/c/e\", \"a/f\")\n  value <- c(\"d\", \"e\", \"f\")\n  \n  df <- data.frame(pathString, value, stringsAsFactors = FALSE)\n\n  #no warn\n  expect_warning(tree <- FromDataFrameTable(df, na.rm = TRUE), NA)\n  expect_equal(Get(tree$leaves, \"value\"), c(d = \"d\", e = \"e\", f = \"f\"))\n  \n  expect_warning(tree <- FromDataFrameTable(df, na.rm = TRUE, check = \"no-warn\"), NA)\n  expect_equal(Get(tree$leaves, \"value\"), c(d = \"d\", e = \"e\", f = \"f\"))\n\n  #reserved words\n  pathString <- c(\"name/path/height/count\", \"name/path/height/e\", \"name/leaves\")\n  value <- c(\"d\", \"e\", \"f\")\n  df <- data.frame(pathString, value, stringsAsFactors = FALSE)\n  expect_that(tree <- FromDataFrameTable(df, na.rm = TRUE), gives_warning())\n  expect_equal(Get(tree$leaves, \"value\"), c(count2 = \"d\", e = \"e\", leaves2 = \"f\"))\n  \n  df <- data.frame(pathString, value, stringsAsFactors = FALSE)\n  expect_warning(tree <- FromDataFrameTable(df, na.rm = TRUE, check = \"no-warn\"), NA)\n  expect_equal(Get(tree$leaves, \"value\"), c(count2 = \"d\", e = \"e\", leaves2 = \"f\"))\n  \n\n})\n\n\ntest_that(\"FromDataFrameNetwork reserved words\", {\n  \n  parent <- c(\"a\", \"a\", \"b\", \"c\", \"c\")\n  child <- c(\"b\", \"f\", \"c\", \"d\", \"e\")\n  value <- c(0:4)\n  \n  network_df <- data.frame(parent, child, value, stringsAsFactors = FALSE)\n  \n  #no warn\n  expect_warning(tree <- FromDataFrameNetwork(network_df), regexp = NA)\n  \n  #reserved words\n  parent <- c(\"a\", \"a\", \"b\", \"c\", \"c\")\n  child <- c(\"b\", \"f\", \"c\", \"d\", \"e\")\n  name <- c(0:4)\n  network_df <- data.frame(parent, child, name, stringsAsFactors = FALSE)\n  expect_that(tree <- FromDataFrameNetwork(network_df), gives_warning())\n  expect_warning(tree <- FromDataFrameNetwork(network_df, check = \"no-warn\"), NA)\n})\n\n\ntest_that(\"as.data.frame.Node\", {\n  data(acme)\n  acmedf <- as.data.frame(acme, \n                          row.names = NULL, \n                          optional = FALSE, \n                          myp = 'p', \n                          'cost', \n                          pstr = function(x) x$pathString,\n                          sg = acme$Get( function(x) x$p)\n                          )\n  expect_equal(names(acmedf), c(\"levelName\", \"myp\", \"cost\", \"pstr\", \"sg\"))\n  expect_equal(acmedf[2, 4], \"Acme Inc./Accounting\")\n  expect_equal(acmedf$sg, acmedf$sg)\n})\n\ntest_that(\"as.data.frame.Node list attributes\", {\n  data(acme)\n  acme$Set(data      = list(list(list(a = 1, b = \"a\"))), filterFun = isLeaf)\n  acme$Set(data      = list(list(list(b = \"c\"))), \n           filterFun = function(n) isNotLeaf(n) && isNotRoot(n))\n  expect_identical(as.data.frame(acme, data = \"data\")$data,\n                   c(NA, \"c\", \"1, a\", \"1, a\", \"c\", \"1, a\", \"1, a\", \"c\", \"1, a\", \n                     \"1, a\", \"1, a\"))\n})\n\n\ntest_that(\"ToDataFrameTable\", {\n  data(acme)\n  acme$myfield <- \"yes\"\n  acmedf <- ToDataFrameTable(acme, myp = \"p\", \"cost\", \"myfield\", pstr = function(x) x$pathString)\n  expect_equal(names(acmedf), c(\"myp\", \"cost\", \"myfield\", \"pstr\"))\n  expect_equal(acmedf[2, 4], \"Acme Inc./Accounting/New Accounting Standards\")\n  expect_equal(nrow(acmedf), acme$leafCount)\n  expect_true(all(acmedf$myfield == \"yes\"))\n})\n\n\n\n\ntest_that(\"ToDataFrameNetwork climb\", {\n  data(acme)\n  acmedf <- ToDataFrameNetwork(acme, \"p\", direction = \"climb\")\n  expect_equal(names(acmedf), c(\"from\", \"to\", \"p\"))\n  expect_equal(acmedf$to, c(\"Accounting\", \"Research\", \"IT\", \"New Software\", \"New Accounting Standards\", \"New Product Line\", \"New Labs\", \"Outsource\", \"Go agile\", \"Switch to R\"))\n  expect_equal(acmedf$from, c(\"Acme Inc.\", \"Acme Inc.\", \"Acme Inc.\", \"Accounting\", \"Accounting\", \"Research\", \"Research\", \"IT\", \"IT\", \"IT\"))\n})\n\n\ntest_that(\"ToDataFrameNetwork descend\", {\n  data(acme)\n  acmedf <- ToDataFrameNetwork(acme, \"p\", direction = \"descend\")\n  expect_equal(names(acmedf), c(\"from\", \"to\", \"p\"))\n  expect_equal(acmedf$from, c(\"Accounting\", \"Research\", \"IT\", \"New Software\", \"New Accounting Standards\", \"New Product Line\", \"New Labs\", \"Outsource\", \"Go agile\", \"Switch to R\"))\n  expect_equal(acmedf$to, c(\"Acme Inc.\", \"Acme Inc.\", \"Acme Inc.\", \"Accounting\", \"Accounting\", \"Research\", \"Research\", \"IT\", \"IT\", \"IT\"))\n})\n\n\n\n\ntest_that(\"ToDataFrame sub-tree\", {\n  data(acme)\n  it <- acme$Climb(\"IT\")\n  df <- ToDataFrameTree(it)\n  expect_equal(dim(df), c(4, 1))\n  expect_equal(stri_sub(df[1, 1], 1, 2), 'IT')  \n})\n\n\ntest_that(\"ToDataFrameTypeCol level\", {\n  data(acme)\n  acme$IT$Outsource$AddChild(\"India\")\n  acme$IT$Outsource$AddChild(\"Poland\")\n  \n  acmedf <- ToDataFrameTypeCol(acme)\n  expect_equal(names(acmedf), c('level_1', 'level_2', 'level_3', 'level_4'))\n  expect_true( all(acmedf$level_1 == 'Acme Inc.'))\n  expect_equal(acmedf$level_2, c('Accounting', 'Accounting', 'Research', 'Research', 'IT', 'IT', 'IT', 'IT'))\n  expect_equal(acmedf$level_3, c('New Software', 'New Accounting Standards', 'New Product Line', 'New Labs', 'Outsource', 'Outsource', 'Go agile', 'Switch to R'))\n  expect_equal(acmedf$level_4, c(NA, NA, NA, NA, 'India', 'Poland', NA, NA))  \n})\n\ntest_that(\"ToDataFrameTypeCol type\", {\n  data(acme)\n  acme$IT$Outsource$AddChild(\"India\")\n  acme$IT$Outsource$AddChild(\"Poland\")\n  acme$Set(type = c('company', 'department', 'project', 'project', 'department', 'project', 'project', 'department', 'program', 'project', 'project', 'project', 'project'))\n  \n  acmedf <- ToDataFrameTypeCol(acme, type = 'type', prefix = NULL)\n  expect_equal(names(acmedf), c('company', 'department', 'program', 'project'))\n  expect_true( all(acmedf$company == 'Acme Inc.'))\n  expect_equal(acmedf$department, c('Accounting', 'Accounting', 'Research', 'Research', 'IT', 'IT', 'IT', 'IT'))\n  expect_equal(acmedf$program, c(NA, NA, NA, NA, 'Outsource', 'Outsource', NA, NA))  \n  expect_equal(acmedf$project, c('New Software', 'New Accounting Standards', 'New Product Line', 'New Labs', 'India', 'Poland', 'Go agile', 'Switch to R'))\n})\n\n\ntest_that(\"FromDataFrameTable col-levels\", {\n  data(acme)\n  acme$Set(floor = c(1, 2, 3),  filterFun = function(x) x$level == 2)\n  x <- ToDataFrameTable(acme, \"pathString\", \"floor\", \"p\", \"cost\") \n  xN <- FromDataFrameTable(x, colLevels = list(NULL, \"floor\", c(\"p\", \"cost\")), na.rm = TRUE)\n  expect_equal(xN$Climb(\"Accounting\")$floor, 1)\n  expect_true(is.null(xN$Climb(\"Accounting\", \"New Accounting Standards\")$floor))\n  expect_true(is.null(xN$floor))\n  expect_equal(xN$Climb(\"Accounting\", \"New Accounting Standards\")$p, 0.75)\n  \n})\n\ntest_that(\"FromDataFrameNetwork descend\", {\n  data(acme)\n  x <- ToDataFrameNetwork(acme, \"p\", \"cost\", direction = \"descend\")\n  xN <- FromDataFrameNetwork(x)\n  expect_equal(xN$totalCount, acme$totalCount)\n  expect_equal(xN$Get(\"name\"), acme$Get(\"name\"))\n  expect_equal(xN$Get(\"p\"), acme$Get(\"p\"))\n  expect_equal(xN$height, acme$height)\n  expect_equal(xN$Get(\"level\"), acme$Get(\"level\"))\n  expect_equal(xN$Get(function(x) x$parent$name), acme$Get(function(x) x$parent$name))\n  expect_equal(xN$Get(\"isLeaf\"), acme$Get(\"isLeaf\"))\n})\n\n\ntest_that(\"FromDataFrameNetwork climb\", {\n  data(acme)\n  x <- ToDataFrameNetwork(acme, \"p\", \"cost\", direction = \"climb\")\n  xN <- FromDataFrameNetwork(x)\n  expect_equal(xN$totalCount, acme$totalCount)\n  expect_equal(xN$Get(\"name\"), acme$Get(\"name\"))\n  expect_equal(xN$Get(\"p\"), acme$Get(\"p\"))\n  expect_equal(xN$height, acme$height)\n  expect_equal(xN$Get(\"level\"), acme$Get(\"level\"))\n  expect_equal(xN$Get(function(x) x$parent$name), acme$Get(function(x) x$parent$name))\n  expect_equal(xN$Get(\"isLeaf\"), acme$Get(\"isLeaf\"))\n})\n\n\ntest_that(\"FromDataFrameNetwork order\", {\n  data(acme)\n  x <- ToDataFrameNetwork(acme, \"p\", \"cost\")\n  odr <- c(4, 1, 6, 8, 9, 10, 2, 7, 5, 3)\n  x <- x[odr, ]\n  xN <- FromDataFrameNetwork(x)\n  expect_equal(xN$Get(\"name\"), acme$Get(\"name\"))\n\n  x <- x[, c('to', 'from', 'p', 'cost')]\n  xN <- FromDataFrameNetwork(x)\n  expect_equal(xN$Get(\"name\"), acme$Get(\"name\"))\n  \n})\n\n\n\n\n\n"
  },
  {
    "path": "tests/testthat/test-treeConversionDendrogram.R",
    "content": "context(\"tree conversion dendrogram\")\n\n\ntest_that(\"as.Node.dendrogram\", {\n  hc <- hclust(dist(USArrests), \"ave\")\n  dend1 <- as.dendrogram(hc)\n  root <- as.Node(dend1)\n  expect_equal(root$totalCount, 99)\n  expect_true(root$isBinary)\n})\n\n\ntest_that(\"as.dendrogram.Node\", {\n  data(acme)\n  acmed <- as.dendrogram(acme)\n  expect_equal(class(acmed), \"dendrogram\")\n  expect_equal(nobs(acmed), acme$leafCount)\n  expect_equal(attr(acmed, \"height\"), 100)\n})\n\n"
  },
  {
    "path": "tests/testthat/test-treeConversionList.R",
    "content": "context(\"tree conversion\")\n\ndata(acme)\n\ntest_that(\"as.list.Node explicit\", {\n  data(acme)\n  \n  l <- as.list(acme, mode = \"explicit\")\n    \n  expect_equal(\"list\", class(l))\n  expect_equal(2, length(l))\n  expect_equal(c('name', 'children'), names(l))\n  expect_equal(c('children'), names(l$children$Research))\n  expect_equal(0.9, l$children$Research$children$`New Labs`$p)\n \n})\n\n\ntest_that(\"as.list.Node explicit nameName=name\", {\n  data(acme)\n  \n  l <- as.list(acme, mode = \"explicit\", nameName = 'name')\n  \n  expect_equal(class(l), \"list\")\n  expect_equal(length(l), 2)\n  expect_equal(names(l), c('name', 'children'))\n  expect_equal(names(l$children$Research), c('name', 'children'))\n  expect_equal(l$children$Research$children$`New Labs`$p, 0.9)\n  \n})\n\ntest_that(\"as.list.Node explicit nameName=id\", {\n  data(acme)\n  \n  l <- as.list(acme, mode = \"explicit\", nameName = 'id')\n  \n  expect_equal(class(l), \"list\")\n  expect_equal(length(l), 2)\n  expect_equal(names(l), c('id', 'children'))\n  expect_equal(names(l$children$Research), c('id', 'children'))\n  expect_equal(l$children$Research$children$`New Labs`$p, 0.9)\n  \n})\n\n\ntest_that(\"as.list.Node simple\", {\n  \n  data(acme)\n  l <- as.list(acme)\n  \n  expect_equal(\"list\", class(l))\n  expect_equal(length(l), 4)\n  expect_equal(names(l), c(\"name\", \"Accounting\", \"Research\", \"IT\"))\n  expect_equal(names(l$Research), c(\"New Product Line\", \"New Labs\" ))\n  expect_equal(0.9, l$Research$`New Labs`$p)\n  \n})\n\ntest_that(\"as.list.Node simple unname no effect\", {\n  \n  data(acme)\n  l <- as.list(acme)\n  \n  expect_equal(\"list\", class(l))\n  expect_equal(length(l), 4)\n  expect_equal(names(l), c(\"name\", \"Accounting\", \"Research\", \"IT\"))\n  expect_equal(names(l$Research), c(\"New Product Line\", \"New Labs\" ))\n  expect_equal(0.9, l$Research$`New Labs`$p)\n  \n})\n\n\ntest_that(\"as.list.Node simple nameName=name\", {\n  \n  data(acme)\n  l <- as.list(acme, nameName = 'name')\n  \n  expect_equal(\"list\", class(l))\n  expect_equal(length(l), 4)\n  expect_equal(names(l), c('name', \"Accounting\", \"Research\", \"IT\"))\n  expect_equal(names(l$Research), c(\"name\", \"New Product Line\", \"New Labs\" ))\n  expect_equal(0.9, l$Research$`New Labs`$p)\n  \n})\n\ntest_that(\"as.list.Node simple keepOnly=p\", {\n  \n  data(acme)\n  l <- as.list(acme, keepOnly = 'p')\n  \n  expect_equal(\"list\", class(l))\n  expect_equal(length(l), 4)\n  expect_equal(names(l), c('name', \"Accounting\", \"Research\", \"IT\"))\n  expect_equal(names(l$Research), c(\"New Product Line\", \"New Labs\" ))\n  expect_equal(0.9, l$Research$`New Labs`$p)\n  expect_null(l$Research$`New Labs`$cost)\n  \n})\n\ntest_that(\"as.list.Node explicit nameName=id\", {\n  \n  \n  l <- as.list(acme, nameName = 'id')\n  \n  expect_equal(\"list\", class(l))\n  expect_equal(length(l), 4)\n  expect_equal(names(l), c('id', \"Accounting\", \"Research\", \"IT\"))\n  expect_equal(names(l$Research), c(\"id\", \"New Product Line\", \"New Labs\" ))\n  expect_equal(0.9, l$Research$`New Labs`$p)\n  \n})\n\n\ntest_that(\"as.Node.list\", {\n  data(acme)\n  n <- as.Node(as.list(acme))\n  \n  expect_equal(\"Acme Inc.\", n$name)\n  expect_equal(3, n$count)\n  expect_equal(11, n$totalCount)\n  expect_equal(0.05, n$Climb(\"IT\", \"Go agile\")$p)\n  \n})\n\n\ntest_that(\"as.list.Node unname\", {\n  data(acme)\n  l <- as.list(acme, mode = \"explicit\", unname = TRUE, nameName = 'id', childrenName = 'sub')\n  \n  expect_equal(\"list\", class(l))\n  expect_equal(2, length(l))\n  expect_equal(c('id', 'sub'), names(l))\n  expect_equal(0.9, l$sub[[2]]$sub[[2]]$p)\n  expect_equal('New Product Line', l$sub[[2]]$sub[[1]]$id)\n  \n})\n\ntest_that(\"as.Node.list unname with mode = simple\", {\n  \n  l <- as.list(acme, unname = TRUE, nameName = 'id', childrenName = 'sub')\n  n <- as.Node(l, nameName = 'id', childrenName = 'sub')\n  \n  expect_equal(\"Acme Inc.\", n$name)\n  expect_equal(3, n$count)\n  expect_equal(11, n$totalCount)\n  expect_equal(0.05, n$Climb(\"IT\", \"Go agile\")$p)\n  \n})\n\n\ntest_that(\"as.Node.list auto\", {\n  \n  lol <- list(type = \"Root\", list(type = \"Rule\", value = 1), list(type = \"Rule\", value = 2))\n  tree <- FromListSimple(lol, nameName = NULL, nodeName = 1)\n  \n  expect_equal(tree$totalCount, 3)\n  expect_equal(unname(tree$Get(\"name\")), as.character(c(1, 1, 2)))\n  expect_equal(tree$children[[1]]$type, \"Rule\")\n  \n})\n\n\ntest_that(\"as.Node.list warning\", {\n  \n  lol <- list(type = \"Root\", list(type = \"Rule\", count = 1), list(type = \"Rule\", count = 2))\n  #tree <- FromListSimple(lol, nameName = NULL, nodeName = 1)\n  tree <- NULL\n  expect_warning(FromListSimple(lol, nameName = NULL, nodeName = 1, check = \"no-warn\"), NA)\n  expect_that(tree <- FromListSimple(lol, nameName = NULL, nodeName = 1), gives_warning())\n  \n  expect_equal(tree$totalCount, 3)\n  expect_equal(unname(tree$Get(\"name\")), as.character(c(1, 1, 2)))\n  \n  expect_equal(unname(tree$Get(\"count\")), c(2,0,0))\n  expect_equal(unname(tree$Get(\"count2\")), c(NA, 1, 2))\n  \n  expect_warning(FromListSimple(lol, nameName = NULL, nodeName = 1, check = \"no-check\"), NA)\n  expect_that(tree <- FromListSimple(lol, nameName = NULL, nodeName = 1), gives_warning())\n  \n  \n})\n\n\n\ntest_that(\"as.Node.list string\", {\n  \n  \n  \n  \n  yaml <- \"\nchildren:\n  CR:\n    description: Currencies\n    type: Currency\n    children:\n      CR_CHF: market\n      CR_EUR: market\n      CR_USD: market\n\"\n  \n  lol <- yaml::yaml.load(yaml)\n  \n  tree <- FromListExplicit(lol)\n  expect_equal(tree$totalCount, 5)\n  expect_equal(tree$height, 3)\n  expect_equal(tree$CR$CR_CHF$name, \"CR_CHF\")\n  \n  #market is numbered (1) instead of lost:\n  expect_equal(tree$attributesAll, c(\"description\", \"type\", \"1\"))\n  \n  \n  \n})\n\n\n\ntest_that(\"as.Node.list string 2\", {\n  \n\n  yaml <- \"\nchildren:\n  CR:\n    description: Currencies\n    type: Currency\n    children:\n      - CR_CHF\n      - CR_EUR\n      - CR_USD\n\"\n  \n  lol <- yaml::yaml.load(yaml)\n  \n  tree <- FromListExplicit(lol)\n  expect_equal(tree$totalCount, 5)\n  expect_equal(tree$height, 3)\n  expect_equal(tree$CR$CR_CHF$name, \"CR_CHF\")\n  \n  \n  \n})\n\n\ntest_that(\"as.Node.list string NULL\", {\n  \n  \n  \n  \n  yaml <- \"\nname: OS Students 2014/15\nOS X:\n  Yosemite:\n  Leopard:\nLinux:\n  Debian:\n    version: 9\n  Ubuntu:\nWindows:\n  W7:\n  W8:\n  W10:\n\"\n  \n  lol <- yaml::yaml.load(yaml)\n  \n  tree <- FromListSimple(lol, interpretNullAsList = TRUE)\n  expect_equal(tree$totalCount, 11)\n  expect_equal(tree$height, 3)\n  expect_equal(tree$Linux$Debian$name, \"Debian\")\n  expect_equal(tree$Linux$Debian$version, 9)\n\n\n})\n\n\ntest_that(\"as.Node.list empty list()\", {\n  lol = list(a = list(aa=1), b=\"hello\", c = list())\n  tree = FromListSimple(lol)\n  expect_equal(tree$totalCount, 3)\n  expect_equal(tree$height, 2)\n  expect_equal(tree$c$count, 0)\n  expect_equal(tree$c$attributes, character(0))\n})\n\n\ntest_that(\"as.Node.list with empty attributes\", {\n  lol = list(a = list(aa=1), \"hello\", c = list(), 1, d=2, list(e=4))\n  tree = FromListSimple(lol)\n  expect_equal(length(tree$attributes), 3)\n  expect_equal(tree$count, 3)\n  expect_true(all(c(1, 2) %in% tree$attributes))\n})\n\n\n\n\ntest_that(\"as.list.Node prune\", {\n  data(acme)\n  \n  l <- ToListExplicit(acme, pruneFun = function(node) node$name != 'Research')\n  \n  expect_equal(\"list\", class(l))\n  expect_equal(2, length(l$children))\n  expect_equal(c('Accounting', 'IT'), names(l$children))\n\n})\n\ntest_that(\"as.list.Node prune\", {\n  data(acme)\n  \n  l <- as.list(acme, pruneFun = function(node) node$name != 'Outsource')\n  \n  expect_equal(\"list\", class(l))\n  expect_equal(c('Go agile', 'Switch to R'), names(l$IT))\n  \n})\n"
  },
  {
    "path": "tests/testthat/test-treeConversionParty.R",
    "content": "context(\"tree conversion party\")\n\n\ntest_that(\"party on\", {\n  skip_if_not_installed(\"party\")\n\n  airq <- subset(airquality, !is.na(Ozone))\n  airct <- party::ctree(Ozone ~ ., data = airq, \n                        controls = party::ctree_control(maxsurrogate = 3))\n  \n  tree <- as.Node(airct)\n  \n  res <- as.numeric(unname(tree$Get(\"name\")))\n  \n  expect_equal(res, 1:9)\n  \n  res <- tree$Get(\"label\")\n  \n  exp <- c(`1` = \"Temp <= 82\",\n          `2` = \"Wind <= 6.9\",\n          `3` = \"weights = 10\",\n          `4` = \"Temp > 77\",\n          `5` = \"weights = 48\",\n          `6` = \"weights = 21\",\n          `7` = \"Wind > 10.3\",\n          `8` = \"weights = 30\",\n          `9` = \"weights = 7\" )\n  \n  expect_equal(res, exp)\n\n})\n\n\n\ntest_that(\"partykid\", {\n  skip_if_not_installed(\"party\")\n  #hack but needed, otherwise extree_data cannot be found\n  library(partykit)\n  airq <- subset(airquality, !is.na(Ozone))\n  airct <- partykit::ctree(Ozone ~ ., data = airq)\n  \n  tree <- as.Node(airct)\n  \n  res <- as.numeric(unname(tree$Get(\"name\")))\n  \n  expect_equal(res, 1:9)\n  \n  res <- tree$Get(\"splitname\")\n  \n  exp <- c(`1` = \"Temp\",\n           `2` = \"Wind\",\n           `3` = NA,\n           `4` = \"Temp\",\n           `5` = NA,\n           `6` = NA,\n           `7` = \"Wind\",\n           `8` = NA,\n           `9` = NA )\n  \n  expect_equal(res, exp)\n  \n  res <- tree$Get(\"splitLevel\")\n  \n  exp <- c(`1` = NA,\n           `2` = \"<= 82\",\n           `3` = \"<= 6.9\",\n           `4` = \"> 6.9\",\n           `5` = \"<= 77\",\n           `6` = \"> 77\",\n           `7` = \"> 82\",\n           `8` = \"<= 10.3\",\n           `9` = \"> 10.3\")\n  \n  expect_equal(res, exp)\n  \n})\n"
  },
  {
    "path": "tests/testthat/test-treeConversionRpart.R",
    "content": "context(\"tree conversion rpart\")\n\ntest_that(\"Conversion from rpart\", {\n  skip_if_not_installed(\"rpart\")\n\n  fit  <- rpart::rpart(Kyphosis ~ Age + Number + Start, data = rpart::kyphosis)\n  tree <- as.Node(fit)\n  expect_equal(tree$totalCount,\n               NROW(fit$frame))\n  expect_true(tree$isBinary)\n  expect_equal(tree$leafCount, \n               sum(fit$frame$var == \"<leaf>\"))\n  expect_true(all(tree$Get(\"name\", filterFun = isNotLeaf) %in% labels(fit)))\n  expect_equivalent(tree$Get(\"rpart.id\"), \n                    as.numeric(rownames(fit$frame)))\n})\n"
  },
  {
    "path": "tests/testthat/test-treeConversionigraph.R",
    "content": "context(\"tree conversion igraph\")\n\n\ntest_that(\"as.Node.igraph undirected\", {\n  skip_if_not_installed(\"igraph\")\n\n  data(acme)\n  ig <- as.igraph.Node(acme, \"p\", c(\"level\", \"isLeaf\"), directed = FALSE)\n  #expect_true(is_hierarchical(ig))\n  expect_false(igraph::is_directed(ig))\n  expect_equal(igraph::gsize(ig), acme$totalCount - 1)\n})\n\n\ntest_that(\"as.Node.igraph directed\", {\n  skip_if_not_installed(\"igraph\")\n  data(acme)\n  ig <- as.igraph.Node(acme, \"p\", c(\"level\", \"isLeaf\"), directed = TRUE)\n  #expect_true(is_hierarchical(ig))\n  expect_true(igraph::is_directed(ig))\n  expect_equal(igraph::gsize(ig), acme$totalCount - 1)\n})\n"
  },
  {
    "path": "tests/testthat/test-treeDocu.R",
    "content": "context(\"tree docu method\")\n\n\n\n\n"
  },
  {
    "path": "tests/testthat/test-treeMethods.R",
    "content": "context(\"tree methods\")\n\ntest_that(\"Node instantiation\", {\n  \n  expect_equal(\n    Node$new()$name,\n    \"\",\n    info=\"Confirm default name is an empty string\"\n  )\n  \n  n <- Node$new(\"bla\")\n  expect_equal(n$name, \"bla\")\n\n  n <- Node$new(\"bla\", check = \"check\")\n  expect_equal(n$name, \"bla\")\n\n  n <- Node$new(\"bla\", check = \"no-check\")\n  expect_equal(n$name, \"bla\")\n  \n  n <- Node$new(\"bla\", check = \"no-warn\")\n  expect_equal(n$name, \"bla\")\n  \n  n <- Node$new(\"bla\", check = \"whatever\")\n  expect_equal(n$name, \"bla\")\n  \n  expect_that(n <- Node$new(\"name\"), gives_warning())\n  expect_equal(n$name, \"name2\")\n  \n  expect_that(n <- Node$new(\"name\", check = \"check\"), gives_warning())\n  expect_equal(n$name, \"name2\")\n\n  expect_warning((n <- Node$new(\"name\", check = \"no-check\")), regexp = NA)\n  expect_equal(n$name, \"name\")\n\n  expect_warning(n <- Node$new(\"name\", check = FALSE), regexp = NA)\n  expect_equal(n$name, \"name\")\n  \n  \n  expect_warning(n <- Node$new(\"name\", check = \"no-warn\"), regexp = NA)\n  expect_equal(n$name, \"name2\")\n  \n  expect_that(n <- Node$new(\"name\", check = \"whatever\"), gives_warning())\n  expect_equal(n$name, \"name2\")\n  \n  expect_error(\n    Node$new(NA_character_),\n    regexp=\"Node name must be a non-NA character\"\n  )\n  \n  expect_error(\n    Node$new(c(\"A\", \"B\")),\n    regexp=\"Node name must be a scalar\"\n  )\n\n})\n\ntest_that(\"Climb NULL\", {\n  data(acme)\n  expect_equal(Climb(acme, 'X'), NULL)\n  expect_equal(Climb(acme, 'X', 'Y', 'Z'), NULL)\n  expect_equal(Climb(acme, 'IT', 'X'), NULL)\n \n})\n\n\ntest_that(\"Climb Equivalent\", {\n  data(acme)\n  expect_equal(Climb(acme, 'IT', 'Go agile'), Climb(acme, 'IT')$Climb('Go agile'))\n  \n})\n\n\n\ntest_that(\"Climb 3rd Level\", {\n  data(acme)\n  Climb(acme, 'IT', 'Go agile')$AddChild('MyTest')$AddChild('MyTest2')\n  expect_equal(\"MyTest2\", Climb(acme, 'IT', 'Go agile', 'MyTest', 'MyTest2')$name )\n  expect_equal(\"MyTest2\", Climb(acme, c('IT', 'Go agile', 'MyTest', 'MyTest2'))$name )\n  expect_equal(\"MyTest2\", Climb(acme, name = c('IT', 'Go agile', 'MyTest', 'MyTest2'))$name )\n  \n})\n\n\n\ntest_that(\"Climb non-name\", {\n  tree <- CreateRegularTree(5, 2)\n  p <- tree$Climb(c(\"1.1\", \"1.1.1\"), position = c(2, 2))$path\n  expect_equal(c(\"1\", \"1.1\", \"1.1.1\", \"1.1.1.2\", \"1.1.1.2.2\"), p)\n  \n})\n\n\n\n\ntest_that(\"Find\", {\n  \n  data(acme)\n  os <- FindNode(acme, \"Outsource\")\n  expect_equal(os$name, \"Outsource\")\n  \n  os <- FindNode(acme, \"XYZ\")\n  expect_null(os)\n  \n  acme$Accounting$AddChild(\"Outsource\")\n  os <- FindNode(acme, \"Outsource\")\n  expect_equal(class(os), c(\"Node\", \"R6\"))\n  expect_equal(os$name, \"Outsource\")\n\n})\n\ntest_that(\"Get prune\", {\n  data(acme)\n  acme$Set(myvalue = c(1.3, 1.5, 0.9, 1, 2, 1.1, 0.8, -1, 0.7, 1.0, 1.01))\n  \n  myFilter <- function(x) {\n    return (!is.null(x$myvalue) && x$myvalue > 1)\n  }\n  \n  \n  get <- acme$Get(\"myvalue\", pruneFun = myFilter)\n  #NOTE: 1.01 is filtered out because its parent is -1!\n  exp <- c(1.3, 1.5, 2, 1.1)\n  names(exp) <- c('Acme Inc.', 'Accounting', 'Research', 'New Product Line')\n  \n  expect_equal(get, exp)\n  \n})\n\n\ntest_that(\"Get filter\", {\n  data(acme)\n  acme$Set(myvalue = c(1.3, 1.5, 0.9, 1, 2, 1.1, 0.8, -1, 0.7, 1.0, 1.01))\n  \n  myFilter <- function(x) {\n    return (!is.null(x$myvalue) && x$myvalue > 1)\n  }\n  \n  \n  get <- acme$Get(\"myvalue\", filterFun = myFilter)\n  \n  exp <- c(1.3, 1.5, 2, 1.1, 1.01)\n  names(exp) <- c('Acme Inc.', 'Accounting', 'Research', 'New Product Line', 'Switch to R')\n  \n  expect_equal(get, exp)\n  \n})\n  \n\n\ntest_that(\"Get pre-order\", {\n  data(acme)\n  get <- acme$Get(\"name\", traversal = \"pre-order\")\n  \n  exp <- c('Acme Inc.', \n           'Accounting', \n           'New Software', \n           'New Accounting Standards', \n           'Research', \n           'New Product Line', \n           'New Labs',\n           'IT', \n           'Outsource', \n           'Go agile',\n           'Switch to R' \n           )\n  \n  names(exp) <- exp\n  \n  expect_equal(get, exp)\n  \n})\n\n\ntest_that(\"Get post-order\", {\n  data(acme)\n  get <- acme$Get(\"name\", traversal = \"post-order\")\n  exp <- c('New Software',\n           'New Accounting Standards', \n           'Accounting',\n           'New Product Line', \n           'New Labs', \n           'Research', \n           'Outsource', \n           'Go agile', \n           'Switch to R', \n           'IT', \n           'Acme Inc.')\n  \n  names(exp) <- exp\n  \n  expect_equal(get, exp)\n  \n})\n\n\ntest_that(\"Get ancestor\", {\n  data(acme)\n  get <- Climb(acme, 'Research', 'New Labs')$Get(\"name\", traversal = \"ancestor\")\n  \n  exp <- c('New Labs', \n           'Research', \n           'Acme Inc.')\n  \n  names(exp) <- exp\n  \n  expect_equal(get, exp)\n  \n})\n\n\ntest_that(\"GetAttribute matrix\", {\n  data(acme)\n  acme$IT$matrix <- diag(2)\n  \n  res <- GetAttribute(acme$IT, \"matrix\")\n  \n  expect_equal(acme$IT$matrix, res)\n  \n})\n\n\ntest_that(\"Get format\", {\n  \n  data(acme)\n  \n  calculateAggregateChildCost <- function(node, fun) {\n    if (node$isLeaf) node$averageCost <- node$cost\n    else node$averageCost <- fun(sapply(node$children, function(x) x$averageCost))\n  }\n  \n  myFormat <- function(x) {\n    format(x, nsmall=2, scientific = FALSE)\n  }\n  \n  acme$Do(calculateAggregateChildCost, mean, traversal = \"post-order\")\n  get <- acme$Get(\"averageCost\", format = myFormat)[\"New Product Line\"]\n  \n  expect_equal(as.character(get), \"2000000.00\")\n  \n\n})\n\n\ntest_that(\"Traverse pre-order\", {\n  data(acme)\n  tr <- Traverse(acme, traversal = \"pre-order\")\n  nms <- sapply(tr, function(x) x$name)\n  exp <- c(\"Acme Inc.\",\n           \"Accounting\",\n           \"New Software\",\n           \"New Accounting Standards\",\n           \"Research\",\n           \"New Product Line\",\n           \"New Labs\",\n           \"IT\",\n           \"Outsource\",\n           \"Go agile\",\n           \"Switch to R\")\n  expect_equal(nms, exp)\n  \n})\n\n\ntest_that(\"Traverse post-order\", {\n  data(acme)\n  tr <- Traverse(acme, traversal = \"post-order\")\n  nms <- sapply(tr, function(x) x$name)\n  exp <- c(\"New Software\",             \"New Accounting Standards\", \"Accounting\",               \"New Product Line\",        \n           \"New Labs\",                 \"Research\",                 \"Outsource\",                \"Go agile\",                \n           \"Switch to R\",              \"IT\",                       \"Acme Inc.\"        )\n  expect_equal(nms, exp)\n  \n})\n\n\ntest_that(\"Traverse in-order\", {\n  data(acme)\n  tr <- Traverse(acme, traversal = \"level\")\n  nms <- sapply(tr, function(x) x$name)\n  exp <- c(\"Acme Inc.\",                \"Accounting\",               \"Research\",                 \"IT\",                      \n           \"New Software\",             \"New Accounting Standards\", \"New Product Line\",         \"New Labs\",                \n           \"Outsource\",                \"Go agile\",                 \"Switch to R\"        )\n  expect_equal(nms, exp)\n  \n})\n\n\ntest_that(\"Traverse empty filter\", {\n  data(acme)\n  tr <- Traverse(acme, filterFun = function(x) x$name == \"Marketing\")\n  nms <- sapply(tr, function(x) x$name)\n  exp <- vector(mode = \"list\")\n  expect_equal(nms, exp)\n  \n})\n\n\ntest_that(\"Traverse empty filter level\", {\n  data(acme)\n  tr <- Traverse(acme, traversal = \"level\", filterFun = function(x) x$name == \"Marketing\")\n  nms <- sapply(tr, function(x) x$name)\n  exp <- vector(mode = \"list\")\n  expect_equal(nms, exp)\n  \n})\n\n\n\ntest_that(\"Traverse custom method\", {\n  CustomTraversalFunction <- function(node) {\n    if (node$isLeaf) return (NULL)\n    return (node$children[[1]])\n  }\n  data(acme)\n  tr <- Traverse(acme, traversal = CustomTraversalFunction, filterFun = function(x) x$name != \"Accounting\")\n  nms <- sapply(tr, function(x) x$name)\n  exp <- c(\"Acme Inc.\", \"New Software\")\n  expect_equal(nms, exp)\n  \n})\n\ntest_that(\"Traverse custom method multi\", {\n  CustomTraversalFunction <- function(node) {\n    if (node$isLeaf) return (NULL)\n    return (node$children)\n  }\n  data(acme)\n  tr <- Traverse(acme, traversal = CustomTraversalFunction)\n  tr2 <- Traverse(acme, traversal = \"pre-order\")\n  nms <- sapply(tr, function(x) x$name)\n  nms2 <- sapply(tr2, function(node) node$name)\n  \n  expect_equal(nms, nms2)\n  \n})\n\ntest_that(\"Traverse custom method multi prune\", {\n  CustomTraversalFunction <- function(node) {\n    if (node$isLeaf) return (NULL)\n    return (node$children)\n  }\n  data(acme)\n  tr <- Traverse(acme, traversal = CustomTraversalFunction, pruneFun = function(node) node$name != \"IT\")\n  tr2 <- Traverse(acme, traversal = \"pre-order\", pruneFun = function(node) node$name != \"IT\")\n  nms <- sapply(tr, function(x) x$name)\n  nms2 <- sapply(tr2, function(node) node$name)\n  \n  expect_equal(nms, nms2)\n  \n})\n\n\ntest_that(\"Do\", {\n  \n  data(acme)\n  \n  calculateAggregateChildCost <- function(node, fun) {\n    if (node$isLeaf) return(node$cost)\n    fun(sapply(node$children, function(x) x$averageCost))\n  }\n  \n  myFormat <- function(x) {\n    format(x, nsmall=2, scientific = FALSE)\n  }\n  \n  acme$Do(function(x) x$averageCost <- calculateAggregateChildCost(x, mean), traversal = \"post-order\")\n  get <- acme$Get('averageCost', traversal = \"post-order\")[\"New Product Line\"]\n  \n  \n  expect_equal(as.numeric(get), 2000000)\n  \n  \n})\n\n\n\ntest_that(\"post-order\", {\n  \n  data(acme)\n  \n  acme$Set(myval = 1:acme$totalCount, traversal = \"post-order\")\n  \n  expect_equal(acme$myval, 11)\n  expect_equal(Climb(acme, \"Research\")$myval, 6)\n  \n})\n\n\ntest_that(\"level\", {\n  \n  data(acme)\n  \n  acme$Set(myval = 1:acme$totalCount, traversal = \"level\")\n  \n  expect_equal(acme$myval, 1)\n  expect_equal(Climb(acme, \"Research\")$myval, 3)\n  expect_equal(Climb(acme, \"IT\", \"Go agile\")$myval, 10)\n  \n})\n\n\n\ntest_that(\"level subtree\", {\n  \n  data(acme)\n  it <- Climb(acme, \"IT\")\n  \n  it$Set(myval = 1:it$totalCount, traversal = \"level\")\n  \n  expect_equal(it$myval, 1)\n  expect_equal(it$Climb(\"Outsource\")$myval, 2)\n  expect_equal(it$Climb(\"Go agile\")$myval, 3)\n  expect_equal(it$Climb(\"Switch to R\")$myval, 4)\n  \n})\n\n\ntest_that(\"prune\", {\n  \n  data(acme)\n  \n  acme$Set(myval = 1:8, pruneFun = function(x) x$name != \"Research\")\n  \n  expect_equal(acme$myval, 1)\n  expect_true(is.null(Climb(acme, \"Research\")$myval))\n  expect_true(is.null(Climb(acme, \"Research\", \"New Labs\")$myval))\n  expect_equal(Climb(acme, \"IT\", \"Go agile\")$myval, 7)\n  \n})\n\n\ntest_that(\"filter\", {\n  \n  data(acme)\n  \n  acme$Set(myval = 1:10, filterFun = function(x) x$name != \"Research\")\n  \n  expect_equal(acme$myval, 1)\n  expect_true(is.null(Climb(acme, \"Research\")$myval))\n  expect_equal(Climb(acme, \"Research\", \"New Labs\")$myval, 6)\n  expect_equal(Climb(acme, \"IT\", \"Go agile\")$myval, 9)\n  \n})\n\n\n\n\ntest_that(\"isBinary\", {\n  \n  node <- Node$new(\"0\")\n  \n  addBinChildren <- function(node, n) {\n    for (i in 1:2) {\n      child <- node$AddChild(paste0(node$name, \".\", i))\n      if (n > 0) addBinChildren(child, n-1)\n    }\n  }\n  \n  addBinChildren(node, 3)\n  \n  expect_true(node$isBinary)\n  \n})\n\n\ntest_that(\"in-order\", {\n  \n  node <- Node$new(\"0\")\n  \n  addBinChildren <- function(node, n) {\n    for (i in 1:2) {\n      child <- node$AddChild(paste0(node$name, \".\", i))\n      if (n > 0) addBinChildren(child, n-1)\n    }\n  }\n  \n  addBinChildren(node, 2)\n  \n  #make sure the tree is irregular\n  addBinChildren(node$Climb(\"0.1\", \"0.1.2\", \"0.1.2.1\"), 0)\n  \n  g <- node$Get(\"name\", traversal = \"in-order\")\n  \n  expected <- c(\"0.1.1.1\",\n                \"0.1.1\",\n                \"0.1.1.2\",\n                \"0.1\",\n                \"0.1.2.1.1\",\n                \"0.1.2.1\",\n                \"0.1.2.1.2\",\n                \"0.1.2\",\n                \"0.1.2.2\",\n                \"0\",\n                \"0.2.1.1\",\n                \"0.2.1\",\n                \"0.2.1.2\",\n                \"0.2\",\n                \"0.2.2.1\",\n                \"0.2.2\",\n                \"0.2.2.2\")\n  names(expected) <- expected\n  expect_equal(g, expected)\n  \n})\n\n\ntest_that(\"Set recycling\", {\n  \n  \n    data(acme)\n    Climb(acme, \"Accounting\", \"New Accounting Standards\")$AddChild(\"ICI 320\")\n    acme$Set(myval = 1:6)\n    expect_equal(acme$myval, 1)\n    expect_equal(Climb(acme, \"Research\", \"New Labs\")$myval, 2)\n    expect_equal(Climb(acme, \"IT\", \"Go agile\")$myval, 5)\n       \n})\n\n\n\n\n\ntest_that(\"Aggregate\", {\n  data(acme)\n  expect_equal(Aggregate(acme, \"cost\", sum), 4950000)\n  \n})\n\n\n\n\ntest_that(\"Clone\", {\n  data(acme)\n  n <- Clone(acme)\n  \n  expect_equal(class(n), class(acme))\n  expect_equal(n$name, acme$name)\n  expect_equal(n$count, acme$count)\n  expect_equal(n$totalCount, acme$totalCount)\n  expect_equal(n$Climb(\"IT\", \"Go agile\")$p, Climb(acme, \"IT\", \"Go agile\")$p)\n  \n  expect_equal(as.list(n), as.list(acme))\n  acme2 <- acme\n  expect_identical(acme, acme2)\n  \n  #expect_false(n, is_identical_to(acme))\n  n$name <- 'Acme2'\n  expect_false(n$name == acme$name)\n  \n})\n\ntest_that(\"Clone formatter\", {\n  data(acme)\n  SetFormat(acme, \"count\", FormatFixedDecimal)\n  SetFormat(Climb(acme, \"IT\", \"Outsource\"), \"p\", FormatPercent)\n  \n  n <- Clone(acme, attributes = TRUE)\n  \n  fo <- attr(n, \"formatters\")[[\"count\"]]\n  expect_equal(fo, FormatFixedDecimal)\n\n  fo2 <- attr(n$Climb(\"IT\", \"Outsource\"), \"formatters\")[[\"p\"]]\n  expect_equal(fo2, FormatPercent)\n  \n  \n})\n\n\ntest_that(\"Clone subtree\", {\n  data(acme)\n  it <- Climb(acme, \"IT\")\n  itcl <- Clone(it)\n  \n  expect_equal(class(itcl), class(it))\n  expect_equal(itcl$name, it$name)\n  expect_equal(itcl$count, it$count)\n  expect_equal(itcl$totalCount, it$totalCount)\n  expect_equal(itcl$Climb(\"Go agile\")$p, it$Climb(\"Go agile\")$p)\n  expect_true(itcl$isRoot)\n})\n\n\ntest_that(\"Aggregate\", {\n  data(acme)\n  \n  g <- acme$Get(Aggregate, \"p\", sum)\n  expect_false(is.na(g[1]))\n  expect_equal(3.65, as.vector(g[1]))  \n})\n\n\ntest_that(\"Aggregate function\", {\n  data(acme)\n  \n  g <- acme$Get(Aggregate, function(x) x$p * x$cost, sum)\n  expect_false(is.na(g[1]))\n  \n  expect_equal(g[[1]], sum(acme$Get(function(x) x$cost * x$p, filterFun = isLeaf)))\n\n})\n\n\n\n\n\ntest_that(\"Formatter Get\", {\n  data(acme)\n  SetFormat(acme, \"p\", FormatPercent)\n  p <- acme$Get(\"p\", format = TRUE)\n  expect_equal(p[[\"Go agile\"]], \"5.00 %\")\n})\n\ntest_that(\"Formatter Get Hierarchy\", {\n  data(acme)\n  SetFormat(acme, \"p\", FormatPercent)\n  acme$p <- 1\n  n <- Climb(acme, \"IT\")\n  SetFormat(n, \"p\", FormatFixedDecimal)\n  p <- acme$Get(\"p\", format = TRUE)\n  expect_equal(p[[\"Acme Inc.\"]], \"100.00 %\")\n  expect_equal(p[[\"Outsource\"]], \"0.200\")\n  \n  p <- acme$Get(\"p\", format = FormatFixedDecimal)\n  expect_equal(p[[\"Acme Inc.\"]], \"1.000\")\n\n  p <- acme$Get(\"p\", format = function(x) x)\n  expect_equal(p[[\"Acme Inc.\"]], 1)\n  expect_true(is.numeric(p[[\"Acme Inc.\"]]))\n  expect_equal(p[[\"Outsource\"]], 0.2)\n  \n  \n  \n})\n\n\ntest_that(\"Set matrix\", {\n  \n  data(acme)\n  acme$Set(id = 1:acme$totalCount)\n  ms <- sapply(1:acme$totalCount, function(x) diag(x))\n  acme$Set(matrix = ms)\n  msget <- acme$Get(\"matrix\")\n  expect_equal(unname(acme$Get(\"name\")), names(msget))\n  expect_equal(ms, unname(msget))\n})\n\n\ntest_that(\"Set pre-order\", {\n  data(acme)\n  acme$Set(mycnt = 1:acme$totalCount)\n  expect_equal( Climb(acme, \"IT\")$mycnt, 8)\n})\n\n\ntest_that(\"Set post-order\", {\n  data(acme)\n  acme$Set(mycnt = 1:acme$totalCount, traversal = \"post-order\")\n  expect_equal( Climb(acme, \"IT\")$mycnt, 10)\n  expect_equal( acme$mycnt, 11)\n})\n\n\ntest_that(\"Set filter\", {\n  data(acme)\n  acme$Set(mycnt = 1:3, filterFun = function(x) x$level == 2)\n  expect_equal( Climb(acme, \"IT\")$mycnt, 3)\n  expect_equal( acme$mycnt, NULL)\n})\n\n\n\ntest_that(\"Revert\", {\n  data(acme)\n  acme$Set(id = 1:acme$totalCount)\n  Revert(acme)\n  ids <- unname(acme$Get(\"id\"))\n  expected = c(1, 8, 11, 10, 9, 5, 7, 6, 2, 4, 3)\n  expect_equal(ids, expected)\n})\n\n\ntest_that(\"attributesAll\", {\n  data(acme)\n  fa <- acme$attributesAll\n  expect_equal(fa, c(\"cost\", \"p\"))\n  acme$Set(tta = 1:acme$totalCount)\n  expect_equal(acme$attributesAll, c(\"tta\", \"cost\", \"p\"))\n})\n\n\ntest_that(\"height\", {\n  data(acme)\n  expect_equal(acme$height, 3)\n  expect_equal(Climb(acme, \"IT\")$height, 2)\n  Climb(acme, \"IT\", \"Outsource\")$AddChild(\"New\")\n  \n  expect_equal(acme$height, 4)\n})\n\n\ntest_that(\"isRoot\", {\n  data(acme)\n  expect_true(acme$isRoot)\n  expect_false(Climb(acme, \"IT\")$isRoot)\n  expect_equal(Climb(acme, \"IT\")$height, 2)\n  isRoot <- acme$Get(\"isRoot\")\n  expect_equal(sum(isRoot), 1)\n  \n})\n\n\ntest_that(\"isLeaf\", {\n  data(acme)\n  expect_false(acme$isLeaf)\n  expect_true(Climb(acme, \"Research\", \"New Labs\")$isLeaf)\n  \n  isLeaf <- acme$Get(\"isLeaf\")\n  leaves <- names(isLeaf)[isLeaf]\n  exp <- c(\"New Software\", \"New Accounting Standards\", \"New Product Line\", \"New Labs\", \n           \"Outsource\", \"Go agile\", \"Switch to R\")\n  expect_equal(leaves, exp)\n  \n})\n\n\n\ntest_that(\"level (active)\", {\n  data(acme)\n  expect_equal(acme$level, 1)  \n  expect_equal(Climb(acme, \"Research\")$level, 2)\n  expect_equal(Climb(acme, \"Research\", \"New Labs\")$level, 3)\n  \n})\n\n\ntest_that(\"set name Climb\", {\n  data(acme)\n  rs <- Climb(acme, \"Research\")\n  rs$name <- \"Research2\"\n  \n  rs2 <- Climb(acme, \"Research\")\n  expect_true(is.null(rs2))\n  rs2 <- Climb(acme, \"Research2\")\n  expect_true(rs2$name == \"Research2\")\n  expect_equal(names(rs$parent$children), c(\"Accounting\", \"Research2\", \"IT\"))\n})\n\n\ntest_that(\"change name\", {\n  data(acme)\n#  acme$Research$name <- \"Research2\"\n  \n#  expect_true(is.null(acme$Research))\n\n  rs <- acme$Research\n  rs$name <- \"Research2\"\n  expect_true(is.null(acme$Research))\n  expect_true(acme$Research2$name == \"Research2\")\n})\n\n\ntest_that(\"attribute function with formatter\", {\n  data(acme)\n  SetFormat(acme, \"cost\", FormatFixedDecimal)\n  acme$IT$cost <- function(self) sum(sapply(self$children, function(x) x$cost))\n  mycost <- acme$Get(\"cost\", format = TRUE)\n  expect_equal(mycost[[8]], \"700000.000\")\n  \n})\n\n\ntest_that(\"Remove Child\", {\n  data(acme)\n  sw <- acme$Accounting$RemoveChild(\"New Software\")\n  expect_equal(sw$name, \"New Software\")\n  expect_true(sw$isRoot)\n  expect_equal(acme$Accounting$count, 1)\n  expect_equal(names(acme$Accounting$children), c(\"New Accounting Standards\"))\n})\n\ntest_that(\"Remove Attribute\", {\n  data(acme)\n  acme$Research$floor <- 21\n  expect_true(\"floor\" %in% acme$Research$attributes)\n  acme$Research$RemoveAttribute(\"floor\")\n  expect_false(\"floor\" %in% acme$Research$attributes)\n})\n\n\ntest_that(\"Remove Attribute stop\", {\n  data(acme)\n  acme$Research$floor <- 21\n  expect_true(\"floor\" %in% acme$Research$attributes)\n  expect_true(acme$Research$RemoveAttribute(\"floor\", FALSE))\n  expect_false(\"floor\" %in% acme$Research$attributes)\n  expect_false(acme$IT$RemoveAttribute(\"floor\", FALSE))\n  \n})\n\ntest_that(\"Add Sibling\", {\n  data(acme)\n  acme$Research$AddSibling(\"Marketing\")$AddChild(\"Web\")$AddSibling(\"Print\")\n  expect_equal(acme$Marketing$position, 3)\n  expect_equal(acme$IT$position, 4)\n  expect_equal(acme$Marketing$Web$siblings[[1]]$name, \"Print\")\n})\n\ntest_that(\"print\", {\n  data(acme)\n  acme2 <- print(acme, \"cost\")\n  expect_equal(colnames(acme2), c(\"levelName\", \"cost\"))\n})\n\n\n\ntest_that(\"print list field\", {\n\n  lol = \n    list(a = list(\n      c = list(1:5), \n      b = 2\n    ))\n  tree <- FromListSimple(lol)\n  #expect no error\n  expect_error(do.call(\"print\", c(tree, tree$attributesAll)), NA)\n})\n\n\ntest_that(\"print list field combo\", {\n\n  aNestedTree = \n    list(a = list(\n      b = 5, \n      a = 2\n    ))\n  \n  tree <- FromListSimple(aNestedTree)\n  #expect no error\n  expect_error(print(tree, \"a\"), NA)\n\n})\n\n\ntest_that(\"Cumulate\", {\n  data(acme)\n  acme$Do(function(x) x$cost <- Aggregate(x, \"cost\", sum), traversal = \"post-order\")\n  acme$Do(function(x) x$cumCost <- Cumulate(x, \"cost\", sum))\n  expect_equal(unname(acme$Get(\"cumCost\")),  c(4950000, 1500000, 1000000, 1500000, 4250000, 2000000, 2750000, 4950000, 400000, 650000, 700000))\n})\n\ntest_that(\"averageBranchingFactor\", {\n  t <- CreateRegularTree(3, 3)\n  expect_equal(t$averageBranchingFactor, 3)\n})\n\n\ntest_that(\"siblings\", {\n  data(acme)\n  s <- acme$IT$siblings\n  expect_equal(2, length(s))\n  nms <- unname(Get(s, \"name\"))\n  expect_equal(c(\"Accounting\", \"Research\"), nms)\n  \n})\n\n\ntest_that(\"Distance\", {\n  data(acme)\n  d <- Distance(FindNode(acme, \"Outsource\"), FindNode(acme, \"Research\"))\n  expect_equal(d, 3)\n  d <- Distance(FindNode(acme, \"Outsource\"), acme)\n  expect_equal(d, 2)\n  d <- Distance(acme, FindNode(acme, \"Outsource\"))\n  expect_equal(d, 2)\n  d <- Distance(FindNode(acme, \"Outsource\"), FindNode(acme, \"Outsource\"))\n  expect_equal(d, 0)\n  d <- Distance(FindNode(acme, \"Outsource\"), FindNode(acme, \"Go agile\"))\n  expect_equal(d, 2)\n})\n\ntest_that(\"Distance large tree\", {\n  tree <- CreateRegularTree(6, 2)\n  d <- Distance(FindNode(tree, \"1.2.1.2.2.2\"), FindNode(tree, \"1.2.2.2.2.2\"))\n  expect_equal(d, 8)\n  d <- Distance(FindNode(tree, \"1.2.1.2.2.2\"), FindNode(tree, \"1.1.1.1.1.1\"))\n  expect_equal(d, 10)\n  \n})\n\n\ntest_that(\"leaves\", {\n  data(acme)\n  l <- acme$leaves\n  expect_equal(7, length(l))\n  expect_equal(unname(sapply(l, function(x) x$name)), c(\"New Software\",\n                                                        \"New Accounting Standards\",\n                                                        \"New Product Line\",\n                                                        \"New Labs\",         \n                                                        \"Outsource\",\n                                                        \"Go agile\",\n                                                        \"Switch to R\"))            \n\n  l <- acme$IT$Outsource$leaves\n  expect_equal(typeof(l), \"list\")\n  expect_equal(length(l), 1)\n  \n})"
  },
  {
    "path": "tests/testthat/test-treeMethodsSideEffect.R",
    "content": "context(\"tree methods side effects\")\n\n\n\ntest_that(\"Sort\", {\n  data(acme)\n  acme$Do(function(x) x$totalCost <- Aggregate(x, \"cost\", sum))\n  Sort(acme, \"totalCost\", decreasing = FALSE)\n  get <- acme$Get('totalCost')\n  exp <- c(4950000, 700000, 50000, 250000, 400000, 1500000, 500000, 1000000, 2750000, 750000, 2000000)\n  names(exp) <- c('Acme Inc.',\n                  'IT',\n                  'Switch to R', \n                  'Go agile',\n                  'Outsource',\n                  'Accounting',\n                  'New Accounting Standards',\n                  'New Software',\n                  'Research',\n                  'New Labs',\n                  'New Product Line'\n  )\n  \n  expect_equal(get, exp)\n  \n  Sort(acme, \"totalCost\", decreasing = TRUE)\n  get <- acme$Get('totalCost')\n  \n  expect_false(identical(all.equal(get, exp), TRUE))\n  \n  \n})\n\n\n\ntest_that(\"Prune leaves\", {\n  data(acme)\n  \n  Prune(acme, function(x) is.null(x$cost) || x$cost < 1000000)\n  expect_equal(acme$leafCount, 5)\n  expect_equal(acme$totalCount, 9)\n  expect_true(all(acme$Get(\"cost\", filterFun = isLeaf) < 1000000))\n  \n})\n\n\ntest_that(\"Prune name\", {\n  data(acme)\n  \n  Prune(acme, function(x) x$name != \"IT\")\n  expect_equal(acme$leafCount, 4)\n  expect_equal(acme$totalCount, 7)\n  \n  expect_true(is.null(Climb(acme, \"IT\")))\n  \n})\n\n"
  },
  {
    "path": "tests/testthat/test-util.R",
    "content": "context(\"util\")\n\n\ntest_that(\"createRegular\", {\n  lvls <- 3\n  children <- 4\n  t <- CreateRegularTree(height = 3, branchingFactor = 4)\n  expect_equal(t$leafCount, children ^ (lvls - 1))\n  expect_equal(t$height, lvls)\n  expect_true(all(t$Get(function(x) x$count, filterFun = isNotLeaf) == 4))\n})\n\n\ntest_that(\"createRandomTree\", {\n  t <- CreateRandomTree(nodes = 100)\n  expect_equal(t$totalCount, 101)\n\n})\n\n\n\n\ntest_that(\"PruneDist 1\", {\n  data(acme)\n  acme1 <- data.tree:::PrintPruneDist(acme, limit = 1)\n  expect_equal(acme1$totalCount, 2)\n  expect_equal(acme1$children[[1]]$name, \"... 3 nodes w/ 7 sub\")\n})\n\n\n\n\ntest_that(\"PruneDist 2\", {\n  data(acme)\n  acme1 <- data.tree:::PrintPruneDist(acme, limit = 5)\n  expect_equal(acme1$totalCount, 8)\n  expect_equal(acme1$IT$children[[1]]$name, \"... 3 nodes w/ 0 sub\")\n})\n\ntest_that(\"PruneSimple\", {\n  data(acme)\n  acme1 <- data.tree:::PrintPruneSimple(acme, limit = 5)\n  expect_equal(acme1$totalCount, 5)\n  expect_equal(acme1$children[[2]]$name, \"... 2 nodes w/ 5 sub\")\n})"
  },
  {
    "path": "tests/testthat.R",
    "content": "library(testthat)\n\ntest_check(\"data.tree\")\n#devtools::test()"
  },
  {
    "path": "vignettes/applications.Rmd",
    "content": "---\ntitle: \"data.tree sample applications\"\nauthor: \"Christoph Glur\"\ndate: '`r Sys.Date()`'\noutput:\n  html_document:\n    includes:\n      before_body: applications.banner.html\n    theme: cerulean\n    toc: yes\n    toc_depth: 2\n  word_document: default\n---\n\n<!--\n  %\\VignetteEngine{knitr::rmarkdown}\n  %\\VignetteIndexEntry{Example applications of data.tree}\n  %\\SweaveUTF8\n-->\n\n\n```{r echo=F}\n### get knitr just the way we like it\n\nknitr::opts_chunk$set(\n  message = FALSE,\n  warning = FALSE,\n  error = FALSE,\n  tidy = FALSE,\n  cache = FALSE\n)\n\n```\n\n# Introduction\n\nThis vignette gives you a quick introduction to data.tree applications. We took care to keep the examples simple enough so non-specialists can follow them. The price for this is, obviously, that the examples are often simple compared to real-life applications.\n\nIf you are using data.tree for things not listed here, and if you believe this is of general interest, then please do drop us a note, so we can include your application in a future version of this vignette. \n\n# World PopulationTreeMap (visualization)\n\nThis example is inspired by the examples of the treemap package. \n\nYou'll learn how to\n\n* convert a data.frame to a data.tree structure\n* navigate a tree and locate specific nodes\n* use `Aggregate` and `Cumulate`\n* manipulate an existing tree, e.g. by using the `Prune` method\n\n## Original Example, to be improved\n\nThe original example visualizes the world population as a tree map.\n\n```{r}\nlibrary(treemap)\ndata(GNI2014)\ntreemap(GNI2014,\n       index=c(\"continent\", \"iso3\"),\n       vSize=\"population\",\n       vColor=\"GNI\",\n       type=\"value\")\n```\n\n\nAs there are many countries, the chart gets clustered with many very small boxes.\nIn this example, we will limit the number of countries and sum the remaining population in a catch-all country called \"Other\".\n\nWe use data.tree to do this aggregation.\n\n## Convert from data.frame\n\nFirst, let's convert the population data into a data.tree structure:\n\n```{r}\nlibrary(data.tree)\nGNI2014$continent <- as.character(GNI2014$continent)\nGNI2014$pathString <- paste(\"world\", GNI2014$continent, GNI2014$country, sep = \"/\")\ntree <- as.Node(GNI2014[,])\nprint(tree, pruneMethod = \"dist\", limit = 20)\n```\n\nWe can also navigate the tree to find the population of a specific country. Luckily, RStudio is quite helpful with its code completion (use `CTRL + SPACE`):\n\n```{r}\n\ntree$Europe$Switzerland$population\n\n```\n\n\nOr, we can look at a sub-tree:\n\n```{r}\nnorthAm <- tree$`North America`\nSort(northAm, \"GNI\", decreasing = TRUE)\nprint(northAm, \"iso3\", \"population\", \"GNI\", limit = 12)\n```\n\nOr, we can find out what is the country with the largest GNI:\n\n```{r}\nmaxGNI <- Aggregate(tree, \"GNI\", max)\n#same thing, in a more traditional way:\nmaxGNI <- max(sapply(tree$leaves, function(x) x$GNI))\n\ntree$Get(\"name\", filterFun = function(x) x$isLeaf && x$GNI == maxGNI)\n```\n\n\n## Aggregate and Cumulate\n\nWe aggregate the population. For non-leaves, this will recursively iterate through children, and cache the result in the `population` field. \n\n```{r}\ntree$Do(function(x) {\n        x$population <- Aggregate(node = x,\n        attribute = \"population\",\n        aggFun = sum)\n        }, \n     traversal = \"post-order\")\n```\n\nNext, we sort each node by population:\n\n```{r}\nSort(tree, attribute = \"population\", decreasing = TRUE, recursive = TRUE)\n\n```\n\nFinally, we cumulate among siblings, and store the running sum in an attribute called `cumPop`:\n\n```{r}\ntree$Do(function(x) x$cumPop <- Cumulate(x, \"population\", sum))\n\n```\n\n\n\nThe tree now looks like this:\n\n\n```{r}\nprint(tree, \"population\", \"cumPop\", pruneMethod = \"dist\", limit = 20)\n```\n\n\n## Prune\n\nThe previous steps were done to define our threshold: big countries should be displayed, while small ones should be grouped together. This lets us define a pruning function that will allow a maximum of 7 countries per continent, and that will prune all countries making up less than 90% of a continent's population.\n\nWe would like to store the original number of countries for further use:\n\n```{r}\n\ntree$Do(function(x) x$origCount <- x$count)\n\n```\n\nWe are now ready to prune. This is done by defining a pruning function, returning 'FALSE' for all countries that should be combined:\n\n```{r}\n\nmyPruneFun <- function(x, cutoff = 0.9, maxCountries = 7) {\n  if (isNotLeaf(x)) return (TRUE)\n  if (x$position > maxCountries) return (FALSE)\n  return (x$cumPop < (x$parent$population * cutoff))\n}\n\n```\n\nWe clone the tree, because we might want to play around with different parameters:\n\n```{r}\ntreeClone <- Clone(tree, pruneFun = myPruneFun)\nprint(treeClone$Oceania, \"population\", pruneMethod = \"simple\", limit = 20)\n```\n\nFinally, we need to sum countries that we pruned away into a new \"Other\" node:\n\n```{r}\n\ntreeClone$Do(function(x) {\n  missing <- x$population - sum(sapply(x$children, function(x) x$population))\n  other <- x$AddChild(\"Other\")\n  other$iso3 <- paste0(\"OTH(\", x$origCount, \")\")\n  other$country <- \"Other\"\n  other$continent <- x$name\n  other$GNI <- 0\n  other$population <- missing\n},\nfilterFun = function(x) x$level == 2\n)\n\n\nprint(treeClone$Oceania, \"population\", pruneMethod = \"simple\", limit = 20)\n\n```\n\n              \n## Plot \n\n### Plotting the treemap\n\nIn order to plot the treemap, we need to convert the data.tree structure back to a data.frame:\n\n```{r}\ndf <- ToDataFrameTable(treeClone, \"iso3\", \"country\", \"continent\", \"population\", \"GNI\")\n\ntreemap(df,\n        index=c(\"continent\", \"iso3\"),\n        vSize=\"population\",\n        vColor=\"GNI\",\n        type=\"value\")\n\n```\n\n\n### Plot as dendrogram\n\nJust for fun, and for no reason other than to demonstrate conversion to dendrogram, we can plot this in a very unusual way:\n\n```{r}\nplot(as.dendrogram(treeClone, heightAttribute = \"population\"))\n\n```\n\n## Further developments\n\nObviously, we should also aggregate the GNI as a weighted average. Namely, we should do this for the *OTH* catch-all countries that we add to the tree.\n\n# Portfolio Breakdown (finance)\n\nIn this example, we show how to display an investment portfolio as a hierarchic breakdown into asset classes.\nYou'll see:\n\n* how you can re-use a traversal\n* advanced use of `Aggregate`\n* how to add default attribute formatters to your tree\n\n## Convert from data.frame\n\n```{r}\nfileName <- system.file(\"extdata\", \"portfolio.csv\", package=\"data.tree\")\npfodf <- read.csv(fileName, stringsAsFactors = FALSE)\nhead(pfodf)\n```\n\nLet us convert the data.frame to a data.tree structure. Here, we use again the path string method. For other options, see `?as.Node.data.frame`\n\n```{r}\npfodf$pathString <- paste(\"portfolio\", \n                          pfodf$AssetCategory, \n                          pfodf$AssetClass, \n                          pfodf$SubAssetClass, \n                          pfodf$ISIN, \n                          sep = \"/\")\npfo <- as.Node(pfodf)\n\n```\n\n\n## Aggregate\n\nTo calculate the weight per asset class, we use the `Aggregate` method:\n\n```{r}\nt <- Traverse(pfo, traversal = \"post-order\")\nDo(t, function(x) x$Weight <- Aggregate(node = x, attribute = \"Weight\", aggFun = sum))\n```\n\nWe now calculate the `WeightOfParent`, \n\n```{r}\n\nDo(t, function(x) x$WeightOfParent <- x$Weight / x$parent$Weight)\n\n```\n\nDuration is a bit more complicated, as this is a concept that applies only to the fixed income asset class. Note that, in the second statement, we are reusing\nthe traversal from above.\n\n```{r}\n\npfo$Do(function(x) x$Duration <- ifelse(is.null(x$Duration), 0, x$Duration), filterFun = isLeaf)\nDo(t, function(x) x$Duration <- Aggregate(x, function(x) x$WeightOfParent * x$Duration, sum))\n\n```\n\n## Formatters\n\nWe can add default formatters to our data.tree structure. Here, we add them to the root, but \nwe might as well add them to any Node in the tree. \n\n```{r}\nSetFormat(pfo, \"WeightOfParent\", function(x) FormatPercent(x, digits = 1))\nSetFormat(pfo, \"Weight\", FormatPercent)\n\nFormatDuration <- function(x) {\n  if (x != 0) res <- FormatFixedDecimal(x, digits = 1)\n  else res <- \"\"\n  return (res)\n}\n\nSetFormat(pfo, \"Duration\", FormatDuration)\n\n```\n\nThese formatter functions will be used when printing a data.tree structure. \n\n## Print\n\n```{r}\n\n#Print\nprint(pfo, \n      \"Weight\", \n      \"WeightOfParent\",\n      \"Duration\",\n      filterFun = function(x) !x$isLeaf)\n\n```\n\n\n\n# ID3 (machine learning)\n\nThis example shows you the following:\n\n* How to build a data.tree structure in an algorithm\n* How to prune a tree\n* How to use data.tree to develop learning algorithms\n\nThanks a lot for all the helpful comments made by Holger von Jouanne-Diedrich.\n\nClassification trees are very popular these days. If you have never come across them, you might be interested in [classification trees](http://en.wikipedia.org/wiki/Decision_tree_learning). These models let you *classify* observations (e.g. things, outcomes) according to the observations' qualities, called *features*. Essentially, all of these models consist of creating a *tree*, where each *node* acts as a *router*. You insert your mushroom *instance* at the *root* of the tree, and then, depending on the mushroom's *features* (size, points, color, etc.), you follow along a different *path*, until a *leaf* node spits out your mushroom's *class*, i.e. whether it's edible or not. \n\nThere are two different steps involved in using such a model: *training* (i.e. constructing the tree), and *predicting* (i.e. using the tree to predict whether a given mushroom is poisonous). This example provides code to do both, using one of the very early algorithms to classify data according to discrete features: [ID3](http://en.wikipedia.org/wiki/ID3_algorithm). It lends itself well for this example, but of course today there are much more elaborate and refined algorithms available.\n\n## ID3 Introduction\n\nDuring the prediction step, each node routes our mushroom according to a feature. But how do we chose the feature? Should we first separate our set according to color or size? That is where classification models differ. \n\nIn ID3, we pick, at each node, the feature with the highest *Information Gain*. In a nutshell, this is the feature which splits the sample in the possibly *purest* subsets. For example, in the case of mushrooms, *dots* might be a more sensible feature than *organic*. \n\n### Purity and Entropy\n\n\n```{r}\nIsPure <- function(data) {\n  length(unique(data[,ncol(data)])) == 1\n}\n```\n\nThe *entropy* is a measure of the purity of a dataset. \n\n```{r}\nEntropy <- function( vls ) {\n  res <- vls/sum(vls) * log2(vls/sum(vls))\n  res[vls == 0] <- 0\n  -sum(res)\n}\n```\n\n\n### Information Gain\n\nMathematically, the information gain IG is defined as:\n\n$$ IG(T,a) = H(T)-\\sum_{v\\in vals(a)}\\frac{|\\{\\textbf{x}\\in T|x_a=v\\}|}{|T|} \\cdot H(\\{\\textbf{x}\\in T|x_a=v\\}) $$\n\nIn words, the information gain measures the *difference* between the entropy *before the split*, and the weighted sum of the entropies *after the split*.\n\nSo, let's rewrite that in R:\n\n\n```{r}\n\nInformationGain <- function( tble ) {\n  entropyBefore <- Entropy(colSums(tble))\n  s <- rowSums(tble)\n  entropyAfter <- sum (s / sum(s) * apply(tble, MARGIN = 1, FUN = Entropy ))\n  informationGain <- entropyBefore - entropyAfter\n  return (informationGain)\n}\n```\n\n\n## Training\n\nWe are all set for the ID3 training algorithm. \n\n### Pseudo code\n\nWe start with the entire training data, and with a root. Then:\n\n1. if the data-set is pure (e.g. all toxic), then  \n    1. construct a leaf having the name of the class (e.g. 'toxic')\n2. else  \n    1. choose the feature with the highest information gain (e.g. 'color')\n    2. for each value of that feature (e.g. 'red', 'brown', 'green')\n        1. take the subset of the data-set having that feature value\n        2. construct a child node having the name of that feature value (e.g. 'red')\n        3. call the algorithm recursively on the child node and the subset\n\n### Implementation in R with the data.tree package\n\nFor the following implementation, we assume that the classifying features are in columns 1 to n-1, whereas the class (the edibility) is in the last column.\n\n```{r}\nTrainID3 <- function(node, data) {\n    \n  node$obsCount <- nrow(data)\n  \n  #if the data-set is pure (e.g. all toxic), then\n  if (IsPure(data)) {\n    #construct a leaf having the name of the pure feature (e.g. 'toxic')\n    child <- node$AddChild(unique(data[,ncol(data)]))\n    node$feature <- tail(names(data), 1)\n    child$obsCount <- nrow(data)\n    child$feature <- ''\n  } else {\n    #calculate the information gain\n    ig <- sapply(colnames(data)[-ncol(data)], \n            function(x) InformationGain(\n              table(data[,x], data[,ncol(data)])\n              )\n            )\n    #chose the feature with the highest information gain (e.g. 'color')\n    #if more than one feature have the same information gain, then take\n    #the first one\n    feature <- names(which.max(ig))\n    node$feature <- feature\n    \n    #take the subset of the data-set having that feature value\n    \n    childObs <- split(data[ ,names(data) != feature, drop = FALSE], \n                      data[ ,feature], \n                      drop = TRUE)\n  \n    for(i in 1:length(childObs)) {\n      #construct a child having the name of that feature value (e.g. 'red')\n      child <- node$AddChild(names(childObs)[i])\n      \n      #call the algorithm recursively on the child and the subset      \n      TrainID3(child, childObs[[i]])\n    }\n    \n  }\n  \n  \n\n}\n```\n\n### Training with data\n\nOur training data looks like this:\n\n```{r}\nlibrary(data.tree)\ndata(mushroom)\nmushroom\n```\n\nIndeed, a bit small. But you get the idea.\n\nWe are ready to train our decision tree by running the function:\n\n\n```{r}\n\ntree <- Node$new(\"mushroom\")\nTrainID3(tree, mushroom)\nprint(tree, \"feature\", \"obsCount\")\n\n```\n\n\n## Prediction\n\n### The prediction method\n\nWe need a predict function, which will route data through our tree and make a prediction based on the leave where it ends up:\n\n```{r}\n\nPredict <- function(tree, features) {\n  if (tree$children[[1]]$isLeaf) return (tree$children[[1]]$name)\n  child <- tree$children[[features[[tree$feature]]]]\n  return ( Predict(child, features))\n}\n\n```\n\n### Using the prediction method\n\nAnd now we use it to predict:\n\n```{r}\nPredict(tree, c(color = 'red', \n                size = 'large', \n                points = 'yes')\n        )\n```\n\nOops! Looks like trusting classification blindly might get you killed.\n\n# Jenny Lind (decision tree, plotting)\n\nThis demo calculates and plots a simple decision tree. It demonstrates the following:\n\n* how to read a yaml file into a data.tree structure\n* how to calculate a decision tree\n* how to plot a data.tree with the data.tree plotting facility\n\n\n## Load YAML file\n\nYAML is similar to JSON, but targeted towards humans (as opposed to computers). It's consise and easy to read.\nYAML can be a neat format to store your data.tree structures, as you can use it across different software\nand systems, you can edit it with any text editor, and you can even send it as an email.\n\nThis is how our YAML file looks:\n\n```{r}\nfileName <- system.file(\"extdata\", \"jennylind.yaml\", package=\"data.tree\")\ncat(readChar(fileName, file.info(fileName)$size))\n\n```\n\nLet's convert the YAML into a data.tree structure. First, we load it with the yaml package into a list of lists. Then we use `as.Node` to convert the list into a data.tree structure:\n\n```{r}\n\nlibrary(data.tree)\nlibrary(yaml)\nlol <- yaml.load_file(fileName)\njl <- as.Node(lol)\nprint(jl, \"type\", \"payoff\", \"p\")\n```\n\n\n## Calculate\n\nNext, we define our payoff function, and apply it to the tree. Note that we use post-order traversal, meaning that we calculate the tree from leaf to root:\n\n```{r}\n\npayoff <- function(node) {\n  if (node$type == 'chance') node$payoff <- sum(sapply(node$children, function(child) child$payoff * child$p))\n  else if (node$type == 'decision') node$payoff <- max(sapply(node$children, function(child) child$payoff))\n}\n\njl$Do(payoff, traversal = \"post-order\", filterFun = isNotLeaf)\n\n```\n\nThe decision function is the next step. Note that we filter on decision nodes:\n\n```{r}\ndecision <- function(x) {\n  po <- sapply(x$children, function(child) child$payoff)\n  x$decision <- names(po[po == x$payoff])\n}\n\njl$Do(decision, filterFun = function(x) x$type == 'decision')\n\n\n```\n\n## Plot\n\n### Plot with the data.tree plotting facility\n\nThe data tree plotting facility uses GraphViz / DiagrammeR. You can provide a function as a style:\n\n\n```{r}\n\nGetNodeLabel <- function(node) switch(node$type, \n                                      terminal = paste0( '$ ', format(node$payoff, scientific = FALSE, big.mark = \",\")),\n                                      paste0('ER\\n', '$ ', format(node$payoff, scientific = FALSE, big.mark = \",\")))\n\nGetEdgeLabel <- function(node) {\n  if (!node$isRoot && node$parent$type == 'chance') {\n    label = paste0(node$name, \" (\", node$p, \")\")\n  } else {\n    label = node$name\n  }\n  return (label)\n}\n\nGetNodeShape <- function(node) switch(node$type, decision = \"box\", chance = \"circle\", terminal = \"none\")\n\n\nSetEdgeStyle(jl, fontname = 'helvetica', label = GetEdgeLabel)\nSetNodeStyle(jl, fontname = 'helvetica', label = GetNodeLabel, shape = GetNodeShape)\n``` \n\nNote that the `fontname` is inherited as is by all children, whereas e.g. the `label` argument is a function, it's called\non each inheriting child node.\n\nAnother alternative is to set the style per node:\n\n```{r}\njl$Do(function(x) SetEdgeStyle(x, color = \"red\", inherit = FALSE), \n      filterFun = function(x) !x$isRoot && x$parent$type == \"decision\" && x$parent$decision == x$name)\n\n\n```\n\nFinally, we direct our plot from left-to-right, and use the plot function to display:\n\n```{r, eval = FALSE}\nSetGraphStyle(jl, rankdir = \"LR\")\nplot(jl)\n\n```\n\n![](assets/dtree.png)\n\n# Bubble Chart (visualization)\n\nIn this example, we will replicate Mike Bostock's bubble example. See here for details: http://bl.ocks.org/mbostock/4063269.  \nWe use Joe Cheng's [bubbles](https://github.com/jcheng5/bubbles) package. All of this is inspired by [Timelyportfolio](https://github.com/timelyportfolio), the king of [htmlwidgets](http://www.htmlwidgets.org).\n\nYou'll learn how to convert a complex JSON into a data.frame, and how to use this to plot hierarchic visualizations.\n\n## Load JSON file\n\nThe data represents the Flare class hierarchy, which is a code library for creating visualizations. The JSON is long, deeply nested, and complicated.\n\n```{r}\nfileName <- system.file(\"extdata\", \"flare.json\", package=\"data.tree\")\nflareJSON <- readChar(fileName, file.info(fileName)$size)\ncat(substr(flareJSON, 1, 300))\n\n```\n\nSo, let's convert it into a data.tree structure:\n\n```{r}\nlibrary(jsonlite)\nflareLoL <- fromJSON(file(fileName),\n                     simplifyDataFrame = FALSE\n                     )\n\nflareTree <- as.Node(flareLoL, mode = \"explicit\", check = \"no-warn\")\nflareTree$attributesAll\nprint(flareTree, \"size\", limit = 30)\n\n```\n\nFinally, we can convert it into a data.frame. The `ToDataFrameTable` only converts leafs, but inherits attributes from ancestors:\n\n```{r}\n\nflare_df <- ToDataFrameTable(flareTree, \n                             className = function(x) x$parent$name, \n                             packageName = \"name\", \n                             \"size\")\nhead(flare_df)\n\n```\n\n\nThis does not look spectacular. But take a look at this [stack overflow](http://stackoverflow.com/questions/31339805/converting-json-format-to-csv-to-upload-data-table-in-r-to-produce-d3-bubble-cha) question to see how people struggle to do this type of operation. \n\nHere, it was particularly simple, because the underlying JSON structure is regular. If it were not (e.g. some nodes contain different attributes than others), the conversion from JSON to data.tree would still work. And then, as a second step, we could modify the data.tree structure before converting it into a data.frame. For example, we could use `Prune` and `Remove` to remove unwanted nodes, use `Set` to remove or add default values, etc.\n\n## Plot\n\nWhat follows has nothing to do with data.tree anymore. We simply provide the bubble chart printing for your enjoyment. In order to run it yourself, you need to install the bubbles package from github:\n\n\n```{r, eval = FALSE}\n\ndevtools::install_github(\"jcheng5/bubbles@6724e43f5e\")\nlibrary(scales)\nlibrary(bubbles)\nlibrary(RColorBrewer)\nbubbles(\n  flare_df$size,\n  substr(flare_df$packageName, 1, 2),\n  tooltip = flare_df$packageName,\n  color = col_factor(\n    brewer.pal(9,\"Set1\"),\n    factor(flare_df$className)\n  )(flare_df$className),\n  height = 800,\n  width = 800\n)\n```\n\n![](assets/bubbles.jpg)\n\n\n# File Explorer (system utilities)\n\nIn this example, we print the files that exist in the folder structure of the file system. As a special goodie, we'll show code that lets you build your own *R File Explorer*, an interactive tree / list widget that lets you expand folders and browse through your file system.\n\n## Print\n\nFirst, let's read the files in a directory tree into R. In this example, the root path \"..\" is the parent of the `vignettes` folder, i.e. the data.tree package folder itself:\n\n\n```{r}\npath <- \"..\"\nfiles <- list.files(path = path, \n                    recursive = TRUE,\n                    include.dirs = FALSE) \n\ndf <- data.frame(\n      filename = sapply(files, \n                        function(fl) paste0(\"data.tree\",\"/\",fl)\n      ), \n      file.info(paste(path, files, sep = \"/\")),\n      stringsAsFactors = FALSE\n    )\n \nprint(head(df)[c(1,2,3,4)], row.names = FALSE)\n\n```\n\nWe now convert this into a data.tree:\n\n```{r}\n\nfileStructure <- as.Node(df, pathName = \"filename\")\nfileStructure$leafCount / (fileStructure$totalCount - fileStructure$leafCount)\nprint(fileStructure, \"mode\", \"size\", limit = 25)\n\n```\n\n## Listviewer html widget\n\nFinally, we can display the files by timelyportfolio's listviewer. As it's not on CRAN, we only display a screenshot of the widget in in this vignette. This is not half as fun as the interactive widget, of course. So please try it out for yourself to see it in action.\n\n```{r, eval = FALSE}\n\n#This requires listviewer, which is available only on github\ndevtools::install_github(\"timelyportfolio/listviewer\")\n\nlibrary(listviewer)\n\nl <- ToListSimple(fileStructure)\njsonedit(l)\n\n```\n\n![](assets/listviewer.jpg)\n\n(Run the code yourself to see the widget in action)\n\n<a name=\"GeneDefect\"></a>\n\n# Gene Defect (genetics, probabilities, multi-generation models)\n\nThis is a simplistic example from the area of genetics. Similar models are found in many attributes, namely wherever you have multi-generation models and probabilities.\n\nThe code generates 100 simulations of a 3 generation population. Individuals can inherit or develop a certain feature (e.g. colour blindness). The probability to develop the feature is based on sex. We then plot the probability distribution of the feature in the last generation.\n\nYou'll learn how to build a data.tree structure according to probabilistic rules, and how to use the structure to infer a probability distribution.\n\n## Algorithm\n\nFirst, we generate a family tree of a population exhibiting a certain feature (e.g. colour blindness).\n\n```{r}\n\n#' @param children the number of children each population member has\n#' @param probSex the probability of the sex of a descendant\n#' @param probInherit the probability the feature is inherited, depending on the sex of the descendant\n#' @param probDevelop the probability the feature is developed (e.g. a gene defect), depending on the sex\n#' of the descendant\n#' @param generations the number of generations our simulated population should have\n#' @param parent for recursion\nGenerateChildrenTree <- function(children = 2, \n                                 probSex = c(male = 0.52, female = 0.48), \n                                 probInherit = c(male = 0.8, female = 0.5),\n                                 probDevelop = c(male = 0.05, female = 0.01),\n                                 generations = 3, \n                                 parent = NULL) {\n  \n  if (is.null(parent)) {\n    parent <- Node$new(\"1\")\n    parent$sex <- 1\n    parent$feature <- TRUE\n    parent$develop <- FALSE\n  }\n  \n  #sex of descendants\n  #1 = male\n  #2 = female\n  sex <- sample.int(n = 2, size = children, replace = TRUE, prob = probSex)\n  for (i in 1:children) child <- parent$AddChild(i)\n  Set(parent$children, sex = sex)\n  \n  #inherit\n  if (parent$feature == TRUE) {\n    for (i in 1:2) {\n      subPop <- Traverse(parent, filterFun = function(x) x$sex == i)\n      inherit <- sample.int(n = 2, \n                            size = length(subPop), \n                            replace = TRUE, \n                            prob = c(1 - probInherit[i], probInherit[i]))\n      \n      Set(subPop, feature = as.logical(inherit - 1))\n    }\n  } else {\n    Set(parent$children, feature = FALSE)\n  }\n  \n  #develop\n  Set(parent$children, develop = FALSE)\n  for (i in 1:2) {\n    subPop <- Traverse(parent, filterFun = function(x) x$sex == i && !x$feature)\n    develop <- sample.int(n = 2, \n                          size = length(subPop), \n                          replace = TRUE, \n                          prob = c(1 - probDevelop[i], probDevelop[i]))\n    Set(subPop, feature = as.logical((develop - 1)), develop = as.logical((develop - 1)))\n  }\n  \n  #recursion to next generation\n  if (generations > 0) for (i in 1:children) GenerateChildrenTree(children, \n                                                                  probSex, \n                                                                  probInherit, \n                                                                  probDevelop, \n                                                                  generations - 1, \n                                                                  parent$children[[i]])\n  \n  return (parent)\n}\n\n```\n\n\n\n## Analysis\n\nJust for demonstration purpose, this is what a tree looks like:\n\n```{r}\n\ntree <- GenerateChildrenTree()\nprint(tree, \"sex\", \"feature\", \"develop\", limit = 20)\n\n```\n\nHow big is our population after three generations?\n\n```{r}\ntree$totalCount\n```\n\n\nFor a given tree, how many have the feature?\n\n```{r}\nlength(Traverse(tree, filterFun = function(x) x$feature))\n```\n\n\nHow many males have developed the feature without inheritance?\n\n```{r}\nlength(Traverse(tree, filterFun = function(x) x$sex == 1 && x$develop))\n```\n\nWhat is the occurrence of the feature in the last generation?\n\n```{r}\nFreqLastGen <- function(tree) {\n  l <- tree$leaves\n  sum(sapply(l, function(x) x$feature))/length(l)\n}\n\nFreqLastGen(tree)\n\n```\n\n## Simulation\n\nGenerate 100 sample trees and get the frequency of the feature in the last generation\n\n```{r}\nsystem.time(x <- sapply(1:100, function(x) FreqLastGen(GenerateChildrenTree())))\n```\n\n\nPlot a histogram of the frequency of the defect in the last generation:\n\n```{r}\nhist(x, probability = TRUE, main = \"Frequency of feature in last generation\")\n```\n\nFor larger populations, you might consider parallelisation, of course. See below for some hints.\n\n## Parallelisation\n\nIt is straight forward to parallelise the simulation. If, as in this example, you do not need to pass around a data.tree structure from one process (fork) to another, it is also rather efficient.\n\n```{r, eval = FALSE}\nlibrary(foreach)\nlibrary(doParallel)\nregisterDoParallel(makeCluster(3))\n#On Linux, there are other alternatives, e.g.: library(doMC);  registerDoMC(3)\n\nsystem.time(x <- foreach (i = 1:100, .packages = \"data.tree\") %dopar% FreqLastGen(GenerateChildrenTree()))\nstopImplicitCluster()\n```\n\n```{r, echo = FALSE}\n\nprint(c(user = 0.07, system = 0.02, elapsed = 1.40))\n```\n\n\n\n\n\nFor the more complicated case where you want to parallelise operations on a single tree, see below.\n\n# Tic-Tac-Toe (game complexity)\n\nIn this example, we do a brute force solution of Tic-Tac-Toe, the well-known 3*3 game.\n\nYou'll learn how data.tree can be used to build a tree of game history, and how the resulting data.tree structure can be used to analyze the game.\n\nIn addition, this example shows you how parallelisation can speed up data.tree.\n\nWe want to set up the problem in a way such that each `Node` is a move of a player, and each path describes the entire history of a game.\n\nWe number the attributes from 1 to 9. Additionally, for easy readability, we label the Nodes in an Excel-like manner, such that field 9, say, is 'c3':\n\n```{r}\n\nattributes <- expand.grid(letters[1:3], 1:3)\nattributes\n\n```\n\nTo speed up things a bit, we consider rotation, so that, say, the first move in a3 and a1 are considered equal, because they could be achieved with a 90 degree rotation of the board. This leaves us with only a3, b3, and b2 for the first move of player 1:\n\n\n```{r}\nttt <- Node$new(\"ttt\")\n\n#consider rotation, so first move is explicit\nttt$AddChild(\"a3\")\nttt$a3$f <- 7\nttt$AddChild(\"b3\")\nttt$b3$f <- 8\nttt$AddChild(\"b2\")\nttt$b2$f <- 5\n\n\nttt$Set(player = 1, filterFun = isLeaf)\n\n\n```\n\n\n## Game play\n\nNow we recurse through the tree, and add possible moves to the leaves, growing it eventually to hold all possible games. To do this, we define a method which, based on a `Node's` path, adds possible moves as children.\n\n\n```{r}\nAddPossibleMoves <- function(node) {\n  t <- Traverse(node, traversal = \"ancestor\", filterFun = isNotRoot)\n  \n  available <- rownames(attributes)[!rownames(attributes) %in% Get(t, \"f\")]\n  for (f in available) {\n    child <- node$AddChild(paste0(attributes[f, 1], attributes[f, 2]))\n    child$f <- as.numeric(f)\n    child$player <- ifelse(node$player == 1, 2, 1)\n    hasWon <- HasWon(child)\n    if (!hasWon && child$level <= 10) AddPossibleMoves(child)\n    if (hasWon) {\n      child$result <- child$player\n      print(paste(\"Player \", child$player, \"wins!\"))\n    } else if(child$level == 10) {\n      child$result <- 0\n      print(\"Tie!\")\n    }\n    \n  }\n  return (node)  \n}\n\n```\n\nNote that we store additional info along the way. For example, in the line `child$player <- ifelse(node$player == 1, 2, 1)`, the player is deferred from the parent `Node`, and set as an attribute in the `Node`.\n\n\n## Exit Criteria\n\nOur algorithm stops whenever either player has won, or when all 9 attributes are taken. Whether a player has won is determined by this function:\n\n```{r}\nHasWon <- function(node) {\n  t <- Traverse(node, traversal = \"ancestor\", filterFun = function(x) !x$isRoot && x$player == node$player)\n  mine <- Get(t, \"f\")\n  mineV <- rep(0, 9)\n  mineV[mine] <- 1\n  mineM <- matrix(mineV, 3, 3, byrow = TRUE)\n  result <- any(rowSums(mineM) == 3) ||\n    any(colSums(mineM) == 3) ||\n    sum(diag(mineM)) == 3 ||\n    sum(diag(t(mineM))) == 3\n  return (result)\n}\n\n```\n\n## Tree creation\n\nThe following code plays all possible games. Depending on your computer, this might take a few minutes:\n\n```{r, eval=FALSE}\nsystem.time(for (child in ttt$children) AddPossibleMoves(child))\n```\n\n```{r, echo= FALSE}\nc(user = 345.645, system = 3.245, elapsed = 346.445)\n```\n\n\n## Analysis\n\nWhat is the total number of games?\n\n```{r, eval = FALSE}\nttt$leafCount\n```\n\n```{r, echo = FALSE}\n89796\n```\n\nHow many nodes (moves) does our tree have?\n\n```{r, eval = FALSE}\nttt$totalCount\n```\n\n```{r, echo = FALSE}\n203716\n```\n\n\nWhat is the average length of a game?\n\n```{r, eval = FALSE}\nmean(ttt$Get(function(x) x$level - 1, filterFun = isLeaf))\n```\n\n```{r, echo = FALSE}\n8.400775\n```\n\n\nWhat is the average branching factor?\n\n```{r, eval = FALSE}\nttt$averageBranchingFactor\n```\n\n```{r, echo = FALSE}\n1.788229\n```\n\nHow many games were won by each player?\n\n```{r, eval = FALSE}\n\nwinnerOne <- Traverse(ttt, filterFun = function(x) x$isLeaf && x$result == 1)\nwinnerTwo <- Traverse(ttt, filterFun = function(x) x$isLeaf && x$result == 2)\nties <- Traverse(ttt, filterFun = function(x) x$isLeaf && x$result == 0)\n\nc(winnerOne = length(winnerOne), winnerTwo = length(winnerTwo), ties = length(ties))\n```\n\n\n```{r, echo=FALSE}\nc(winnerOne = 39588, winnerTwo = 21408, ties = 28800)\n```\n\n\nWe can, for example, look at any Node, using the `PrintBoard` function. This function prints the game history:\n\n```{r}\n\nPrintBoard <- function(node) {\n  mineV <- rep(0, 9)\n\n  \n  t <- Traverse(node, traversal = \"ancestor\", filterFun = function(x) !x$isRoot && x$player == 1)\n  field <- Get(t, \"f\")\n  value <- Get(t, function(x) paste0(\"X\", x$level - 1))\n  mineV[field] <- value\n  \n  t <- Traverse(node, traversal = \"ancestor\", filterFun = function(x) !x$isRoot && x$player == 2)\n  field <- Get(t, \"f\")\n  value <- Get(t, function(x) paste0(\"O\", x$level - 1))\n  mineV[field] <- value\n    \n  mineM <- matrix(mineV, 3, 3, byrow = TRUE)\n  rownames(mineM) <- letters[1:3]\n  colnames(mineM) <- as.character(1:3)\n  mineM\n}\n\n```\nThe first number denotes the move (1 to 9). The second number is the player:\n\n```{r, eval = FALSE}\n\nPrintBoard(ties[[1]])\n\n```\n\n```{r, echo = FALSE}\nmt <- matrix(c(\"O2\", \"X3\", \"O4\", \"X5\", \"O6\", \"X7\", \"X1\", \"O8\", \"X9\"), nrow = 3, ncol = 3, byrow = TRUE)\nrownames(mt) <- letters[1:3]\ncolnames(mt) <- as.character(1:3)\nmt\n```\n\nExercise: Do the same for Chess!\n\n## Parallelisation\n\nHere, the parallelisation is more challenging as with the [Gene Defect](#GeneDefect) example above. The reason is that we have only one tree, albeit a big one. So we need a strategy to do what we call intra-tree parallelisation.\n\nIn a perfect world, data.tree and intra-tree parallelisation would tell a love story: Many operations are recursive, and can be called equally well on a subtree or on an entire tree. Therefore, it is very natural to delegate the calculation of multiple sub-trees to different processes.\n\nFor example, tic-tac-toe seems almost trivial to parallelise: Remember that, on level 2, we created manually 3 `Nodes`. The creation of the sub-trees on these `Nodes` will be completely independent on the other sub-trees. Then, each sub-tree can be created in its own process. \n\nSo, in theory, we could use any parallelisation mechanism available in R.\nUnfortunately, you need to take into account a few things. As a matter of fact, to pass the sub-trees from a fork process back to the main process, R needs to serialize the `Nodes` of the sub-tree, and this results in huge objects. As a result, collecting the sub-trees would take ages. \n\nSo, instead, we can\n\n1. create the sub-trees, each in its own process\n2. run the analysis in the child process\n3. return the result of the analysis to the main process\n4. aggregate the results\n\n```{r, eval=FALSE}\n\n\nAnalyseTicTacToe <- function(subtree) {\n  # 1. create sub-tree\n  AddPossibleMoves(subtree)\n  # 2. run the analysis\n  winnerOne <- Traverse(subtree, filterFun = function(x) x$isLeaf && x$result == 1)\n  winnerTwo <- Traverse(subtree, filterFun = function(x) x$isLeaf && x$result == 2)\n  ties <- Traverse(subtree, filterFun = function(x) x$isLeaf && x$result == 0)\n\n  res <- c(winnerOne = length(winnerOne), \n           winnerTwo = length(winnerTwo),\n           ties = length(ties))\n  # 3. return the result\n  return(res)\n}\n\n\nlibrary(foreach)\nlibrary(doParallel)\nregisterDoParallel(makeCluster(3))\n#On Linux, there are other alternatives, e.g.: library(doMC);  registerDoMC(3)\nsystem.time(\n  x <- foreach (child = ttt$children, \n                .packages = \"data.tree\") %dopar% AnalyseTicTacToe(child)\n)\n```\n\n```{r, echo= FALSE}\nc(user = 0.05, system = 0.04, elapsed = 116.86)\n```\n\n\n```{r, eval = FALSE}\nstopImplicitCluster()\n# 4. aggregate results\nrowSums(sapply(x, c))\n```\n\n```{r, echo=FALSE}\nc(winnerOne = 39588, winnerTwo = 21408, ties = 28800)\n```\n\n"
  },
  {
    "path": "vignettes/applications.banner.html",
    "content": "<img src=\"banner_applications.jpg\" alt=\"Banner\">\n<style type=\"text/css\">\n.rosabox { \n  background-color:#FFDDDD; \n  font-size: 90%;\n  border-radius: 20px;\n  padding:2em; \n  line-height: 1.6em;}\n</style>\n<br>\n<br>\n\n\n\n"
  },
  {
    "path": "vignettes/data.tree.Rmd",
    "content": "---\ntitle: \"Introduction to data.tree\"\nauthor: \"Christoph Glur\"\ndate: '`r Sys.Date()`'\noutput:\n  html_document:\n    includes:\n      before_body: intro.banner.html\n    self_contained: yes\n    theme: cerulean\n    toc: yes\n    toc_depth: 2\n  pdf_document:\n    toc: yes\n    toc_depth: 2\n---\n\n<!--\n  %\\VignetteEngine{knitr::rmarkdown}\n  %\\VignetteIndexEntry{Quick introduction to data.tree}\n-->\n\n```{r echo=F}\n### get knitr just the way we like it\n\nknitr::opts_chunk$set(\n  message = FALSE,\n  warning = FALSE,\n  error = FALSE,\n  tidy = FALSE,\n  cache = FALSE\n)\n\n```\n\n\n# Introduction\n\n## Trees\n\nTrees are ubiquitous in mathematics, computer science, data sciences, finance, and in many other attributes. Trees are especially useful when we are facing *hierarchical data*. For example, trees are used:\n\n* in decision theory (cf. decision trees)\n* in machine learning (e.g. classification trees)\n* in finance, e.g. to classify financial instruments into asset classes\n* in routing algorithms\n* in computer science and programming (e.g. binary search trees, XML)\n* e.g. for family trees\n\nFor more details, see the applications vignette by typing `vignette(\"applications\", package = \"data.tree\")`\n\n## Trees in R\n\nTree-like structures are already used in R. For example, environments can be seen as nodes in a tree. And CRAN provides numerous packages that deal with tree-like structures, especially in the area of decision theory. Yet, there is no general purpose hierarchical data structure that could be used as conveniently and generically as, say, `data.frame`. \n\nAs a result, people often try to resolve hierarchical problems in a tabular fashion, for instance with data.frames. But often, hierarchies don't marry with tables, and various workarounds are usually required. \n\n\n## Trees in `data.tree`\n\nThis package offers an alternative. The `data.tree` package lets you create hierarchies, called `data.tree` **structures**. The building block of theses structures are `Node` objects. The package provides basic traversal, search, and sort operations, and an infrastructure for recursive tree programming. You can decorate `Nodes` with your own attributes and methods, so as to extend the package to your needs. \n\nThe package also provides convenience methods for neatly printing and plotting trees. It supports conversion from and to `data.frames`, `lists`, and other tree structures such as `dendrogram`, `phylo` objects from the ape package, `igraph`, and other packages.\n\nTechnically, `data.tree` structures are bi-directional, ordered trees. Bi-directional means that you can navigate from parent to children and vice versa. Ordered means that the sort order of the children of a parent node is well-defined.\n\n# `data.tree` basics\n\n## Definitions\n\n* __`data.tree` structure__: a _tree_, consisting of multiple `Node` objects. Often, the entry point to a `data.tree` structure is the _root Node_\n* __`Node`__: both a class and the basic building block of `data.tree` structures\n* __attribute__: an active, a field, or a method. **Not to be confused with standard R attributes, c.f. `?attr`, which have a different meaning. Many methods and functions have an `attribute` arg, which can refer to a an active, a field or a method. For example, see `?Get`\n* __active__ (sometimes called property): a field on a `Node` that can be called like an attribute, but behaves like a function without arguments. For example: `node$position`\n* __field__: a named value on a `Node`, e.g. `node$cost <- 2500`\n* __method__: a function acting on an object (on a `Node` in this context). Many methods are available in OO style (e.g. `node$Revert()`) or in traditional style (`Revert(node)`)\n* __inheritance__: in this context, inheritance refers to a situation in which a child `Node` inherits e.g. an attribute from one of its ancestors. For example, see `?Get`, `?SetNodeStyle`\n\n## Tree creation\n\nThere are different ways to create a `data.tree` structure. For example, you can create a tree **programmatically**, by **conversion** from other R objects, or from a **file**.\n\n### Create a tree programmatically\n\nLet's start by creating a tree programmatically. We do this by creating `Node` objects, and linking them together so as to define the parent-child relationships.\n\nIn this example, we are looking at a company, Acme Inc., and the tree reflects its organisational structure. The root (level 1) is the company. On level 2, the nodes represent departments, and the leaves of the tree represent projects that the company is considering for next year:\n\n```{r}\nlibrary(data.tree)\n\nacme <- Node$new(\"Acme Inc.\")\n  accounting <- acme$AddChild(\"Accounting\")\n    software <- accounting$AddChild(\"New Software\")\n    standards <- accounting$AddChild(\"New Accounting Standards\")\n  research <- acme$AddChild(\"Research\")\n    newProductLine <- research$AddChild(\"New Product Line\")\n    newLabs <- research$AddChild(\"New Labs\")\n  it <- acme$AddChild(\"IT\")\n    outsource <- it$AddChild(\"Outsource\")\n    agile <- it$AddChild(\"Go agile\")\n    goToR <- it$AddChild(\"Switch to R\")\n\nprint(acme)\n```\n\nAs you can see from the previous example, each `Node` is identified by its *name*, i.e. the argument you pass into the `Node$new(name)` constructor. The name needs to be *unique* among siblings, such that paths to `Nodes` are unambiguous.\n\n`Node` inherits from `R6` reference class. This has the following implications:\n\n1. You can call methods on a `Node` in OO style, e.g. `acme$Get(\"name\")`\n2. `Node` exhibits *reference semantics*. Thus, multiple variables in R can point to the same `Node`, and modifying a `Node` will modify it for all referencing variables. In the above code example, both `acme$IT` and `it` reference the same object. This is different from the *value semantics*, which is much more widely used in R.\n\n### Create a tree from a `data.frame`\n\nCreating a tree programmatically is useful especially in the context of algorithms. However, most times you will create a tree by conversion. This could be by conversion from a nested list-of-lists, by conversion from another R tree-structure (e.g. an ape `phylo`), or by conversion from a `data.frame`. For more details on all the options, type `?as.Node` and refer to the *See Also* section.\n\nOne of the most common conversions is the one from a `data.frame` in table format. The following code illustrates this. We load the GNI2014 data from the treemap package. This `data.frame` is in table format, meaning that each row will represent a *leaf* in the `data.tree` structure:\n\n```{r}\nlibrary(treemap)\ndata(GNI2014)\nhead(GNI2014)\n```\n\nLet's convert that into a `data.tree` structure! We start by defining a *pathString*. The pathString describes the hierarchy by defining a path from the root to each leaf. In this example, the hierarchy comes very naturally:\n\n\n```{r}\nGNI2014$pathString <- paste(\"world\", \n                            GNI2014$continent, \n                            GNI2014$country, \n                            sep = \"/\")\n\n```\n\nOnce our pathString is defined, conversion to Node is very easy:\n\n```{r}\npopulation <- as.Node(GNI2014)\nprint(population, \"iso3\", \"population\", \"GNI\", limit = 20)\n```\n\nThis is a simple example, and more options are available. Type `?FromDataFrameTable` for all the details.\n\n### Create a tree from a file\n\nOften, trees are created from one of many file formats. When developing this package, We opted for a multi-step approach, meaning that you first import the file into one of the well-known R data structures. Then you convert these into a `data.tree` structure. For example, typical import patterns could be:\n\n* csv -> data.frame in table format (`?read.csv`) -> data.tree (`?as.Node.data.frame`)\n* Newick -> ape phylo (`?ape::read.tree`) -> data.tree (`?as.Node.phylo` )\n* csv -> data.frame in network format (`?read.csv`) -> data.tree (c.f. `?FromDataFrameNetwork`)\n* yaml -> list of lists (`?yaml::yaml.load`) -> data.tree (`?as.Node.list`)\n* json -> list of lists (e.g. `?jsonlite::fromJSON`) -> data.tree (`?as.Node.list`)\n\nIf you have a choice, we recommend you consider yaml format to store and share your hierarchies. It is concise, human-readable, and very easy to convert to a data.tree. An example is provided here for illustration. The data represents what platforms and OS versions a group of students use:\n\n```{r}\nlibrary(yaml)\nyaml <- \"\nname: OS Students 2014/15\nOS X:\n  Yosemite:\n    users: 16\n  Leopard:\n    users: 43\nLinux:\n  Debian:\n    users: 27\n  Ubuntu:\n    users: 36\nWindows:\n  W7:\n    users: 31\n  W8:\n    users: 32\n  W10:\n    users: 4\n\"\n\nosList <- yaml.load(yaml)\nosNode <- as.Node(osList)\nprint(osNode, \"users\")\n```\n\nIn cases where your leaf elements have no attributes, you might want to interpret them as nodes, and not as attributes. In such cases, you can use\n`interpretNullAsList = TRUE` to convert these into `Nodes` (instead of attributes).\n\nFor example:\n\n```{r}\nlibrary(yaml)\nyaml <- \"\nname: OS Students 2014/15\nOS X:\n  Yosemite:\n  Leopard:\nLinux:\n  Debian:\n  Ubuntu:\nWindows:\n  W7:\n  W8:\n  W10:\n\"\n\nosList <- yaml.load(yaml)\nosNode <- as.Node(osList, interpretNullAsList = TRUE)\nosNode$printFormatters <- list(h = \"\\u2500\" , v = \"\\u2502\", l = \"\\u2514\", j = \"\\u251C\")\nprint(osNode, \"users\")\n```\n\n## Node methods\n\nAs seen above, a `data.tree` structure is composed of `Node` objects, and the entry point to a `data.tree` structure is always a `Node`, often the *root* `Node` of a tree.\n\nThere are different types of methods:\n\n* OO-style actives (sometimes called properties) on `Nodes`, such as e.g. `Node$isRoot`\n* OO-style methods on `Nodes`, such as e.g. `Node$AddChild(name)`\n* Classical R methods, such as e.g. `Clone(node)`. \n\n\n### Actives Examples (aka Properties)\n\nActives look and feel like attributes, but they are dynamically evaluated. They are documented in the `Node` documentation, which is accessed by typing `?Node`. \n\nRemember our population example:\n\n```{r}\nprint(population, limit = 15)\npopulation$isRoot\npopulation$height\npopulation$count\npopulation$totalCount\npopulation$attributes\npopulation$attributesAll\npopulation$averageBranchingFactor\n```\n\nThe naming convention of the package is that attributes and actives are lower case, whereas methods are upper / CamelCase.\nRStudio and other IDEs work well with `data.tree`. If you have a `Node`, simply type `myNode$ + SPACE` to get a list of available attributes, actives and methods. \n\n### OO-Style Methods Examples\n\nExamples of OO-Style methods\n\nYou will find more information on these examples below.\n\n\nGet will traverse the tree and collect specific values for the `Nodes` it traverses:\n \n```{r}\n\nsum(population$Get(\"population\", filterFun = isLeaf))\n\n```\n\nPrune traverses the tree and keeps only the subtrees for which the pruneFun returns TRUE. \n\n```{r}\nPrune(population, pruneFun = function(x) !x$isLeaf || x$population > 1000000)\n```\n\nNote that the Prune function has side-effects, as it acts on the original population object.\nThe population sum is now smaller:\n\n```{r}\nsum(population$Get(\"population\", filterFun = isLeaf), na.rm = TRUE)\n```\n\n\n\n### Traditional R Methods\n\n```{r}\npopClone <- Clone(acme)\n\n```\n\nTraditional S3 generics are available especially for conversion:\n\n```{r}\nas.data.frame(acme)\n```\n\nThough there is also a more specialised non-generic version:\n\n```{r}\nToDataFrameNetwork(acme)\n```\n\n\n## Climbing a tree (tree navigation)\n\nTo *climb* a tree means to navigate to a specific `Node` in the `data.tree` structure. \n\n### Navigation by path\n\nThe most natural form of climbing a tree is to climb by path:\n\n```{r}\nacme$IT$Outsource\nacme$Research$`New Labs`\n```\n\n\n### Navigation by position\n\nHowever, there is a number of other ways to get to a specific `Node`. We can access the children of a `Node` directly through `Node$children`: \n\n\n```{r}\n\nacme$children[[1]]$children[[2]]$name\n\n```\n\n\n### Navigation by attributes\n\nFurthermore, we can not only navigate by name, but also by other attributes. This is achieved with the `Climb` method. The name of each `...` argument designates the field, and the value matches against `Nodes`. Each argument refers to the subsequent level to climb. In this example, `Climb` takes acme's child at position 1 (i.e. `Accounting`), then it takes `Accounting's` child called `New Software`:\n\n```{r}\nacme$Climb(position = 1, name = \"New Software\")$path\n\n```\n\nAs a shortcut, you can climb multiple levels with a single argument:\n\n```{r}\ntree <- CreateRegularTree(5, 5)\ntree$Climb(position = c(2, 3, 4))$path\n```\n\nFinally, you can even combine. The following example starts on the root, then looks for child at position 2, then for its child at position 3. Next, we move to the child having name = \"1.2.3.4\", and finally its child having name \"1.2.3.4.5\":\n\n```{r}\ntree$Climb(position = c(2, 3), name = c(\"1.2.3.4\", \"1.2.3.4.5\"))$path\n```\n\n\n## Custom attributes\n\nJust as with, say, a `list`, we can add any custom field to any `Node` in a `data.tree` structure. Let's go back to our acme company: \n\n```{r}\nacme\n```\n\nWe now add costs and probabilities to the projects in each department:\n\n\n```{r}\nacme$Accounting$`New Software`$cost <- 1000000\nacme$Accounting$`New Accounting Standards`$cost <- 500000\nacme$Research$`New Product Line`$cost <- 2000000\nacme$Research$`New Labs`$cost <- 750000\nacme$IT$Outsource$cost <- 400000\nacme$IT$`Go agile`$cost <- 250000\nacme$IT$`Switch to R`$cost <- 50000\n\nacme$Accounting$`New Software`$p <- 0.5\nacme$Accounting$`New Accounting Standards`$p <- 0.75\nacme$Research$`New Product Line`$p <- 0.25\nacme$Research$`New Labs`$p <- 0.9\nacme$IT$Outsource$p <- 0.2\nacme$IT$`Go agile`$p <- 0.05\nacme$IT$`Switch to R`$p <- 1\nprint(acme, \"cost\", \"p\")\n\n```\n\nNote that there is a list of reserved names you cannot use as `Node` attributes:\n\n\n```{r}\nNODE_RESERVED_NAMES_CONST\n```\n### Custom attributes in constructor\n\nAn alternative, often convenient way to assign custom attributes is in the constructor, or in the `Node$AddChild` method:\n\n```{r}\nbirds <- Node$new(\"Aves\", vulgo = \"Bird\")\nbirds$AddChild(\"Neognathae\", vulgo = \"New Jaws\", species = 10000)\nbirds$AddChild(\"Palaeognathae\", vulgo = \"Old Jaws\", species = 60)\nprint(birds, \"vulgo\", \"species\")\n\n```\n\n### Custom attributes as function\n\nNothing stops you from setting a function as a field. This calculates a value dynamically, i.e. whenever a field is accessed in tree traversal. For example, you can add a new `Node` to your structure, and the function will reflect this. Think of this as a hierarchical spreadsheet, in which you can set formulas into cells.\n\nConsider the following example:\n\n```{r}\nbirds$species <- function(self) sum(sapply(self$children, function(x) x$species))\nprint(birds, \"species\")\n\n```\ndata.tree maps the `self` argument to the `Node` at hand. Thus, you must name the argument `self`.\n\nNow, let's assume we discover a new species. Then, the species on the root adjusts dynamically:\n\n```{r}\nbirds$Palaeognathae$species <- 61\nprint(birds, \"species\")\n```\n\nThis, together with the `Set` method and recursion, becomes a very powerful tool, as we'll see later.\n\n\n## Printing\n\n### Basic Printing\n\nBasic printing is easy, as you surely have noted in the previous sections. `print` displays a tree in a tree-grid view. On the left, you have the hierarchy. Then you have a column per variable you want to print:\n\n```{r}\n\nprint(acme, \"cost\", \"p\")\n\n```\n\nFor more advanced printing, you have a few options. \n\n### Formatters\n\nYou can use *formatters* to output a variable in a certain way. You can use formatters in two ways:  \n\n* You can set them on a `Node` using the `SetFormat` method. If you do this, then the formatter will be picked up as a default formatter whenever you `print`, `Get`, convert to `data.frame`, etc.  Formatters can be set on any `Node` in a `data.tree` structure act on any descendant. So you can overwrite a formatter for a sub-tree.\n* You can add an explicit ad-hoc formatter to the `Get` method (see below). This will overwrite default formatters previously set via the `SetFormat` method. You can also set the formatter to `identity` to void a default formatter.\n\nSetting a formatter using the `SetFormat` method:\n\n```{r}\nSetFormat(acme, \"p\", formatFun = FormatPercent)\nSetFormat(acme, \"cost\", formatFun = function(x) FormatFixedDecimal(x, digits = 2))\nprint(acme, \"cost\", \"p\")\n\n```\n\n### Printing using `Get`\n\nFormatting with the `Get` method overwrites any formatters found along the path:\n\n```{r}\ndata.frame(cost = acme$Get(\"cost\", format = function(x) FormatFixedDecimal(x, 2)),\n           p = acme$Get(\"p\", format = FormatPercent))\n           \n\n```\n\n\n\n## Plotting\n\n### `plot`\n\n`data.tree` is mainly a data structure. As it is easy to convert `data.tree` structures to other formats, you have access to a large number of tools to plot a `data.tree` structure. For example, you can plot a `data.tree` structure as a dendrogram, as an ape tree, as a treeview, etc. \nAdditionally, `data.tree` also provides its own plotting facility. It is built on GraphViz/DiagrammeR, and you can access these features via the `plot` and `ToGraphViz` functions. Note that DiagrammeR is not required to use data.tree, so `plot` only works if DiagrammeR is installed on your system. For example:\n\n```{r, eval = FALSE}\nplot(acme)\n```\n\n![acme](assets/acme.png)\n\n### Styling\n\nSimilar to formatters for printing, you can style your tree and store the styling directly in the tree, for later use:\n\n```{r, eval = FALSE}\nSetGraphStyle(acme, rankdir = \"TB\")\nSetEdgeStyle(acme, arrowhead = \"vee\", color = \"grey35\", penwidth = 2)\nSetNodeStyle(acme, style = \"filled,rounded\", shape = \"box\", fillcolor = \"GreenYellow\", \n            fontname = \"helvetica\", tooltip = GetDefaultTooltip)\nSetNodeStyle(acme$IT, fillcolor = \"LightBlue\", penwidth = \"5px\")\nplot(acme)\n```\n\n![acme](assets/acmestyle.png)\n\nFor details on the styling attributes, see http://graphviz.org/Documentation.php .\n\nNote that, by default, most Node style attributes will be inherited. Though, for example, `label` will not be inherited. However, inheritance can be avoided for all style attributes, as for the Accounting node in the following example:\n\n```{r, eval = FALSE}\nSetNodeStyle(acme$Accounting, inherit = FALSE, fillcolor = \"Thistle\", \n             fontcolor = \"Firebrick\", tooltip = \"This is the accounting department\")\nplot(acme)\n```\n\n![acme](assets/acmestyle2.png)\n\nUse `Do` to set style on specific nodes:\n\n```{r, eval = FALSE}\nDo(acme$leaves, function(node) SetNodeStyle(node, shape = \"egg\"))\nplot(acme)\n```\n\n![acme](assets/acmestyle3.png)\n\n### Other Visualisations\n\nHowever, there are also endless other possibilities to visualise `data.tree` structures. There are more examples in the applications vignette. Type `vignette('applications', package = \"data.tree\")`.\n\n#### Dendrogram\n\nFor example, using dendrogram:\n\n```{r}\nplot(as.dendrogram(CreateRandomTree(nodes = 20)), center = TRUE)\n```\n\n#### igraph\n\nOr, using igraph: \n\n```{r echo=FALSE }\nlibrary(igraph, quietly = TRUE, warn.conflicts = FALSE, verbose = FALSE)\n```\n\n\n```{r}\nlibrary(igraph)\nplot(as.igraph(acme, directed = TRUE, direction = \"climb\"))\n```\n\n#### networkD3\n\nOr, using networkD3:\n(you can actually touch these thingies and drag them around, don't be shy!)\n\n```{r}\nlibrary(networkD3)\nacmeNetwork <- ToDataFrameNetwork(acme, \"name\")\nsimpleNetwork(acmeNetwork[-3], fontSize = 12)\n```\n\nAnother example, which at the same time shows conversion from csv:\n\n\n```{r}\nfileName <- system.file(\"extdata\", \"useR15.csv\", package=\"data.tree\")\nuseRdf <- read.csv(fileName, stringsAsFactors = FALSE)\n#define the hierarchy (Session/Room/Speaker)\nuseRdf$pathString <- paste(\"useR\", useRdf$session, useRdf$room, useRdf$speaker, sep=\"|\")\n#convert to Node\nuseRtree <- as.Node(useRdf, pathDelimiter = \"|\")\n\n#plot with networkD3\nuseRtreeList <- ToListExplicit(useRtree, unname = TRUE)\nradialNetwork( useRtreeList)\n\n```\n\n## Tree Conversion\n\nIn order to take advantage of the R eco-system, you can convert your `data.tree` structure to other oft-used data types. The general rule is that, for each target type, there is a one-does-it-all generics, and a few more specialised conversion functions. For example, in order to convert a `data.tree` to a data.frame, you can either use `as.data.frame.Node`, or `ToDataFrameTree`, `ToDataFrameTable`, or `ToDataFrameNetwork`. The documentation for all of these variations is accessible via `?as.data.frame.Node`.\n\n### Converting to `data.frame`\n\nAs you saw just above, creating a `data.frame` is easy. \n\nAgain, note that we always call such methods on the root `Node` of a `data.tree` structure, or on the root `Node` of a subtree:\n\n```{r}\nacmedf <- as.data.frame(acme)\nas.data.frame(acme$IT)\n```\n\nThe same can be achieved by using the more specialised method:\n```{r, eval=FALSE}\nToDataFrameTree(acme)\n```\n\nWe can also add field values of the `Nodes` as columns to the `data.frame`:\n```{r}\nToDataFrameTree(acme, \"level\", \"cost\")\n```\n\nNote that it is not required that the field is set on each and every `Node`.\n\nOther data frame conversions are:\n\n```{r}\nToDataFrameTable(acme, \"pathString\", \"cost\")\n```\n\n```{r}\nToDataFrameNetwork(acme, \"cost\")\n```\n\nAnd, finally, we can also put attributes of our nodes in a column, based on a type discriminator. This sounds more complicated then what it is. Consider the default discriminator, `level`:\n\n```{r}\nToDataFrameTypeCol(acme, 'cost')\n```\n\nLet's look at a somewhat more advanced example. First, let's assume that for the outsourcing project, we have two separate possibilities: Outsourcing to India or outsourcing to Poland:\n\n```{r}\nacme$IT$Outsource$AddChild(\"India\")\nacme$IT$Outsource$AddChild(\"Poland\")\n\n```\n\nNow, with this slightly more complex tree structure, the level is not a usefully discriminator anymore, because some projects are in level 3, while the new projects are in level 4. For this reason, we introduce a type field on our node objects: A node type can be a company (root only), a department (Accounting, Research, and IT), a program (Oursource), and a project (the rest, i.e. all the leaves):\n\n```{r}\nacme$Set(type = c('company', 'department', 'project', 'project', 'department', 'project', 'project', 'department', 'program', 'project', 'project', 'project', 'project'))\n\n```\n\nOur tree now looks like this:\n\n```{r}\nprint(acme, 'type')\n```\n\n\nWe can now create a data.frame in which we have one column per distinct type value. Namely, a company column, a department column, a program column, and a project column. Note that the columns are not hardcoded, but derived dynamically from your data in the tree structure:\n\n```{r}\nToDataFrameTypeCol(acme, type = 'type', prefix = NULL)\n```\n\n\n### Converting to List of Lists\n\nList of lists are useful for various use cases:\n\n* as an intermediate step in converting to JSON, XML, YAML\n* for functions that take a lol as an input. This is especially the case for visualisations and charts, e.g with many html widgets\n* to save a `data.tree` structure as an R object (see performance considerations below)\n\n\n```{r}\ndata(acme)\nstr(as.list(acme$IT))\nstr(ToListExplicit(acme$IT, unname = FALSE, nameName = \"id\", childrenName = \"dependencies\"))\n```\n\n### Converting to other objects\n\nThere are also conversions to igraph objects, to phylo / ape, to dendrogram, and others. For details, see `?as.phylo.Node`, `?as.dendrogram.Node`, `?as.igraph.Node`.\n\n# Tree Traversal\n\nTree traversal is one of the core concepts of trees. See, for example, here: [Tree Traversal on Wikipedia](http://en.wikipedia.org/wiki/Tree_traversal).\n\n## `Get`\n\nThe `Get` method traverses the tree and collects values from each node. It then returns a vector or a list, containing the collected values. \n\nAdditional features of the `Get` method are:\n\n* execute a function on each node, and append the function's result to the returned vector\n* execute a `Node` method on each node, and append the method's return value to the returned vector\n\n\n### Traversal order\n\nThe `Get` method can traverse the tree in various ways. This is called **traversal order**.\n\n#### Pre-Order\n\nThe default traversal mode is **pre-order**. \n\n![pre-order](assets/preorder.png)\n\nThis is what is used e.g. in `print`:\n\n```{r}\nprint(acme, \"level\")\n```\n\n#### Post-Order\n\nThe **post-order** traversal mode returns children first, returning parents only after all its children have been traversed and returned:\n\n![post-order](assets/postorder.png)\n\nWe can use it like this on the `Get` method:\n\n```{r}\nacme$Get('level', traversal = \"post-order\")\n```\n\nThis is useful if your parent's value depends on the children, as we'll see below.\n\n#### Ancestor\n\nThis is a non-standard traversal mode that does not traverse the entire tree. Instead, the ancestor mode starts from a `Node`, then walks the tree along the path from parent to parent, up to the root.\n\n```{r}\n\ndata.frame(level = agile$Get('level', traversal = \"ancestor\"))\n\n```\n\n### Filter and Prune\n\nYou can add a filter and/or a prune function to the `Get` method. These functions have to take a `Node` as an input, and return `TRUE` if the `Node` should be considered, and `FALSE` otherwise. \nThe difference between the `pruneFun` and the `filterFun` is that filters act only on specific nodes, whereas if the `pruneFun` returns `FALSE`, then the entire sub-tree spanned by the `Node` is ignored.\n\nFor example:\n\n\n```{r}\nacme$Get('name', pruneFun = function(x) x$position <= 2)\n```\n\n\nThere are also some convenient filter functions available in the package, such as `isLeaf`, `isRoot`, `isNotLeaf`, etc.\n\n```{r}\nacme$Get('name', filterFun = isLeaf)\n```\n\n\n### Attributes\n\nThe `attribute` parameter determines what is collected. This is called `attribute`, but it should not be confused with R's concept of object attributes (e.g. `?attributes`).\nIn this context, an attribute can be either:\n\n* the name of a `Node` field\n* the name of a `Node` method or active\n* a function, whose first argument must be a Node\n\nThroughout this document, we refer to `attribute` in this sense.\n\n#### Field\n\n```{r}\nacme$Get('name')\n```\n\n\n#### Method\n\nYou can pass a standard R function to the `Get` method (and thus to `print`, `as.data.frame`, etc.). The only requirement this function must satisfy is that its first argument be of class `Node`. Subsequent arguments can be added through the ellipsis (...). For example:\n\n```{r}\n\nExpectedCost <- function(node, adjustmentFactor = 1) {\n  return ( node$cost * node$p * adjustmentFactor)\n}\n\nacme$Get(ExpectedCost, adjustmentFactor = 0.9, filterFun = isLeaf)\n\n```\n\n\n\n#### Using recursion\n\nRecursion comes naturally with data.tree, and it is one of its core strengths: \n\n```{r}\nCost <- function(node) {\n  result <- node$cost\n  if(length(result) == 0) result <- sum(sapply(node$children, Cost))\n  return (result)\n}\n\nprint(acme, \"p\", cost = Cost)\n```\n\nThere is a built-in function that would make this example even simpler: `Aggregate`. It is explained below.\n\n## `Do`\n\nDo is similar to `Get` in that it also traverses a tree in a specific traversal order. However, instead of fetching an attribute, it will (surprise!) do something, namely run a function. For example, we can tell the `Do` method to assign a value to each `Node` it traverses. This is especially useful if the attribute parameter is a function, as in the previous examples. For instance, we can store the aggregated cost for later use and printing:\n\n```{r}\n\nacme$Do(function(node) node$cost <- Cost(node), filterFun = isNotLeaf)\nprint(acme, \"p\", \"cost\")\n\n```\n\n\n## `Set`\n\nThe `Set` method is the counterpart to the `Get` method. The `Set` method takes a vector or a single value as an input, and traverses the tree in a certain order. Each `Node` is assigned a value from the vector, one after the other, recycling.\n\n### Assigning values\n\n```{r}\nacme$Set(id = 1:acme$totalCount)\n\nprint(acme, \"id\")\n```\n\nThe `Set` method can take multiple vectors as an input, and, optionally, you can define the name of the attribute. Finally, just as for the `Get` method, the **traversal order** is important for the `Set`.\n\n```{r}\nsecretaries <- c(3, 2, 8)\nemployees <- c(52, 43, 51)\nacme$Set(secretaries, \n         emps = employees,\n         filterFun = function(x) x$level == 2)\nprint(acme, \"emps\", \"secretaries\", \"id\")\n\n\n```\n\n\n### Deleting attributes\n\nThe `Set` method can also be used to assign a single value directly to all `Nodes` traversed. For example, to remove the `avgExpectedCost`, we assign `NULL` on each node, using the fact that the `Set` recycles:\n\n```{r}\nacme$Set(avgExpectedCost = NULL)\n```\n\nHowever, note that setting a field to `NULL` will not make it gone for good. You will still see it:\n```{r}\nacme$attributesAll\n```\n\nIn order remove it completely, you can use the `RemoveAttribute` method:\n\n```{r}\nacme$Do(function(node) node$RemoveAttribute(\"avgExpectedCost\"))\n```\n\n\n\n### Using Set and function assignment\n\nEarlier, we saw that we can add a function dynamically to a `Node`. We can, of course, also do this via the `Set` method\n\n```{r}\nacme$Set(cost = c(function(self) sum(sapply(self$children, \n                                            function(child) GetAttribute(child, \"cost\")))), \n         filterFun = isNotLeaf)\nprint(acme, \"cost\")\nacme$IT$AddChild(\"Paperless\", cost = 240000)\nprint(acme, \"cost\")\n```\n\n\n## `Traverse` and explicit traversal\n\nPreviously, we have used the `Get`, `Set` and `Do` methods in their OO-style version. This is often very convenient for quick access to variables. However, sometimes you want to re-use the same traversal for multiple sequential operations. For this, you can use what is called **explicit traversal**. It works like so:\n\n```{r}\ntraversal <- Traverse(acme, traversal = \"post-order\", filterFun = function(x) x$level == 2)\nSet(traversal, floor = c(1, 2, 3))\nDo(traversal, function(x) {\n    if (x$floor <= 2) {\n      x$extension <- \"044\"\n    } else {\n      x$extension <- \"043\"\n    }\n  })\nGet(traversal, \"extension\")\n\n```\n\n\n# Advanced Features\n\n## `Aggregate`\n\nThe `Aggregate` method provides a shorthand for the oft-used case when a parent is the aggregate of its child values, as seen in the previous example. `Aggregate` calls a function recursively on children. If a child holds the attribute, that value is returned. Otherwise, the attribute is collected from all children, and aggregated using the `aggFun`. For example:\n\n\n\n```{r}\nAggregate(node = acme, attribute = \"cost\", aggFun = sum)\n\n```\n\nWe can also use this in the `Get` method, of course:\n\n```{r, eval=FALSE}\nacme$Get(Aggregate, \"cost\", sum)\n```\n\nNote, however, that this is not very efficient: `Aggregate` will be called twice on, say, *IT*: Once when the traversal passes *IT* itself, the second time recursively when `Aggregate` is called on the root. For this reason, we have the option to store/cache the calculated value along the way. For one thing, this is a convenient way to save an additional `Set` call in case we want to store the aggregated value. Additionally, it speeds up calculation because `Aggregate` on an ancestor will use a cached value on a descendant:\n\n```{r}\nacme$Do(function(node) node$cost <- Aggregate(node, attribute = \"cost\", aggFun = sum), traversal = \"post-order\")\nprint(acme, \"cost\")\n\n```\n\n\n## `Cumulate`\n\nIn its simplest form, the `Cumulate` function just sums up an attribute value along siblings, taking into consideration all siblings before the `Node` on which `Cumulate` is called:\n\n```{r}\nCumulate(acme$IT$`Go agile`, \"cost\", sum)\n\n```\n\nOr, to find the minimum cost among siblings:\n\n```{r}\nCumulate(acme$IT$`Go agile`, \"cost\", min)\n\n```\n\nThis can be useful in combination with traversal, e.g. to calculate a running sum among siblings. Specifically, the `cacheAttribute` lets you store the running sum in a field. This not only speeds up calculation, but lets you re-use the calculated values later:\n\n```{r}\n\nacme$Do(function(node) node$cumCost <- Cumulate(node, \n                                                attribute = \"cost\", \n                                                aggFun = sum))\nprint(acme, \"cost\", \"cumCost\")\n\n```\n\n\n## `Clone`\n\nAs stated above, `Nodes` exhibit reference semantics. If you call, say, `Set`, then this changes the `Nodes` in the tree. The changes will be visible for all variables having a reference on the `data.tree` structure. As a consequence, you might want to \"save away\" the current state of a structure. To do this, you can `Clone` an entire tree:\n\n```{r}\nacmeClone <- Clone(acme)\nacmeClone$name <- \"New Acme\"\n# acmeClone does not point to the same reference object anymore:\nacme$name == acmeClone$name\n```\n\n\n## `Sort`\n\nWith the `Sort` method, you can sort an entire tree, a sub-tree, or children of a specific `Node`. The method will sort recursively and sort children with respect to a child attribute. As explained earlier, the child attribute can be a function or a method.\n\n```{r}\nSort(acme, \"name\")\nacme\nSort(acme, Aggregate, \"cost\", sum, decreasing = TRUE, recursive = TRUE)\nprint(acme, \"cost\", aggCost = acme$Get(Aggregate, \"cost\", sum))\n```\n\n## `Prune`\n\nYou can prune sub-trees out of a tree, by that removing an entire sub-tree from a tree. There are two variations of this:\n* *temporary* pruning, e.g. just for printing: This is the `pruneFun` parameter, e.g. in `Get`\n* *side effect* or *permanent* pruning, meaning that you modify your `data.tree` structure for good. This is achieved with the `Prune` method.\n\nConsider the following example of permanent pruning:\n\n```{r}\nacme$Do(function(x) x$cost <- Aggregate(x, \"cost\", sum))\nPrune(acme, function(x) x$cost > 700000)\nprint(acme, \"cost\")\n```\n\n\n# Performance Considerations\n\n## CPU\n\nThe `data.tree` package has been built to work with hierarchical data, to support visualization, to foster rapid prototyping, and for other applications where development time saved is more important than computing time lost. Having said this, it becomes clear that big data and `data.tree` do not marry particularly well. Don't expect R to build your `data.tree` structure with a few million `Nodes` during your cigarette break. Do not try to convert a gigabyte JSON document to a `data.tree` structure in a testthat test case.\n\nHowever, if you are respecting the following guidelines, I promise that you and your `Nodes` will have a lot of fun together. So here it goes:\n\n1. Creating a `Node` is relatively expensive. `CreateRegularTree(6, 6)` creates a `data.tree` structure with 9331 `Nodes`. On an AWS c4.large instance, this takes about 2.5 seconds.\n2. `Clone` is similar to `Node` creation, with an extra penalty of about 50%.\n3. Traversing (`Traverse`, `Get`, `Set` and `Do`) is relatively cheap. \n\nThis is really what you would expect. `data.tree` builds on R6, i.e. reference objects. There is an overhead in creating them, as your computer needs to manage the references they hold. However, performing operations that change your tree (e.g. `Prune` or `Set`) are often faster than value semantics, as your computer does not need to copy the entire object in memory.\n\nJust to give you an order of magnitude: The following times are achieved on an AWS c4.large instance:\n\n```{r, eval = FALSE}\nsystem.time(tree <- CreateRegularTree(6, 6))\n```\n\n```{r, echo = FALSE}\nc(user = 2.499, system = 0.009, elapsed = 2.506)\n```\n\n```{r, eval = FALSE}\nsystem.time(tree <- Clone(tree))\n```\n\n```{r, echo = FALSE}\nc(user = 3.704, system = 0.023, elapsed = 3.726)\n```\n\n```{r, eval = FALSE}\nsystem.time(traversal <- Traverse(tree))\n```\n\n```{r, echo = FALSE}\nc(user = 0.096, system = 0.000, elapsed = 0.097)\n```\n\n```{r, eval = FALSE}\nsystem.time(Set(traversal, id = 1:tree$totalCount))\n```\n\n```{r, echo = FALSE}\nc(user = 0.205, system = 0.000, elapsed = 0.204)\n```\n\n```{r, eval = FALSE}\nsystem.time(ids <- Get(traversal, \"id\"))\n```\n\n```{r, echo = FALSE}\nc(user = 0.569, system = 0.000, elapsed = 0.569)\n```\n\n\n```{r, eval = FALSE}\nleaves <- Traverse(tree, filterFun = isLeaf)\nSet(leaves, leafId = 1:length(leaves))\nsystem.time(Get(traversal, function(node) Aggregate(node, \"leafId\", max)))\n```\n\n```{r, echo = FALSE}\nc(user = 1.418, system = 0.000, elapsed = 1.417)\n```\n\nWith caching, you can save some time:\n\n```{r, eval = FALSE}\nsystem.time(tree$Get(function(node) Aggregate(tree, \"leafId\", max, \"maxLeafId\"), traversal = \"post-order\"))\n```\n\n```{r, echo = FALSE}\nc(user = 0.69, system = 0.00, elapsed = 0.69)\n```\n\n\n## Memory\n\ndata.tree structures have a relatively large memory footprint. However, for every-day applications using modern computers, this will not normally have an impact on your work **except when saving a `data.tree` structure to disk**. \n\nFor an explanation why that is the case, you might want to read this answer on [Stack Overflow](http://stackoverflow.com/questions/13912867/empty-r-environment-becomes-large-file-when-saved).\n\nDepending on your development environment, you might want to turn off the option to save the workspace to .RData on exit.\n"
  },
  {
    "path": "vignettes/intro.banner.html",
    "content": "<img src=\"banner_intro.jpg\" alt=\"Banner\">\n<style type=\"text/css\">\n.rosabox { \n  background-color:#FFDDDD; \n  font-size: 90%;\n  border-radius: 20px;\n  padding:2em; \n  line-height: 1.6em;}\n</style>\n<br>\n<br>\n\n<div class=\"rosabox\">\nAbraham Lincoln once said, \"Give me six hours to chop down a tree and I will spend the first four sharpening the axe.\"\n<br>Aunt Margaret used to say, \"If you dream of a forest, you'd better learn how to plant a tree.\"\n<br>data.tree says, \"No matter if you are a lumberjack or a tree hugger. I will be your sanding block, and I will be your seed.\"\n</div>"
  }
]