Как создать дендрограмму из дерева каталогов?

Указание корневого абсолютного пути каталога. Как создать объект дендрограммы всего пути ниже него, чтобы я мог визуализировать дерево каталогов с помощью R?

Предположим, что следующий вызов возвратил следующие листовые узлы.

list.files(path, full.names = TRUE, recursive = TRUE)

root/a/some/file.R
root/a/another/file.R
root/a/another/cool/file.R
root/b/some/data.csv
root/b/more/data.csv

Я хотел бы сделать график в R, как вывод программы unix tree:

root
├── a
│   ├── another
│   │   ├── cool
│   │   │   └── file.R
│   │   └── file.R
│   └── some
│       └── file.R
└── b
    ├── more
    │   └── data.csv
    └── some
        └── data.csv

Было бы особенно полезно, если бы решение включало разложение дерева файловой системы на два data.frame:

  • таблица узлов (с которой я мог бы включать такие атрибуты, как дата изменения)
  • и таблица ребер (также с атрибутами)

А затем построим объект дендрограммы из этих двух data.frame s.

Ответ 1

Здесь возможный подход, чтобы получить то, о чем вы изначально просили, - такую систему, как дерево. Это даст объекту data.tree который достаточно гибок и может быть создан для построения графика, как вы, возможно, захотите, но мне не совсем понятно, что вы хотите:

path <- c(
    "root/a/some/file.R", 
    "root/a/another/file.R", 
    "root/a/another/cool/file.R", 
    "root/b/some/data.csv", 
    "root/b/more/data.csv"
)


library(data.tree); library(plyr)

x <- lapply(strsplit(path, "/"), function(z) as.data.frame(t(z)))
x <- rbind.fill(x)
x$pathString <- apply(x, 1, function(x) paste(trimws(na.omit(x)), collapse="/"))
(mytree <- data.tree::as.Node(x))

1  root                  
2   ¦--a                 
3   ¦   ¦--some          
4   ¦   ¦   °--file.R    
5   ¦   °--another       
6   ¦       ¦--file.R    
7   ¦       °--cool      
8   ¦           °--file.R
9   °--b                 
10      ¦--some          
11      ¦   °--data.csv  
12      °--more          
13          °--data.csv  


plot(mytree)

Вы можете получить нужные вам части (я думаю), но для этого потребуется, чтобы вы выполнили часть работы и data.tree преобразование между типами данных в data.tree: https://cran.r-project.org/web/packages/data.tree/виньетки /data.tree.html # дерево преобразования

Я использую этот подход в своей функции tree пакетов pathr, когда use.data.tree = TRUE https://github.com/trinker/pathr#tree

РЕДАКТИРОВАТЬ За @Luke комментарий ниже... data.tree::as.Node принимает путь:

(mytree <- data.tree::as.Node(data.frame(pathString = path)))

                levelName
1  root2                 
2   ¦--a                 
3   ¦   ¦--some          
4   ¦   ¦   °--file.R    
5   ¦   °--another       
6   ¦       ¦--file.R    
7   ¦       °--cool      
8   ¦           °--file.R
9   °--b                 
10      ¦--some          
11      ¦   °--data.csv  
12      °--more          
13          °--data.csv  

Ответ 2

Если вы находитесь в Windows, вы можете использовать мой пакет dir2json, установив его следующим образом:

drat::addRepo("stlarepo")
install.packages("dir2json")

Также возможно использовать его в Linux, но есть DLL, связанная с динамическими библиотеками GHC, которые должны быть установлены в системе (в то время как эта DLL автономна в Windows).

> library(dir2json)
> cat(dir2tree("src"))
src
|
`- contrib
   |
   +- PACKAGES.gz
   |
   +- PACKAGES
   |
   +- jsonAccess_0.1.1.tar.gz
   |
   +- expansions_1.2.tar.gz
   |
   `- dir2json_2.1.0.tar.gz
> cat(dir2tree("src", vertical=TRUE))
                                            src                                             
                                             |                                              
                                          contrib                                           
                                             |                                              
      ---------------------------------------------------------------------------           
     /          |                 |                       |                      \          
PACKAGES.gz  PACKAGES  jsonAccess_0.1.1.tar.gz  expansions_1.2.tar.gz  dir2json_2.1.0.tar.gz

Пакет также содержит приложение Shiny, которое генерирует интерактивное представление дерева каталогов Reingold-Tilford:

> dir2json::shinyDirTree(".")

Папка Reingold-Tilford

Ответ 3

Стоит добавить, что отличный пакет fs предлагает функцию dir_tree которая доставляет эту функциональность в R очень удобным способом.

tmp_dir <- tempdir()
# Create some directories
for (i in 1:10) {
    dir.create(path = file.path(tmp_dir,
                                basename(tempfile(pattern = "dir")),
                                basename(tempfile(pattern = "sub_dir"))),
               recursive = TRUE)
}
# Create directory tree
fs::dir_tree(path = tmp_dir, recurse = TRUE)

Результаты

/tmp/RtmpEhB0ne
├── dir15213121dd5903
│   └── sub_dir1521315a5425ba
├── dir152131227b086f
│   └── sub_dir1521314255d96b
├── dir152131353e6603
│   └── sub_dir1521315b52aeed
├── dir15213136870535
│   └── sub_dir15213127b34f64
├── dir1521313bbf738b
│   └── sub_dir152131473939ea
├── dir152131403f4fd5
│   └── sub_dir152131115296e7
├── dir152131503d0d55
│   └── sub_dir15213114368572
├── dir1521316f0bb0c3
│   └── sub_dir1521314aea266b
├── dir1521317fe305e9
│   └── sub_dir152131bcfe8a
└── dir1521319800dfb
    └── sub_dir15213129defd4a

Помимо печати дерева каталогов, обнаруженные пути могут быть возвращены объекту.

sink(file = tempfile(fileext = ".log"))
res_fs_tree <- fs::dir_tree(path = tmp_dir, recurse = TRUE)
sink()
res_fs_tree[[1]]
# [1] "/tmp/RtmpEhB0ne/dir15213121dd5903/sub_dir1521315a5425ba"