graph4lgThe rationale of the graph4lg package in R is to make
the construction and analysis of genetic and landscape graphs easier for
landscape genetic studies (hence the name graph4lg, meaning
Graphs for Landscape Genetics). This package provides users with tools
for:
Each one of the vignettes associated with this package focuses on one of these points. This first vignette will focus on landscape and genetic data processing. It will describe the package functions allowing users to:
The package already includes simulated data sets for genetic and
spatial data, allowing users to discover its different functionalities.
The first data set (data_simul) was simulated with CDPOP
(Landguth and Cushman 2010) on a simulated
landscape. It consists of 1500 individuals from 50 populations genotyped
for 20 microsatellite loci. Individuals dispersed less when the
cost-distance between populations was large. A landscape graph was
created with Graphab Foltête et al. (2021)
whose nodes were the 50 simulated populations and the links were
weighted by cost-distance values between populations. The project
created with Graphab was included into the package such that the
landscape graphs and the cost-distance matrix can be easily imported
into the R environment.
The second data set (data_ex) was simulated as the first
one but included only 10 populations. It is used to generate quick
examples.
The first type of functions from this package allows users to process genetic data. These functions load genetic data in an R environment and convert them when necessary.
In order to make the package user-friendly and compatible with
genetic data commonly used in landscape genetics, the functions
genepop_to_genind, structure_to_genind,
gstud_to_genind and loci_to_genind allow users
to convert genetic data from formats used respectively in the
gstudio (Dyer 2009) and
pegas (Paradis 2010) packages
in R and in STRUCTURE (Pritchard et al.
2000) and GENEPOP (Raymond 1995)
software into R objects with the class attribute genind
from ADEGENET package (Jombart 2008). The
genind format makes it possible to use
time-efficient functions from the adegenet package (coded
in C). This package was developed and is regularly maintained by Thibaut
Jombart (his website).
The genind_to_genepop function enables to convert
genind object into text files in the genepop
format in order to perform analyses with this commonly used R package
and executable software. All these functions work with
microsatellite data (with 2 or 3-digits allele
coding).
The package is compatible with SNPs data as long as
they have been loaded into a genind object (ideally using
the vcfR package with the
return.alleles = TRUE option in the
vcfR::vcfR2genind() function).
The GENEPOP software (Raymond 1995) developed by M. Raymond and F. Rousset (Montpellier, France) can be used as an executable file, with or without graphical user interface, or as an R package (GENEPOP git repository). It is frequently used to compute FST values and to test for Hardy-Weinberg equilibrium, linkage disequilibrium or genetic differentiation. Besides, when performing simulations with CDPOP (Landguth and Cushman 2010), individual genotypes can be saved as GENEPOP files at the end of the simulation.
The function genepop_to_genind loads a GENEPOP file
(.txt extension) and converts it into a genind object. To
use it, the path to the file, the total number and names of the loci and
the population names must be indicated.
data_genind <- genepop_to_genind(path = paste0(system.file('extdata',
package = 'graph4lg'),
"/gpop_simul_10_g100_04_20.txt"),
n.loci = 20, pop_names = as.character(1:10))
#> Registered S3 method overwritten by 'ade4':
#> method from
#> print.amova pegas
data_genind
#> /// GENIND OBJECT /////////
#>
#> // 200 individuals; 20 loci; 124 alleles; size: 139.8 Kb
#>
#> // Basic content
#> @tab: 200 x 124 matrix of allele counts
#> @loc.n.all: number of alleles per locus (range: 3-9)
#> @loc.fac: locus factor for the 124 columns of @tab
#> @all.names: list of allele names for each locus
#> @ploidy: ploidy of each individual (range: 2-2)
#> @type: codom
#> @call: adegenet::df2genind(X = as.matrix(x[, attr(x, "locicol"), drop = FALSE]),
#> sep = "/", pop = pop, ploidy = ploidy)
#>
#> // Optional content
#> @pop: population of each individual (group size range: 20-20)We get a genind object. It contains the genotypes of the
1500 individuals from the 50 populations created during the simulation
(similar to the data set data_ex_genind).
The genind_to_genepop function performs the reverse
conversion, i.e., it converts a genind object into a
GENEPOP file. This file is created and saved in the working directory
defined earlier.
This function can create, for example, a GENEPOP file to test for pairwise population genetic differentiation or to compute fixation indices with GENEPOP software.
The STRUCTURE software (Pritchard et al.
2000) is frequently used in population genetics and landscape
genetics. It enables to create population clusters through a Bayesian
approach aiming at minimising the deviation from Hardy-Weinberg
equilibrium when merging populations together. The input files have a
particular structure. The function structure_to_genind
converts this type of file into a genind object.
To use the function, we need to indicate the path to the file, the names of the loci, the individual ID and the population names in the same order as in the original file.
loci_names <- paste0("LOCI-", as.character(1:20))
ind_names <- as.character(1:200)
pop_names <- as.character(1:10)
data_paru <- structure_to_genind(path = paste0(system.file('extdata',
package = 'graph4lg'),
"/data_ex_str.txt"),
loci_names = loci_names,
pop_names = pop_names,
ind_names = ind_names)
data_paru
#> /// GENIND OBJECT /////////
#>
#> // 200 individuals; 20 loci; 124 alleles; size: 139.5 Kb
#>
#> // Basic content
#> @tab: 200 x 124 matrix of allele counts
#> @loc.n.all: number of alleles per locus (range: 3-9)
#> @loc.fac: locus factor for the 124 columns of @tab
#> @all.names: list of allele names for each locus
#> @ploidy: ploidy of each individual (range: 2-2)
#> @type: codom
#> @call: adegenet::df2genind(X = as.matrix(x[, attr(x, "locicol"), drop = FALSE]),
#> sep = "/", pop = pop, ploidy = ploidy)
#>
#> // Optional content
#> @pop: population of each individual (group size range: 20-20)The gstudio and popgraph packages,
developed by R. Dyer (Dyer 2009), use R
data.frames as input data, with columns of class
locus. These data.frame objects are
gstud objects. Given these packages are often used to
create genetic graphs, we created a function to convert them into the
genind format.
A gstud object generally has the following structure
(simulations with 10 populations as an example):
print(head(data_ex_gstud))
#> ID POP LOCUS-1 LOCUS-2 LOCUS-3 LOCUS-4 LOCUS-5 LOCUS-6 LOCUS-7 LOCUS-8
#> 23 1 1 116:130 104:104 123:123 103:103 124:124 106:113 113:117 101:101
#> 24 2 1 116:116 104:104 123:123 103:129 124:124 106:113 113:113 101:101
#> 25 3 1 130:130 104:104 123:123 103:103 124:124 106:113 113:113 101:101
#> 26 4 1 116:116 104:107 123:123 103:103 124:124 106:106 117:117 101:114
#> 27 5 1 116:130 104:107 123:123 103:103 124:124 106:106 113:117 101:114
#> 28 6 1 116:116 104:104 123:123 103:103 124:124 113:113 109:113 101:114
#> LOCUS-9 LOCUS-10 LOCUS-11 LOCUS-12 LOCUS-13 LOCUS-14 LOCUS-15 LOCUS-16
#> 23 102:126 114:114 123:123 104:120 105:105 103:122 106:129 115:115
#> 24 126:126 114:118 123:123 120:120 104:105 103:103 116:116 102:115
#> 25 102:126 118:118 109:123 120:120 104:104 103:103 116:129 102:102
#> 26 102:126 118:118 123:123 104:120 105:105 103:103 116:129 115:115
#> 27 102:106 114:114 123:123 104:120 105:105 103:122 116:129 102:115
#> 28 124:126 114:114 123:123 104:104 105:105 103:122 106:106 102:102
#> LOCUS-17 LOCUS-18 LOCUS-19 LOCUS-20
#> 23 103:103 122:122 129:129 109:130
#> 24 103:103 122:122 109:129 109:130
#> 25 103:103 122:122 109:122 109:109
#> 26 103:103 122:122 122:129 109:130
#> 27 103:103 122:122 129:129 109:130
#> 28 103:103 122:122 122:129 117:120To convert it with the function gstud_to_genind, we
indicate the name of the data.frame and of the columns
containing population names and individual names:
gstud_to_genind(x = data_ex_gstud, pop_col = "POP",
ind_col = "ID")
#> Individuals in 'x' were not ordered, they have
#> been ordered by populations and populations ordered in alphabetic
#> order for the conversion.
#> /// GENIND OBJECT /////////
#>
#> // 200 individuals; 20 loci; 124 alleles; size: 139.8 Kb
#>
#> // Basic content
#> @tab: 200 x 124 matrix of allele counts
#> @loc.n.all: number of alleles per locus (range: 3-9)
#> @loc.fac: locus factor for the 124 columns of @tab
#> @all.names: list of allele names for each locus
#> @ploidy: ploidy of each individual (range: 2-2)
#> @type: codom
#> @call: adegenet::df2genind(X = as.matrix(x[, attr(x, "locicol"), drop = FALSE]),
#> sep = "/", pop = pop, ploidy = ploidy)
#>
#> // Optional content
#> @pop: population of each individual (group size range: 20-20)Once a genetic dataset has been loaded in the R environment, the
function pop_gen_index computes some genetic
diversity indices at the population level.
gen_div <- pop_gen_index(data_ex_genind)
print(head(gen_div))
#> ID Nb_ind A Ho He
#> 1 1 20 2.40 0.4000 0.3833750
#> 10 10 20 2.85 0.4850 0.4636250
#> 2 2 20 2.90 0.4250 0.4434375
#> 3 3 20 2.90 0.4700 0.4090625
#> 4 4 20 2.95 0.4675 0.4261250
#> 5 5 20 3.00 0.3925 0.4415625By default, it computes all the available indices, i.e., the number of individuals (“Nb_ind”), the total allelic richness (“A”), the expected heterozygosity (“He”), and the observed heterozygosity (“Ho”).
In landscape genetics, apart from local population or landscape properties at the sampling site level, particular attention is given to between population/habitat patch distances. The package includes three functions to compute both genetic and landscape distances.
From a genind object, the mat_gen_dist
function calculates several types of between population genetic
distances:
FST (Weir and Cockerham
1984) or linearised FST (Rousset 1997) (options ‘dist=FST’
and ‘dist=FST_lin’).
G’ST (Hedrick 2005)
(option ‘dist=GST’) (graph4lg <= 1.6.0).
DJost (Jost 2008)
(option ‘dist=D’) (graph4lg <= 1.6.0).
DPS (1 - proportion of shared alleles) Murphy et al. (2015) (option
‘dist=DPS’).
Euclidean genetic distance (Excoffier et
al. 1992) (option ‘dist=basic’).
Euclidean genetic distance with a weighting depending on allelic
frequencies giving more weight to rare alleles (Fortuna et al. 2009) (option
‘dist=weight’).
Euclidean genetic distance computed after a PCA of the matrix of
allelic frequencies by population. The axes considered to compute the
Euclidean distance are the non-collinear principal components (total
number of alleles - number of loci) Shirk et al.
(2017) (option ‘dist=PCA’).
Euclidean genetic distance computed in the same way as with the
function popgraph from popgraph package,
i.e. after a PCA and two SVD, among other computation steps (option
‘dist=PG’). This distance differs from the conditional
genetic distance (cGD) computed from a population graph by summing
genetic distances along shortest paths.
To do these calculations with the function mat_gen_dist,
we just have to indicate the name of the genind object
which includes the genetic data of the individuals as well as the
populations to which each of them belongs. The other argument of the
function is the type of genetic distance to compute. Here are two
examples:
mat_dps[1:5, 1:5]
#> 1 10 11 12 13
#> 1 0.0000000 0.7883333 0.5900000 0.6816667 0.8733333
#> 10 0.7883333 0.0000000 0.5741667 0.5450000 0.8816667
#> 11 0.5900000 0.5741667 0.0000000 0.3750000 0.8658333
#> 12 0.6816667 0.5450000 0.3750000 0.0000000 0.8633333
#> 13 0.8733333 0.8816667 0.8658333 0.8633333 0.0000000The package also calculates Euclidean geographical
distances between populations with the function
mat_geo_dist. It takes as arguments:
data: A data.frame with 3 columns
corresponding to point ID, longitude (x) and latitude (y) whose column
names are specified in other arguments below. It can also be an
sf point spatial feature created in R or by importing a
shapefile layer with the sf package.ID: population or point IDx: population or point longitudey: population or point latitudecrds_type: “proj” or “polar”. Indicates whether
coordinates are from a projected (“proj”) or a polar (“polar”)
coordinate reference system.gc_formula: if coordinates are polar, then it specifies
the formula to use. By default, the Vicenty formula is used.When geographical coordinates are given in a projected coordinate reference system (metric), Pythagoras’s theorem is used to compute the distances. Conversely, when they are given in a polar CRS (degrees), Great Circle distances are computed. A warning message is displayed in every case.
Example with the 50 point projected coordinates included in the
pts_pop_simul data set:
print(head(pts_pop_simul))
#> ID x y
#> 0 1 25650 54150
#> 1 2 22550 53650
#> 2 3 7250 51750
#> 3 4 32350 50550
#> 4 5 27350 49650
#> 5 6 15950 49550mat_geo <- mat_geo_dist(data = pts_pop_simul,
ID = "ID", x = "x", y = "y",
crds_type = "proj")
#> Coordinates were treated as projected coordinates. Check whether
#> it is the case.mat_geo[1:5, 1:5]
#> 1 2 3 4 5
#> 1 0.000 3140.064 18555.86 7605.919 4810.405
#> 2 3140.064 0.000 15417.52 10278.619 6248.200
#> 3 18555.862 15417.522 0.00 25128.669 20209.404
#> 4 7605.919 10278.619 25128.67 0.000 5080.354
#> 5 4810.405 6248.200 20209.40 5080.354 0.000Examples with 4 city polar coordinates:
city_us <- data.frame(name = c("New York City", "Chicago",
"Los Angeles", "Atlanta"),
lat = c(40.75170, 41.87440,
34.05420, 33.75280),
lon = c(-73.99420, -87.63940,
-118.24100, -84.39360))
mat_geo_us <- mat_geo_dist(data = city_us,
ID = "name", x = "lon", y = "lat",
crds_type = "polar")
#> Coordinates were treated as polar coordinates. Check whether
#> it is the case.
head(mat_geo_us)
#> Atlanta Chicago Los Angeles New York City
#> Atlanta 0.0 367050.9 16225865 1168203
#> Chicago 367050.9 0.0 16590655 1523685
#> Los Angeles 16225865.1 16590655.5 0 15072934
#> New York City 1168203.4 1523684.7 15072934 0Because straight line Euclidean distances cannot accurately reflect how species move in landscapes, methods have been developed to better represent how they move by incorporating information about the resistance of landscape features to their movements. Among them, the computation of least-cost paths and of their cumulated cost-distances along these paths is a very popular approach.
The function mat_cost_dist makes possible the
computation of cost-distances between a set of points on a
raster with discrete cell values corresponding to land use
types. Each land use type is given a cost reflecting its resistance to
movement. A high value means that the cell is difficult to cross for an
individual.
The raster input can be either:
character string) to a raster file in format
.tif or .asc,SpatRaster object already loaded in R environment
with package terra.The point (pts) input can be either:
character string) to a .csv file,data.frame already loaded in R environmentsf point spatial feature created in R or by
importing a shapefile layer with the sf package.In all cases, this object must have three data columns indicating the point ID, x (longitude) and y (latitude) in a projected coordinate reference system.
To do the computation, we need to create a data.frame
with two columns (code and cost) specifying
the cost associated with every raster cell value.
By default, the computation is performed with
costDistance function from gdistance package
(method = "gdistance"). For example :
x <- terra::rast(ncols = 10, nrows = 10,
xmin = 0, xmax = 100,
ymin = 0, ymax = 100)
terra::values(x) <- sample(c(1,2,3,4), size = 100, replace = TRUE)
pts <- data.frame(ID = 1:4,
x = c(10, 90, 10, 90),
y = c(90, 10, 90, 10))
cost <- data.frame(code = 1:4,
cost = c(1, 10, 100, 1000))
mat_cd <- mat_cost_dist(raster = x,
pts = pts, cost = cost,
method = "gdistance")
#> Registered S3 method overwritten by 'proxy':
#> method from
#> dim.dist ecodist
head(mat_cd)
#> 1 2 3 4
#> 1 0.0000 184.8492 0.0000 184.8492
#> 2 184.8492 0.0000 184.8492 0.0000
#> 3 0.0000 184.8492 0.0000 184.8492
#> 4 184.8492 0.0000 184.8492 0.0000gdistance cannot perform the computation anymore when
the raster size and the number of points increase. Using another coding
language than R is a way to overcome this limitation. That is why the
function mat_cost_dist includes another method for
computing cost distances. It relies upon the .jar file
costdist-0.5.jar (Java language), developed by Gilles
Vuidel (UMR TheMA, Besancon, France). It is automatically downloaded by
the user at the first use of the function mat_cost_dist
with the argument method = "java", provided Java is
installed in the user’s machine. This program makes possible the
parallelisation of the computation. The argument
parallel.java takes values between 1 and the number of
cores in the user’s machine - 1, thereby setting the number of cores
used for the computation.
For example, when using method="java", the command
should be:
When method="java", least cost paths progress in 8
directions from one cell, whereas it can be controlled when
method = "gdistance" with the argument
direction=4 (or 8 or 16).
When choosing which method? Using
method="java" becomes more and more interesting as the
raster size and the number of points increase. In the previous example
(raster: 10 \(\times\) 10 cells, 4
points), using method="gdistance" is the fastest option
(0.67 s. vs 2.56 s.). With a raster of 100 \(\times\) 100 cells and 4 points, both
methods are equivalent (2 s.). With a raster of 1000 \(\times\) 1000 cells and 4 points,
method="java" is by far the fastest (120 s. vs 8 s.).
Besides, depending on the input data types, computation times can vary:
method="java", the best option is to provide
a .asc raster file and a .csv point file.method="gdistance", the best option is to
provide a RasterLayer object in R and a
SpatialPointsDataFrame object in R.N.B.: the method="gdistance" option
relies on the RasterLayer format of the raster
package. This package is progressively replaced by terra,
which offers more stable functions and has more stable dependencies. In
the future, this option might not be continued if gdistance
does not update their dependency.
The functions presented in the last sections create objects in R,
such as data.frame and matrix. The package
includes functions to process these objects, ordering them, comparing
them and converting them.
In landscape genetics, when comparing two matrices of distances
between the same sets of elements (e.g., doing a Mantel test to assess
isolation by distance patterns), the two matrices must be ordered in the
same way. The function reorder_mat reorders a symmetric
matrix according to a specified order of its row/column names.
For example, when computing a geographical distance from a
data.frame in which the ID column contains
integer values, the resulting distance matrix is ordered in the
increasing order of these ID (1, 2, 3, …., 10). If the same IDs are
character strings, the resulting distance matrix will be ordered in
alphabetical order (“1”, “10”, “2”, “3”, …, “9”). In the following
example, we illustrate how to reorder a matrix in such a case.
mat_g1 <- mat_geo_dist(pts_pop_ex,
ID = "ID", x = "x", y = "y",
crds_type = "proj")
#> Coordinates were treated as projected coordinates. Check whether
#> it is the case.
head(mat_g1)
#> 1 2 3 4 5 6 7 8
#> 1 0.00 30050.125 21967.248 41694.12 26916.352 19313.21 37283.91 29098.797
#> 2 30050.12 0.000 8360.024 11800.42 6529.931 23825.41 19804.04 25766.063
#> 3 21967.25 8360.024 0.000 19746.39 5728.001 16843.99 20392.40 21332.135
#> 4 41694.12 11800.424 19746.392 0.00 15582.362 32572.99 20145.72 31270.753
#> 5 26916.35 6529.931 5728.001 15582.36 0.000 17629.80 15280.05 19293.781
#> 6 19313.21 23825.407 16843.990 32572.99 17629.804 0.00 20333.47 9790.812
#> 9 10
#> 1 33737.96 29230.81
#> 2 24485.91 30425.15
#> 3 22000.23 25242.03
#> 4 27789.39 36391.76
#> 5 18483.51 23900.84
#> 6 14827.34 10647.07
row.names(mat_g1)
#> [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10"
# Reorder mat_g1
mat_g2 <- reorder_mat(mat_g1,
order = as.character(1:10)[order(as.character(1:10))])
head(mat_g2)
#> 1 10 2 3 4 5 6 7
#> 1 0.00 29230.81 30050.125 21967.248 41694.12 26916.352 19313.21 37283.91
#> 10 29230.81 0.00 30425.154 25242.028 36391.76 23900.837 10647.07 18775.78
#> 2 30050.12 30425.15 0.000 8360.024 11800.42 6529.931 23825.41 19804.04
#> 3 21967.25 25242.03 8360.024 0.000 19746.39 5728.001 16843.99 20392.40
#> 4 41694.12 36391.76 11800.424 19746.392 0.00 15582.362 32572.99 20145.72
#> 5 26916.35 23900.84 6529.931 5728.001 15582.36 0.000 17629.80 15280.05
#> 8 9
#> 1 29098.797 33737.96
#> 10 5147.815 10348.43
#> 2 25766.063 24485.91
#> 3 21332.135 22000.23
#> 4 31270.753 27789.39
#> 5 19293.781 18483.51
row.names(mat_g2)
#> [1] "1" "10" "2" "3" "4" "5" "6" "7" "8" "9"Cost-distances are expressed in cost units arbitrarily defined based on the cost values assigned to every land cover type when creating resistance surfaces. However, species dispersal distances are usually known as distances expressed in metric units. When we know that the probability that a species covers 10 km is 5 %, we can ask what is the equivalent of this distance in cost distance units according to the assumed cost value scenario. It can be useful in order to prune a landscape graph with a given distance threshold or simply to get an idea of the order of magnitude of cost-distance values.
For that purpose, a regression of the between population cost-distance values against the corresponding geographical distances can be performed. It estimates the relationship between both types of distance. Then, the resulting parameter estimates enable to convert a geographical distance into its cost-distance equivalent according to the cost scenario.
The function convert_cd performs the linear regression
or log-log linear regression between the geographical distance matrix
and the cost-distance matrix, in the same way as Tournant et al. (2013) and as performed by
Graphab software.
Below, we estimate the relationship between geographical distance and cost-distance between the populations used to perform the gene-flow simulation. We convert 10 km into cost-distance units. The function also plots the relationship between these distances.
mat_ld <- reorder_mat(mat_ld, order = row.names(mat_geo))
convert_res <- convert_cd(mat_euc = mat_geo, mat_ld = mat_ld,
to_convert = 10000, fig = TRUE,
method = "log-log", pts_col = "grey")
convert_res
#> $`Converted values`
#> 10000
#> 1605.543
#>
#> $`Model parameters`
#> Intercept Slope
#> -2.251216 1.045828
#>
#> $`Model multiple R-squared`
#> Multiple R-squared
#> 0.6870757
#>
#> $PlotIn this case, we can see that 10 km are equivalent to 1.606 cost-distance units. The log-log linear model estimates the relationship between geographical distance (GD) and cost-distance (CD) such that: \(log(CD)=-2.2512+1.0458 \times log(GD)\). The determination coefficient \(R^2\) associated with this linear model is 0.69.
A figure is returned as the fourth element of
convert_res. The black dot represented on this figure
refers to the 10 km value on the regression line characterising the
relationship between cost-distance and geographical distance.
Distance values can be stored in two main ways. First, they can be stored in pairwise distance matrices. The distance between point \(i\) and point \(j\) is the value at the \(i_{th}\) row and the \(j_{th}\) column, and also at the \(j_{th}\) row and the \(i_{th}\) column. Such a matrix is the required input of analyses such as Mantel tests and can be used to create graphs when considered as an adjacency matrix.
However, it is quite an heavy object and these values can be stored in smaller objects called edge lists, which are basically tables with three columns: from, to, distance.
The function pw_mat_to_df converts a pairwise
matrix into an edge list stored in a
data.frame object.
df_dist <- pw_mat_to_df(pw_mat = mat_geo)
print(head(df_dist))
#> id_1 id_2 id_link value
#> 1_2 1 2 1_2 3140.064
#> 1_3 1 3 1_3 18555.862
#> 2_3 2 3 2_3 15417.522
#> 1_4 1 4 1_4 7605.919
#> 2_4 2 4 2_4 10278.619
#> 3_4 3 4 3_4 25128.669The resulting object df_dist is a
data.frame with 4 columns: id_1,
id_2, id_link and value.
Conversely, the function df_to_pw_mat converts an edge
list stored in a data.frame object into a pairwise
matrix.
mat_dist <- df_to_pw_mat(data = df_dist,
from = "id_1", to = "id_2", value = "value")
mat_dist[1:5, 1:5]
#> 1 2 3 4 5
#> 1 0.000 3140.064 18555.86 7605.919 4810.405
#> 2 3140.064 0.000 15417.52 10278.619 6248.200
#> 3 18555.862 15417.522 0.00 25128.669 20209.404
#> 4 7605.919 10278.619 25128.67 0.000 5080.354
#> 5 4810.405 6248.200 20209.40 5080.354 0.000In the next vignette, we present how to construct and analyse
genetic graphs with graph4lg.