开发者

Generating a Call Graph in R

I've been given a big chunk of poorly formatted monolithic R code with plenty of functions, and I'd like to work out what functions call what functions.

I thought I could use roxygen's @callGraph stuff, but a) the code needs to be in a package, which will be a headache with this code, and b) it doesn't even seem to work when I do run it on a simple package of mine. I see a posting from one of the Roxygen authors saying call graph generation is disabled because of the Rgr开发者_如何学Caphviz dependency, but the code is there. Anyway.

Anyone got a better way of quickly working out that foo calls bar, baz, and qux, and that qux calls quux?

Edit: Solutions based on R's profiling system are great, assuming you can actually run the code... Half the stuff in the files doesn't get run, and I don't know what it does... Static analysis is too much to hope for, I guess.

Edit 2: Roxygen's call graph stuff seems to do a static analysis, based on recursive descent of the expression of the function and checking for is.callable. It would be lovely to be able to run this on any function... I may play with this tomorrow...


Would profr help you out? From the documentation:

> ?profr
> glm_ex <- profr(example(glm))
Read 17 items
>      head(glm_ex)
             f level time start  end  leaf source
8      example     1 0.32  0.00 0.32 FALSE  utils
9  <Anonymous>     2 0.04  0.00 0.04 FALSE   <NA>
10      source     2 0.28  0.04 0.32 FALSE   base
11  prepare_Rd     3 0.02  0.00 0.02 FALSE   <NA>
12      render     3 0.02  0.02 0.04 FALSE   <NA>
13 getSrcLines     3 0.02  0.04 0.06 FALSE   base
>      summary(glm_ex)
               f          level             time          start       
 eval.with.vis  :10   Min.   : 1.000   Min.   :0.02   Min.   :0.0000  
 <Anonymous>    : 3   1st Qu.: 4.000   1st Qu.:0.02   1st Qu.:0.1200  
 lazyLoadDBfetch: 3   Median : 6.000   Median :0.02   Median :0.2000  
 %in%           : 3   Mean   : 7.211   Mean   :0.03   Mean   :0.1769  
 inherits       : 3   3rd Qu.: 9.000   3rd Qu.:0.02   3rd Qu.:0.2600  
 is.factor      : 3   Max.   :22.000   Max.   :0.32   Max.   :0.3000  
 (Other)        :65                                                   
      end            leaf            source         
 Min.   :0.0200   Mode :logical   Length:90         
 1st Qu.:0.1500   FALSE:75        Class :character  
 Median :0.2400   TRUE :15        Mode  :character  
 Mean   :0.2069   NA's :0                           
 3rd Qu.:0.2800                                     
 Max.   :0.3200                                     

> plot(glm_ex)

Generating a Call Graph in R

Not quite what you are after, but you may be able to adapt it to your needs.


The CodeDepends package (CRAN, website, GitHub) looks interesting, I haven't looked into it though. Among others, it promises

  • creating call graphs between sets of functions

presumably through the makeCallGraph() function.


I have not used it, but a quick look at the proftools package indicates that it can do this. You'll have to run Rprof first and then use the proftools to analyze the output. I think you want the plotProfileCallGraph() function.


Besides proftools and profr, there is the Perl script by Romain on the R Wiki. Combined with graphviz, it does graphs (with edges weighted) -- see here for more.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜