Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
470 views
in Technique[技术] by (71.8m points)

r - How to build a dendrogram from a directory tree?

Given a root absolute directory path. How do I generate a dendrogram object of all path's below it so that I can visualize the directory tree with R?

Suppose the following call returned the following leaf nodes.

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

I'd like to make a plot in R like the output of the unix tree program:

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

It would be especially useful if the solution involved decomposing the file system tree into two data.frame's:

  1. a table of nodes (with which I could include attributes such as modification date)
  2. and a table of edges (also with attributes)

And then building the dendrogram object from those two data.frames.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here's a possible approach to get what you originally asked for which is a system like tree. This will give a data.tree object that's pretty flexible and could be made to plot like you might want but it's not entirely clear to me what you want:

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)

You can get the parts you want (I think) but it'll require you to do the leg work and figure out conversion between data types in data.tree: https://cran.r-project.org/web/packages/data.tree/vignettes/data.tree.html#tree-conversion

I use this approach in my pathr package's tree function when use.data.tree = TRUE https://github.com/trinker/pathr#tree

EDIT Per@Luke's comment below...data.tree::as.Node takes a path directly:

(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  

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...