-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathREADME.Rmd
More file actions
407 lines (307 loc) · 19 KB
/
Copy pathREADME.Rmd
File metadata and controls
407 lines (307 loc) · 19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
library(manynet)
list_functions <- function(string){
paste0("`", paste(paste0(ls("package:manynet")[grepl(string, ls("package:manynet"))], "()"), collapse = "`, `"), "`")
}
list_data <- function(string){
paste0("`", paste(paste0(ls("package:manynet")[grepl(string, ls("package:manynet"))]), collapse = "`, `"), "`")
}
```
# manynet
<img src="man/figures/logo.png" align="right" alt="manynet logo" width="150"/>
<!-- badges: start -->
[](https://lifecycle.r-lib.org/articles/stages.html#maturing)



[](https://app.codecov.io/gh/stocnet/manynet?branch=main)
<!-- [](https://www.codefactor.io/repository/github/stocnet/manynet) -->
<!-- [](https://bestpractices.coreinfrastructure.org/projects/4559) -->
<!-- [](https://doi.org/10.5281/zenodo.7076396) -->
<!-- see https://zenodo.org/record/7076396 -->
<!--  -->
<!-- badges: end -->
## About the package
While many awesome packages for network analysis exist for R,
all with their own offerings and advantages,
they also all have their own vocabulary, syntax,
and expected formats for data inputs and analytic outputs.
Many of these packages only work on _some_ types of networks
(usually one-mode, simple, directed or undirected networks) for _some_ types of analysis;
if you want to analyse a different type of network or try a different analysis,
a different package is needed.
This can make learning and using network analysis tools in R challenging.
By contrast, `{manynet}` offers _many_ tools that help researchers make, manipulate, and modify _many_ (if not most) types and kinds of networks,
including matrices, edgelists, and objects from other packages such as `{igraph}`, `{network}`, `{tidygraph}`, `{diffnet}`, and `{siena}`,
as well as one-mode and two-mode, directed and undirected, weighted, unweighted, and signed,
longitudinal and dynamic networks.
If you have social network data, `{manynet}` probably has the tools to help you work with it.
NB: If you are looking for the visualisation functions that used to be
in `{manynet}`, these have been migrated to their own package `{autograph}`.
If you are looking for the network analytic functions that used to be in
`{manynet}`, these have been migrated to their own package `{netrics}`.
If you install and load `{migraph}`,
all these packages will be installed and loaded and you can use all functionality, past and present.
- [Making](#making)
- [Importing network data](#importing-network-data)
- [Identifying network data](#identifying-network-data)
- [Inventing network data](#inventing-network-data)
- [Manipulating](#manipulating)
- [Translating network data](#translating-network-data)
- [Wrangling with dplyr-style verbs](#wrangling-with-dplyr-style-verbs)
- [Modifying](#modifying)
- [Reformatting](#reformatting)
- [Transforming](#transforming)
- [Splitting and Joining](#splitting-and-joining)
- [Installation](#installation)
- [Stable](#stable)
- [Development](#development)
- [Relationship to other packages](#relationship-to-other-packages)
- [Funding details](#funding-details)
## Making
Networks can come from many sources and be found in many different formats:
some can be found in this or other packages,
some can be created or generated using functions in this package,
and others can be downloaded from the internet and imported from your file system.
`{manynet}` provides tools to make networks from all these sources in any number of common formats.
#### Importing network data
`{manynet}` offers a number of options
for importing network data found in other repositories.
Besides importing and exporting to Excel edgelists, nodelists, and (bi)adjacency matrices,
there are specific routines included for
[UCINET](http://www.analytictech.com/archive/ucinet.htm),
[Pajek](http://mrvar.fdv.uni-lj.si/pajek/),
[Gephi](https://gephi.org),
and GraphML files, e.g.:
<img src="https://www.jameshollway.com/post/manynet/README-import-graph-1.png" alt="Graph of manynet input/output formats"/>
```{r import-graph, echo = FALSE, dpi = 300, fig.height=2.5, eval=FALSE}
library(patchwork)
library(ggplot2)
imports <- igraph::graph_from_literal(ucinet:pajek+--+stocnet,
matrix:graphml:gexf+--+stocnet,
dynetml--+stocnet,
edgelist:nodelist+--+tibble)
imports <- imports |> mutate(type = ifelse(node_labels(imports)%in% c("stocnet","tibble"), TRUE, FALSE))
graphr(imports, node_size = 4)
```
If you cannot remember the file name/path, then just run `read_*()` with the parentheses empty,
and a file selection popup will open so that you can browse through your file system to find the file.
Usually both `read_*()` and `write_*()` are offered to make sure that `{manynet}` is compatible with your
larger project and analytic workflow.
- `r list_functions("^read_")`
- `r list_functions("^write_")`
#### Identifying network data
There may be no need to import network data though, if that network data already exists in a package in R.
To facilitate testing and to contribute to an ecosystem of easily accessible network data,
particularly for pedagogical purposes,
we include a number of classical and instructional network datasets,
all thoroughly documented and ready for analysis.
Here are just a few examples, all available in `{manynet}`:
<img src="https://www.jameshollway.com/post/manynet/README-ison_egs-1.png" alt="Graphs illustrating several of the classic networks included in the package"/>
```{r ison_egs, echo = FALSE, dpi = 250, message=FALSE, fig.height=3, eval=FALSE}
graphr(to_unlabelled(ison_karateka)) + ggtitle("Karateka", subtitle = "Zachary 1977") +
graphr(ison_algebra, labels = FALSE) + ggtitle("Algebra", subtitle = "McFarland 2001") +
graphr(to_unlabelled(ison_southern_women)) + ggtitle("Southern Women", subtitle = "Davis et al 1941")
#/
# (graphr(ison_lawfirm) + ggtitle("Law Firm", subtitle = "Lazega 2001") +
```
The package includes three families of network data:
- Classic/instructional networks: `r list_data("^ison_")`
- Fictional networks: `r list_data("^fict_")`
- International/political networks: `r list_data("^irps_")`
#### Inventing network data
`{manynet}` includes functions for making networks algorithmically.
The `create_*` group of functions create networks with a particular structure,
and will always create the same format from the same inputs,
e.g.:
<img src="https://www.jameshollway.com/post/manynet/README-create_egs-1.png" alt="Graphs illustrating the creation of lattices and tree networks"/>
```{r create_egs, echo = FALSE, dpi = 300, message=FALSE, fig.height=3, eval=FALSE}
(graphr(create_lattice(15)) + ggtitle("Lattice", subtitle = "create_lattice(15)") +
graphr(create_tree(15)) + ggtitle("Tree", subtitle = "create_tree(15)"))
```
See also `r list_functions("^create_")`.
The `generate_*` group of functions generate networks from
generative mechanisms that may include some random aspect,
and so will return a different output each time they are run,
e.g.:
<img src="https://www.jameshollway.com/post/manynet/README-generate_egs-1.png" alt="Graphs of small-world and scale-free networks of 15 nodes"/>
```{r generate_egs, echo = FALSE, dpi = 300, message=FALSE, fig.height=3, eval=FALSE}
(graphr(generate_smallworld(15)) + ggtitle("Small-World", subtitle = "generate_smallworld(15)") +
graphr(generate_scalefree(15)) + ggtitle("Scale-Free", subtitle = "generate_scalefree(15)"))
```
See also `r list_functions("^generate_")`.
Note that all these functions can create directed or undirected,
one-mode or two-mode networks.
Creating two-mode networks is as easy as passing the first argument (`n`)
a vector of two integers instead of one.
For example, while `n = 15` will create a one-mode network of 15 nodes,
whereas `n = c(10,5)` will create a two-mode network of 10 nodes in the first mode,
and 5 nodes in the second mode.
Some of these functions wrap existing algorithms in other packages,
while others are unique offerings or add additional formats,
e.g. two-mode networks.
<img src="https://www.jameshollway.com/post/manynet/README-generate_tm-1.png" alt="Graphs of generated one- and two-mode small-world networks"/>
```{r generate_tm, echo = FALSE, dpi = 300, message=FALSE, fig.height=3, warning=FALSE, eval=FALSE}
graphr(generate_smallworld(15, directed = TRUE), layout = "stress") + ggtitle("Small-World", subtitle = "generate_smallworld(15, directed = TRUE)") + graphr(generate_smallworld(c(10,5)), layout = "stress") + ggtitle("Small-World", subtitle = "generate_smallworld(c(10,5))")
```
#### Inventing data on networks
`{manynet}` also includes functions for simulating diffusion
or learning processes over a given network:
- `r list_functions("^play_")`
The diffusion models include not only SI and threshold models,
but also SIS, SIR, SIRS, SEIR, and SEIRS.
These simulations return results that can be analysed with the
network-level and node-level diffusion measures in `{netrics}`.
## Manipulating
`{manynet}` offers comprehensive tools for manipulating networks,
including coercing between formats and using familiar dplyr-style verbs
to work with nodes, ties, and their attributes.
#### Translating network data
Once you have imported network data,
identified network data in this or other packages in R,
or invented your own,
you may need to translate this data into another class for analysis.
`{manynet}`'s `as_*()` functions can be used to coerce objects
from one of many common classes into any other.
Below is a directed graph showing the currently available options:
<img src="https://www.jameshollway.com/post/manynet/README-coercion-graph-1.png" alt="Graph of coercible relationships between classes"/>
```{r coercion-graph, echo = FALSE, dpi = 300, eval=FALSE, fig.height=8, fig.width=8}
library(autograph)
graphr(igraph::graph_from_literal(
edgelist --+ igraph:tidygraph:network:graphAM:stocnet,
matrix --+ igraph:tidygraph:network:graphAM:stocnet,
igraph --+ tidygraph:network:siena:graphAM:diff_model:stocnet,
tidygraph --+ igraph:network:siena:graphAM,
network --+ igraph:tidygraph:graphAM:stocnet,
siena --+ igraph:tidygraph:network:graphAM:matrix:edgelist,
diff_model --+ igraph:tidygraph:matrix:diffnet,
diffnet --+ igraph:tidygraph:network:diff_model,
stocnet --+ igraph:tidygraph:network:graphAM:matrix:edgelist
), layout = "circle", node_size = 3)
ggsave("~/Library/CloudStorage/Dropbox/Sites/jameshollway.com/content/post/manynet/README-coercion-graph-1.png")
```
These functions are designed to be as intuitive and lossless as possible,
outperforming many other class-coercion packages.
We use these functions internally in every `{manynet}`, `{autograph}`, `{netrics}`, and `{migraph}` function to
(1) allow them to be run on any compatible network format
and (2) use the most efficient algorithm available.
This makes all these packages compatible with your existing workflow,
whether you use base R matrices or edgelists as data frames,
[`{igraph}`](https://igraph.org/r/),
[`{network}`](https://statnet.org), or
[`{tidygraph}`](https://tidygraph.data-imaginist.com/index.html),
and extensible by developments in those other packages too.
#### Wrangling with dplyr-style verbs
`{manynet}` offers a set of dplyr-inspired verbs for working directly with
network nodes, ties, and their attributes.
These verbs follow the familiar tidyverse grammar,
making network manipulation intuitive for R users:
```{r manip-example, eval = FALSE}
ison_southern_women |>
mutate_ties(weight = 1) |>
filter_nodes(node_is_mode(ison_southern_women)) |>
select_nodes(name)
```
Available verbs for manipulating **nodes**: `mutate_nodes()`, `filter_nodes()`, `select_nodes()`, `rename_nodes()`, `arrange_nodes()`, `bind_nodes()`, `add_nodes()`, `delete_nodes()`, `join_nodes()`
Available verbs for manipulating **ties**: `mutate_ties()`, `filter_ties()`, `select_ties()`, `rename_ties()`, `arrange_ties()`, `bind_ties()`, `add_ties()`, `delete_ties()`, `join_ties()`
Available verbs for manipulating **changes**: `r list_functions("_changes$")`
Available verbs for manipulating **globals**: `r list_functions("_globals$")`
## Modifying
Before or during analysis, you may need to modify the structure of the network you are analysing.
`{manynet}`'s `to_*()` functions can be used on any class object
to reformat, transform, or split networks into networks with other properties.
### Reformatting
Reformatting means changing the format of the network,
e.g. from directed to undirected via `to_undirected()`.
<img src="https://www.jameshollway.com/post/manynet/README-directed_egs-1.png" alt="Graphs illustrating modification of a network's directedness"/>
```{r directed_egs, echo = FALSE, dpi = 300, fig.height=3, warning=FALSE, message=FALSE, eval=FALSE}
graphr(to_directed(ison_brandes)) + ggtitle("Directed", subtitle = "to_directed(ison_brandes)") +
graphr(to_undirected(ison_brandes)) + ggtitle("Undirected", subtitle = "to_undirected(ison_brandes)")
```
See also `r list_functions("^to_.*ed$")`.
### Transforming
Transforming means changing the dimensions of the network,
e.g. from a two-mode network to a one-mode projection via `to_mode1()` or `to_mode2()`.
<img src="https://www.jameshollway.com/post/manynet/README-projection_egs-1.png" alt="Graphs illustrating decomposition of a two-mode network into its projections"/>
```{r projection_egs, echo = FALSE, dpi = 300, fig.height=3, warning=FALSE, message=FALSE, eval=FALSE}
graphr(ison_southern_women, layout = "stress") + ggtitle("Original", subtitle = "ison_southern_women") +
graphr(to_mode1(ison_southern_women)) + ggtitle("Row Projection", subtitle = "to_mode1(ison_southern_women)") +
graphr(to_mode2(ison_southern_women)) + ggtitle("Column Projection", subtitle = "to_mode2(ison_southern_women)") &
ggplot2::theme(plot.subtitle = element_text(size = 10))
```
Compared with other packages, `{manynet}`'s `to_mode1()` and `to_mode2()` functions are more flexible and efficient,
work with all input classes, offer additional weighting options (such as Jaccard or cosine normalisation), and retain node and edge attributes.
### Splitting and Joining
Splitting means separating a network,
e.g. from a whole network to the various ego networks via `to_egos()`.
<img src="https://www.jameshollway.com/post/manynet/README-splitting_egs-1.png" alt="Graphs illustrating decomposition of a network into egonets"/>
```{r splitting_egs, echo = FALSE, dpi = 250, fig.height=4, warning=FALSE, message=FALSE, eval=FALSE}
graphr(ison_adolescents) + ggtitle("Original", subtitle = "ison_adolescents") +
graphs(lapply(to_egos(ison_adolescents), to_unlabelled)) + ggtitle("Ego Splitting", subtitle = "to_egos(ison_adolescents)")
```
Those functions that split a network into a list of networks are
distinguishable as those `to_*()` functions that are named in the plural.
Split data can be rejoined using the `from_*()` family of functions.
See also `r list_functions("^to_.*s$")` and `r list_functions("^from_")`.
## Cheat sheet
The cheat sheet below summarises how `{manynet}`'s functions are organised.
Click to download the PDF to print or keep at hand,
and see [the manynet website](https://stocnet.github.io/manynet/) for more.
<a href="https://github.com/stocnet/manynet/blob/main/inst/figures/cheatsheet.pdf"><img src="https://raw.githubusercontent.com/stocnet/manynet/main/man/figures/cheatsheet.png" alt="manynet cheatsheet page 1" width="49%"/></a>
## Installation
### Stable
The easiest way to install the latest stable version of `{manynet}` is via CRAN.
Simply open the R console and enter:
`install.packages('manynet')`
`library(manynet)` will then load the package and make the data and tutorials (see below) contained within the package available.
### Development
For the latest development version,
for slightly earlier access to new features or for testing,
you may wish to download and install the binaries from Github
or install from source locally.
The latest binary releases for all major OSes -- Windows, Mac, and Linux --
can be found [here](https://github.com/stocnet/manynet/releases/latest).
Download the appropriate binary for your operating system,
and install using an adapted version of the following commands:
- For Windows: `install.packages("~/Downloads/manynet_winOS.zip", repos = NULL)`
- For Mac: `install.packages("~/Downloads/manynet_macOS.tgz", repos = NULL)`
- For Unix: `install.packages("~/Downloads/manynet_linuxOS.tar.gz", repos = NULL)`
To install from source the latest main version of `{manynet}` from Github,
please install the `{remotes}` package from CRAN and then:
- For latest stable version:
`remotes::install_github("stocnet/manynet")`
- For latest development version:
`remotes::install_github("stocnet/manynet@develop")`
### Other sources
Those using Mac computers may also install using Macports:
`sudo port install R-manynet`
## Relationship to other packages
This package stands on the shoulders of several incredible packages.
In terms of the objects it works with,
this package aims to provide an updated, more comprehensive replacement for `{intergraph}`.
As such it works with objects in `{igraph}` and `{network}` formats,
but also equally well with base matrices and edgelists (data frames),
and formats from several other packages.
The user interface is inspired in some ways by Thomas Lin Pedersen's excellent `{tidygraph}` package,
though makes some different decisions,
and uses the quickest `{igraph}` or `{network}` routines where available.
`{manynet}` has inherited most of its core functionality from its maternal package, `{migraph}`,
but has also devolved its visualisation capabilities to its sibling package, [`{autograph}`](https://stocnet.github.io/autograph/),
and its network analytic capabilities to its sibling package, [`{netrics}`](https://stocnet.github.io/netrics/).
[`{migraph}`](https://stocnet.github.io/migraph/) continues to offer modelling functions that builds upon
the architecture provided by `{manynet}`.
For more, please check out `{migraph}` and the other [stocnet](https://github.com/stocnet) packages directly.
## Funding details
Development on this package has been funded by the Swiss National Science Foundation (SNSF)
[Grant Number 188976](https://data.snf.ch/grants/grant/188976):
"Power and Networks and the Rate of Change in Institutional Complexes" (PANARCHIC).