---
title: "Functiondepends - usage"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Functiondepends - usage}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  out.width = "100%",
  message = FALSE,
  warning = FALSE,
  fig.width = 10, 
  fig.height = 5,
  fig.fullwidth = TRUE
)
```

```{r setup}
library(functiondepends)
```

```{r, include = FALSE}
envir <- functiondepends:::envir
functions <- functiondepends:::functions
```

```{r, eval = FALSE}
# Create environment for loaded functions 
envir <- new.env()
# Search recursively source files
functions <- find_functions(".", envir = envir, recursive = TRUE)
```

```{r}
functions
```

Search for dependencies of function `find_functions` within parsed functions:

```{r dependency}
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}
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 function_in_path_info}
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}
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}
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 degree}
dependency <- find_dependencies(unique(functions$Function), envir = envir, in_envir = TRUE)
dependency %>% 
  distinct(Target, TargetInDegree) %>% 
  arrange(-TargetInDegree)
```

```{r network}
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_full}
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.8

plot(
  g,
  vertex.color = "grey",
  edge.color = "grey",
  edge.arrow.size = .4,
  main = "Full functions dependency graph"
)
```

