Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jakubsob/functiondepends
Find Functions and their Dependencies
https://github.com/jakubsob/functiondepends
Last synced: 2 months ago
JSON representation
Find Functions and their Dependencies
- Host: GitHub
- URL: https://github.com/jakubsob/functiondepends
- Owner: jakubsob
- License: other
- Created: 2020-10-13T19:34:15.000Z (about 4 years ago)
- Default Branch: master
- Last Pushed: 2022-02-21T19:06:14.000Z (almost 3 years ago)
- Last Synced: 2023-07-04T18:01:39.471Z (over 1 year ago)
- Language: R
- Homepage: https://jakubsob.github.io/functiondepends/
- Size: 2.89 MB
- Stars: 11
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.Rmd
- License: LICENSE
Awesome Lists containing this project
README
---
output: github_document
---```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%",
message = FALSE,
warning = FALSE
)
library(functiondepends)
```# functiondepends
[![R build status](https://github.com/jakubsob/functiondepends/workflows/R-CMD-check/badge.svg)](https://github.com/jakubsob/functiondepends/actions)
[![license](https://img.shields.io/badge/license-mit-lightgrey.svg)](https://choosealicense.com/)
[![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/functiondepends)](https://cran.r-project.org/package=functiondepends)
[![CRAN_latest_release_date](https://www.r-pkg.org/badges/last-release/functiondepends)](https://cran.r-project.org/package=functiondepends)
[![CRAN status](https://cranlogs.r-pkg.org/badges/grand-total/functiondepends)](https://CRAN.R-project.org/package=functiondepends)The goal of functiondepends is to allow for tidy exploration of unstructured codebase without evaluation of code.
## Installation
One can install `functiondepends` from CRAN:
```{r, eval = FALSE}
install.packages("functiondepends")
```or development version from GitHub:
```{r, eval = FALSE}
# install.packages("devtools")
devtools::install_github("jakubsob/functiondepends")
```## Examples
```{r, include = FALSE}
envir <- functiondepends:::envir
functions <- functiondepends:::functions
``````{r, eval = FALSE}
library(functiondepends)
# Create environment for loaded functions
envir <- new.env()
# Search recursively current directory
functions <- find_functions(".", envir = envir, recursive = TRUE)
``````{r}
functions
```Search for dependencies of function `find_functions` within parsed functions:
```{r}
dependency <- find_dependencies("find_functions", envir = envir, in_envir = TRUE)
dependency
```Note that `SourceNamespace` column has value `user-defined` as the functions are searched within source of the package.
Search for all dependencies of `find_functions` function:
```{r functions_in_path, fig.height=4}
library(ggplot2)
library(dplyr)dependency <- find_dependencies("find_functions", envir = envir, in_envir = FALSE)
dependency %>%
slice_max(SourceRep, n = 10) %>%
mutate(Source = reorder(Source, SourceRep)) %>%
ggplot(aes(x = Source, y = SourceRep, fill = SourceNamespace)) +
geom_col() +
coord_flip() +
labs(caption = "Top 10 most repeated calls in 'find_functions'.")
```Note that name `df` is often used to store object of type `data.frame`. `df` is also a name of F distribution density function from `stats` package. If you suspect that given function ought not to use a specific package, see the source code of function to check the context. To do so, one can execute `find_dependencies` function with `add_info` argument set to `TRUE`.
```{r}
library(tidyr)dependency <- find_dependencies("find_functions", envir = envir, in_envir = FALSE, add_info = TRUE)
dependency %>%
filter(SourceNamespace == "stats") %>%
select(Source, SourcePosition, SourceContext) %>%
unnest(c(SourcePosition, SourceContext))
```One can see that indeed `df` is not a call to function `stats::df`.
```{r target_degree, fig.height=4}
dependency <- find_dependencies(unique(functions$Function), envir = envir, in_envir = FALSE)
dependency %>%
distinct(Target, TargetInDegree) %>%
mutate(Target = reorder(Target, TargetInDegree)) %>%
ggplot(aes(x = Target, y = TargetInDegree)) +
geom_col() +
coord_flip() +
labs(caption = "Functions with most function calls.")
``````{r namespace_count, fig.height=4}
dependency <- find_dependencies(unique(functions$Function), envir = envir, in_envir = FALSE)
dependency %>%
group_by(SourceNamespace) %>%
tally(name = "Count") %>%
slice_max(Count, n = 10) %>%
mutate(SourceNamespace = reorder(SourceNamespace, Count)) %>%
ggplot(aes(x = SourceNamespace, y = Count)) +
geom_col() +
coord_flip() +
labs(caption = "Top 10 used namespaces.")
```See which user-defined functions depend most on other user-defined functions within searched codebase.
```{r}
dependency <- find_dependencies(unique(functions$Function), envir = envir, in_envir = TRUE)
dependency %>%
distinct(Target, TargetInDegree) %>%
arrange(-TargetInDegree)
``````{r network_env, fig.height=4}
library(igraph)edges <- dependency %>%
select(Source, Target) %>%
na.omit()vertices <- unique(c(dependency$Source, dependency$Target))
vertices <- vertices[!is.na(vertices)]g <- graph_from_data_frame(d = edges, vertices = vertices)
deg <- degree(g, mode = "in")
V(g)$size <- deg * 10 + 5
V(g)$label.cex <- (degree(g, mode = "in", normalized = TRUE) + 1)plot(
g,
vertex.color = "grey",
edge.color = "grey",
edge.arrow.size = .4,
main = "Functions dependency graph"
)
``````{r network, fig.height=4}
dependency <- find_dependencies(unique(functions$Function), envir = envir, in_envir = FALSE)
edges <- dependency %>%
select(Source, Target) %>%
na.omit()
vertices <- unique(c(edges$Source, edges$Target))g <- graph_from_data_frame(edges)
deg <- degree(g, mode = "in")
V(g)$size <- deg
V(g)$label.cex <- (degree(g, mode = "in", normalized = TRUE) + 1) / 1.8plot(
g,
vertex.color = "grey",
edge.color = "grey",
edge.arrow.size = .4,
main = "Full functions dependency graph"
)
```