Build a file diagram for an R code

2019-06-18 04:39发布

问题:

I need to work on a relatively large R code written by someone else. The code has no documentation, and it's split into countless files, each one of which can contain one or more functions. The original author didn't use a Makefile, so there's no documentation on what's calling what.

As a first step, I'd like to build a dendrogram. I mean a tree whose root is the main file, the interior nodes are the various files called, and the leaves (terminal nodes) are files which don't call functions defined in other files. Is there a way to do that automatically? A picture output would be great, but even a text file would do. R Studio solutions would also be ok.

EDIT: apparently my description is not clear enough, thus I add a very simple (trivial, actually) example. Assume I have 4 source files main.r, foo.r, bar.r and blargh.r, all in the same folder (the real case has ~50 files all "tidily" stored in the same ruddy folder, together with input/output files). The content of main.r is:

# main.r
source("foo.r")
source("bar.r")
source("blargh.r")

foo()
bar()

foo.r:

# foo.r
foo <- function(){
    print("I'm foo")
    blargh()
}

bar.r:

# bar.r
bar <- function(){
    print("I'm bar")
    blargh()
}

blargh.r

# blargh.r
blargh <- function(){
    print("I'm blargh")
}

What I need to generate is a diagram like this:

  main.r
   ¦--foo.r                 
   ¦   ¦       
   ¦   °--blargh.r       
   ¦       
   °--bar.r                 
       ¦    
       °--blargh.r          

回答1:

Assuming that the path contains the all the sub-directories and files,

files <- list.files(path, full.names = TRUE, recursive = TRUE)
#for eg.
files<- c(
    "root/dir1/some/file1.R", 
    "root/dir1/another1/file2.R", 
    "root/dir1/another1/new/file3.R", 
    "root/dir2/some/data1.csv", 
    "root/dir2/more/data2.csv"
)

Now you have all your files, in files variable.

library(data.tree)
library(plyr)

a <- lapply(strsplit(files, "/"), function(z) as.data.frame(t(z)))
a <- rbind.fill(a)
mytree <- data.tree::as.Node(data.frame(pathString = path))
plot(mytree)

1  root                  
2   ¦--dir1                 
3   ¦   ¦--some          
4   ¦   ¦   °--file1.R    
5   ¦   °--another1       
6   ¦       ¦--file2.R    
7   ¦       °--new      
8   ¦           °--file3.R
9   °--dir2                 
10      ¦--some          
11      ¦   °--data1.csv  
12      °--more          
13          °--data2.csv  

Note : This structure is called a dendogram. Hope this helps.