Cartograflow
is designed to filter origin-destination matrix for thematic flow mapping purposes using {sf}
objects and {Cartography}
to design the map.
You can use long “L” or matrix “M” [n*n] flow dataset formats.
– flowtabmat()
is to transform “L” to “M” formats, also to build an empty square matrix from spatial codes.
– flowcarre()
is to square a matrix.
– flowjointure()
is to performs a spatial join between a flow dataset and a spatial features layer (as a map background) or an external matrix.
– flowstructmat()
fixes an unpreviously codes shift in the flow dataset “M” format. If necessary this function is to be used with flowjointure
and flowtabmat
.
– flowtype()
is to compute volumn and balance flow from observed flows - respectively to compute symetric and skewmetric matrix from an asymmetric one.
– flowreduct()
is to reduce the flow dataset regarding another matrix, e.g. distances travelled.
metric
is the metric of the distance matrix : continuous (e.g. for meters) or ordinal (e.g. for adjacency). If the metric is continuous (e.g for filtering flows by kilometric distances travelled), use:
d.criteria
is for selecting dmin or dmax distance criteria for “continuous” metric ; Argument dmin
is for keeping only flows up to a dmin criterion in km ; Argument dmax
for selecting values less than a dmax criterion in km.
d
is the value of the selected dmin or dmax criteria.
Notice that these arguments can be used as a filter criterion in flowmap()
.
Flow concentration analysis:
– flowgini()
performs a Gini’s concentration analysis of the flow features, by computing Gini coefficient and plotting interactive Lorenz curve.
To be use before flowanalysis()
Flow filtering according to a concentration criterion:
– flowanalysis()
computes filters criterions based on:
These arguments can be used as filter criterion in flowmap()
.
Flow filtering based on a continuous distance criterion
– flowdist()
computes a continous distance matrix from spatial features (area or points). The result is a matrix of the distances travelled between ODs, with flows filtered or not.
Flow filtering based on an ordinal distance / neighbourhood criterion:
– flowcontig()
compute an ordinal distance matrix from spatial features (area). The result is a matrix of adjacency or k-contiguity of the ODs.
background
is the areal spatial features ;code
is the spatial features codes ; k
is to enter the number (k:1,2,…,k) of the contiguity matrix to be constructed : if (k=1), ODs places are adjacent, then the flow have to cross only 1 boundary, else (k=k) ODs places are distant from n borders ;algo
is the algorithm to use for ordinal distance calculation (also Default is “automatic” for “Dijkstra’s”) ; Notice that the function automatically returns the maximum (k) number of the spatial layer.
– flowmap()
is to plot flows as segments or arrows, by acting on the following arguments:
filter
is to filter or not flow’s information or features threshold
is used to set the filtering level of the flows when filter= “True” taille
is the value of the width of the flow feature a.head
is the arrow head parameter (in, out, in and out) a.length
is the length of the edges of the arrow head (in inches) a.angle
is the angle from the shaft of the arrow to the edge of the arrow head a.col
is the arrow’s color plota
is to add spatial features as map background to the flows’s plot add
is to allow to overlay flow features on external spatial features background Useful external packages are {dplyr} {sf} {igraph} {rlang} {cartography}.
Flow dataset
## 'data.frame': 121 obs. of 4 variables:
## $ i : chr "T1" "T1" "T1" "T1" ...
## $ j : chr "T1" "T10" "T11" "T12" ...
## $ Fij : num 291058 8297 3889 17064 12163 ...
## $ count: num 351 43 13 77 52 55 134 63 53 14 ...
Select variable and change matrix format
# Selecting useful variables
tabflow<-data%>%select(i,j,Fij)
# Change matrix format (if necessary)
matflow <-flowtabmat(tabflow,matlist="M")
## Using Fij as value column: use value.var to override.
## great:your matrix is square!
## T1 T10 T11 T12
## T1 291058 8297 3889 17064
## T10 73743 19501 11707 4931
## T11 22408 9359 12108 6084
## T12 68625 1906 7269 46515
#dim(matflow)
# reverse Change matrix format : from matrix to list
tabflow<-flowtabmat(tab=matflow, matlist="L")
colnames(tabflow)<-c("i","j","Fij")
head(tabflow)
## i j Fij
## 1 T1 T1 291058
## 2 T10 T1 73743
## 3 T11 T1 22408
## 4 T12 T1 68625
## 5 T2 T1 47427
## 6 T3 T1 45772
Geographical dataset
Compute bilateral flows : volum, balance and asymetry
# Compute bilateral volum : FSij
matflow_vol<-flowtype(matflow, format="M", "bivolum")
tabflow_vol<-flowtype(tabflow, format="L", "bivolum")
# Compute bilateral balance : FSij
tabflow_net<-flowtype(tabflow, format="L", "bisold")
# Compute all types of bilateral flows, in one 6 columns "L"format matrix
tabflow_all<-flowtype(tabflow, format="L", x="all")
head(tabflow_all)
## i j Fij Fji FSij FDij
## 1 T1 T1 291058 291058 582116 0
## 2 T1 T10 8297 73743 82040 65446
## 3 T1 T11 3889 22408 26297 18519
## 4 T1 T12 17064 68625 85689 51561
## 5 T1 T2 12163 47427 59590 35264
## 6 T1 T3 32682 45772 78454 13090
Plot all origin-destination links without any filtering criterion will reveal a graphic complexity (“spaghetti-effect”). So it is better to plot flow up to a simple global paramet (eg. mean).
Above-average flowmap
library(sf)
data(flowdata)
map <- st_read(system.file("shape/MGP_TER.shp", package = "cartograflow"))
## Reading layer `MGP_TER' from data source `/tmp/Rtmpi55GKi/Rinst7e283817c48b/cartograflow/shape/MGP_TER.shp' using driver `ESRI Shapefile'
## Simple feature collection with 12 features and 14 fields
## geometry type: POLYGON
## dimension: XY
## bbox: xmin: 637297.4 ymin: 6838629 xmax: 671752.1 ymax: 6879246
## projected CRS: Lambert_Conformal_Conic
# Add and overlay spatial background
par(bg = "NA")
knitr::opts_chunk$set(fig.width=6, fig.height=6)
par(mar=c(0,0,1,0))
extent <- c(2800000, 1340000, 6400000, 4800000)
resolution<-150
plot(st_geometry(map), col = NA, border=NA, bg="#dfe6e1")
plot(st_geometry(map), col = "light grey", add=TRUE)
# Flow mapping above-average flows
flowmap(tab=tabflow,
fij="Fij",
origin.f = "i",
destination.f = "j",
bkg = map,
code="EPT_NUM",
nodes.X="X",
nodes.Y = "Y",
filter=TRUE,
threshold =(mean(tabflow$Fij)), #mean value is the level of threshold
taille=20,
a.head = 1,
a.length = 0.11,
a.angle = 30,
a.col="#138913",
add=TRUE)
# Map Legend
legendPropLines(pos="topleft",
title.txt="Flows up to 13220 commuters",
title.cex=0.8,
cex=0.5,
values.cex= 0.7,
var=c(mean(tabflow$Fij),max(tabflow$Fij)),
lwd=5,
frame = FALSE,
col="#138913",
values.rnd = 0
)
#Map cosmetic
layoutLayer(title = "Commuters up to above-average in Greater Paris",
coltitle ="black",
author = "Cartograflow, 2020",
sources = "Data : INSEE, 2017 ; Basemap : APUR, RIATE, 2018.",
scale = 2,
tabtitle = FALSE,
frame = TRUE,
col = "grey"
)
# North arrow
north("topright")
Main functions
flowgini()
and flowanalysis()
Compute the concentration of flow values
tabgini<-flowgini(ODpts = tabflow,
origin="i",destination = "j",valflow = "Fij",
lorenz.plot = FALSE)
## Gini's coefficent =73.16 %
Plot the corresponding interactive Lorenz’ curve
## i j Fij link flowcum linkcum
## 1 T1 T1 291058 1 0.1819563 0.008264463
## 73 T1 T4 81129 1 0.2326745 0.016528926
## 2 T10 T1 73743 1 0.2787752 0.024793388
## 4 T12 T1 68625 1 0.3216765 0.033057851
## 7 T4 T1 66223 1 0.3630761 0.041322314
## 11 T8 T1 58770 1 0.3998165 0.049586777
Compute the “critflow” parameter (ex. significance)
## [1] "threshold = 13442 --- flows = 80 % --- links = 23.14 %"
Flowmap filtered according to flows values significance
Using the flowanalysis()
“critflow” value to select flows.
# Graphic parameters
knitr::opts_chunk$set(fig.width=6, fig.height=6)
par(mar=c(0,0,1,0))
extent <- c(2800000, 1340000, 6400000, 4800000)
resolution<-150
# Overlay a spatial background
par(bg = "NA")
# Add the corresponding background
plot(st_geometry(map), col = NA, border=NA, bg="#dfe6e1")
plot(st_geometry(map), col = "light grey", add=TRUE)
# For mapping flow up to 13342
flowmap(tab=tabflow,
fij="Fij",origin.f = "i",destination.f = "j",
bkg = map,code="EPT_NUM",nodes.X="X",nodes.Y = "Y",
add=TRUE,
filter=TRUE,
threshold=13442,
taille=15,
a.head = 1,
a.length = 0.11,
a.angle = 30,
a.col="#138913")
# Map Legend
legendPropLines(pos="topleft",
title.txt="Commuters up to 13442\n (80% of the largest flows)",
title.cex=0.8,
cex=0.5,
values.cex= 0.7,
var=c(13442,max(tabflow$Fij)),
lwd=15,
frame = FALSE,
col="#138913",
values.rnd = 0
)
#Map cosmetic
layoutLayer(title = "Significant professional mobility in Greater Paris",
coltitle ="black",
author = "Cartograflow, 2020",
sources = "Data : INSEE, 2017 ; Basemap : APUR, RIATE, 2018.",
scale = 2,
tabtitle = FALSE,
frame = TRUE,
col = "grey",
)
# north arrow
north("topright")
Flowmap filtered according to flow features’ density
Using the flowanalysis()
“critlink value” to select flows and then flowmap.
Filtering an Origin-Destination matrix with a continuous distance matrix (in kilometers). The aim is to plot flow 1) less than a maximum distance value, 2) above a minimum distance travelled criterion or 3) on a range of distances.
Main function
flowdist()
Useful additional functions
flowjointure()
and flowreduct()
with the metric
parameter:" continuous".
Compute distance matrix
Function aims first to compute a distance matrix then to reduce the matrix and finally to plot the (filtered) flows. Example is for euclidian distance.
## i j Fij
## 1 T1 T1 291058
## 2 T10 T1 73743
## 3 T11 T1 22408
## 4 T12 T1 68625
## 5 T2 T1 47427
## 6 T3 T1 45772
tab<-flowjointure(geom="area",DF.flow=tabflow,origin = "i",destination = "j",
bkg=map,id="EPT_NUM",x="X",y="Y")
## Warning in st_centroid.sf(.): st_centroid assumes attributes are constant over
## geometries of x
tab.distance<-flowdist(tab,
dist.method = "euclidian",
result = "dist")
tab.distance<-tab.distance %>% select(i,j,distance)
tab<-tab %>% select(i,j,ydata)
head(tab.distance)
## i j distance
## 1 T1 T1 0.000
## 2 T10 T1 11367.443
## 3 T11 T1 17285.787
## 4 T12 T1 12460.261
## 5 T2 T1 9367.284
## 6 T3 T1 9951.666
Flow reduction according to a maximum distance travelled
Using for mapping flow less than the maximum distance travelled criterion.
#reduce the flow dataset from a selected distance travelled (eg. 8.5 km)
library(rlang)
tab.flow<-flowreduct(tab,
tab.distance,
metric = "continous",
d.criteria = "dmax", #max distance parameter
d = 8567) #max distance value - Q1 : 8567 km
#select for all i,j flow values up to 0
flow.d<-tab.flow %>%
select(i,j,flowfilter) %>%
filter(flowfilter !=0)
head(flow.d)
## i j flowfilter
## 1 T1 T8 18756
## 2 T10 T11 11707
## 3 T10 T8 6236
## 4 T10 T9 3497
## 5 T11 T10 9359
## 6 T12 T2 5728
Flowmap filtered according to a maximum distance travelled parameter
Using the flowreduct()
d.criteria as “dmax” distance parameter to plot flows less than the maximum distance criterion (here : 8,5 km).
# Graphic parameters
knitr::opts_chunk$set(fig.width=6, fig.height=6)
par(mar=c(0,0,1,0))
extent <- c(2800000, 1340000, 6400000, 4800000)
resolution<-150
# Overlay a spatial background
par(bg = "NA")
# Add the corresponding background
plot(st_geometry(map), col = NA, border=NA, bg="#dfe6e1")
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
## Warning in polypath(p_bind(x[[i]]), border = border[i], lty = lty[i], lwd =
## lwd[i], : Path drawing non disponible pour ce périphérique
#Flowmap : flow travelled less than 8.5 km (as the first quartile Q1)
flowmap(tab=flow.d,
fij="flowfilter",origin.f = "i",destination.f = "j",
bkg = map,code="EPT_NUM",nodes.X="X",nodes.Y = "Y",
filter=TRUE,
taille=8,
a.head = 1,
a.length = 0.11,
a.col="#f7714f",
add=TRUE)
## Warning in st_centroid.sf(.): st_centroid assumes attributes are constant over
## geometries of x
## you use the default threshold= 1
#Map legend
legendPropLines(pos="topleft",
title.txt="Number of commuters\n(distance travelled less than 8,5 km)",
title.cex=0.8,
cex=0.5,
values.cex= 0.7,
var=c(min(flow.d$flowfilter),8567),
col="#f7714f",
lwd=8,
frame = FALSE,
values.rnd = 0
)
#Map cosmetic
layoutLayer(title = "Professional mobility in Greater Paris : short distance travelled",
author = "Cartograflow, 2020",
sources = "Data : INSEE, 2017 ; Basemap : APUR, RIATE, 2018.",
scale = 2,
tabtitle = FALSE,
frame = TRUE,
col = "grey",
coltitle ="black"
)
# north arrow
north("topright")
Flowmap filtered according to a minimum distance travelled parameter
Using the flowreduct()
d.criteria as “dmin” distance parameter to plot flows above the minimum distance criterion (here : 20 km).
Using the flowreduct()
*d.criteria as “dmax” distance parameter in association with a flowmap()
_“threshold”_** value to map flows between two values (here between the first and third quartiles [Q1 - Q3]) - Not show.
Filtering an Origin-Destination matrix with an ordinal distance matrix. This matrix describes a neighborhood space defined by a number (k) of boundaries to be crossed in order to reach a place of destination from a place of origin. The aim is to map local flows that are either adjacent or located at low (k).
Main function
flowcontig()
Useful additional function
flowreduct()
with the metric
parameter: “ordinal”.
Computes the neighbouring graph
Example is for neighbouring areas which share a common boundary (k=1)
library(igraph)
## Neighbouring graph (order k= 1)
graph_ckij_1<-flowcontig(bkg=map, code="EPT_NUM",
k=1, algo = "automatic")
## [1] "ordre max = 3"
Plot the neighbouring graph (k=1)
Flow reduction according to the neighbouring graph
Reducing flow matrix by the neighbouring graph (k=1)
library(rlang)
#head(tabflow)
#head(graph_ckij_1)
reduc_k1<-flowreduct(tabflow,
graph_ckij_1,
metric = "ordinal")
head(reduc_k1)
## i j flow ordre.c
## 1 T1 T10 8297 1
## 2 T1 T12 17064 1
## 3 T1 T2 12163 1
## 4 T1 T3 32682 1
## 5 T1 T4 81129 1
## 6 T1 T5 16622 1
Flowmap between adjacent areas
Using (k=1) parameter
# Graphic parameters
knitr::opts_chunk$set(fig.width=6, fig.height=6)
par(mar=c(0,0,1,0))
extent <- c(2800000, 1340000, 6400000, 4800000)
resolution<-150
# Overlay a spatial background
par(bg = "NA")
# Add the corresponding background
plot(st_geometry(map), col = NA, border=NA, bg="#dfe6e1")
plot(st_geometry(map), col = "light grey", add=TRUE)
#Flowmap : flow travelled between adjacent areas
flowmap(tab=reduc_k1,
fij="flow",origin.f = "i",destination.f = "j",
bkg = map,code="EPT_NUM",nodes.X="X",nodes.Y = "Y",
filter=TRUE,
taille=8,
a.head = 1,
a.length = 0.11,
a.col="#0e7fe3",
add=TRUE
)
# Map Legend
legendPropLines(pos="topleft",
title.txt="Number of commuters in adjacent places\n(k=1)",
title.cex=0.8,
cex=0.5,
values.cex= 0.7,
var=c(min(reduc_k1$flow),max(reduc_k1$flow)),
col="#0e7fe3",
lwd=8,
frame = FALSE,
values.rnd = 0
)
# Map cosmetic
layoutLayer(title = "Professional mobility in Greater Paris between 1-neighbouring municipalities",
author = "Cartograflow, 2020",
sources = "Data : INSEE, 2017 ; Basemap : APUR, RIATE, 2018.",
scale = 2,
tabtitle = FALSE,
frame = TRUE,
col = "grey",
coltitle ="black")
Flowmap between non adjacent areas
Using for example (k=3) parameter.
Flowmap reducing and filtering according to ordinal matrix
Using the flowcontig()
(k) parameter in association to the flowmap()
threshold parameter to map above-average flows that occur between adjacent areas. - Not show.
#Computes k=1
library(igraph)
#Neighbouring graph k=1
graph_ckij_1<-flowcontig(bkg=map, code="EPT_NUM",k=1)
## [1] "ordre max = 3"
#Flow reduction
reduc_k1<-flowreduct(tabflow,
graph_ckij_1,
metric = "ordinal")
#Mean flow value
reduc_k1_mean<-mean(reduc_k1$flow)
mean<-mean(tabflow$Fij)
# mean value of reduc_k1_mean =18591
# mean value of tabflow =13220
# Graphic parameters
knitr::opts_chunk$set(fig.width=6, fig.height=6)
par(mar=c(0,0,1,0))
extent <- c(2800000, 1340000, 6400000, 4800000)
resolution<-150
# Overlay a spatial background
par(bg = "NA")
# Add the corresponding background
plot(st_geometry(map), col = NA, border=NA, bg="#dfe6e1")
plot(st_geometry(map), col = "light grey", add=TRUE)
#Flowmap : flow travelled between adjacent areas
flowmap(tab=reduc_k1,
fij="flow",origin.f = "i",destination.f = "j",
bkg = map,code="EPT_NUM",nodes.X="X",nodes.Y = "Y",
filter=TRUE,
threshold = 13220, #reduc_k1 mean value is 18591 ; tabflow mean value is 13220
taille=8,
a.head = 1,
a.length = 0.11,
a.col="#0e7fe3",
add=TRUE
)
# Map Legend
legendPropLines(pos="topleft",
title.txt="Number of above-average flows that occur between adjacent areas\n(k=1)",
title.cex=0.8,
cex=0.5,
values.cex= 0.7,
var=c(min(reduc_k1$flow),max(reduc_k1$flow)),
col="#0e7fe3",
lwd=8,
frame = FALSE,
values.rnd = 0
)
# Map cosmetic
layoutLayer(title = "Professional mobility in Greater Paris between 1-neighbouring municipalities",
author = "Cartograflow, 2020",
sources = "Data : INSEE, 2017 ; Basemap : APUR, RIATE, 2018.",
scale = 2,
tabtitle = FALSE,
frame = TRUE,
col = "grey",
coltitle ="black")
– Statistical dataset :
- INSEE - Base flux de mobilité (2015) - URL : https://www.insee.fr/fr/statistiques/fichier/3566008/rp2015_mobpro_txt.zip
– Geographical dataset : - municipalities : IGN, GEOFLA 2015 v2.1 - Greater Paris : APUR, UMS 2414 RIATE, 2018.
## R Under development (unstable) (2020-01-27 r77729)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04 LTS
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
##
## locale:
## [1] LC_CTYPE=fr_FR.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=fr_FR.UTF-8 LC_COLLATE=C
## [5] LC_MONETARY=fr_FR.UTF-8 LC_MESSAGES=fr_FR.UTF-8
## [7] LC_PAPER=fr_FR.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] igraph_1.2.5 rlang_0.4.6 cartography_2.4.1 cartograflow_1.0.1
## [5] dplyr_0.8.99.9003 sf_0.9-3
##
## loaded via a namespace (and not attached):
## [1] tidyselect_1.1.0 xfun_0.13 purrr_0.3.4 reshape2_1.4.4
## [5] lattice_0.20-41 colorspace_1.4-1 vctrs_0.3.0 generics_0.0.2
## [9] htmltools_0.4.0 viridisLite_0.3.0 yaml_2.2.1 plotly_4.9.2.1
## [13] e1071_1.7-3 pillar_1.4.4 foreign_0.8-79 glue_1.4.1
## [17] DBI_1.1.0 sp_1.4-1 lifecycle_0.2.0 plyr_1.8.6
## [21] stringr_1.4.0 rgeos_0.5-3 munsell_0.5.0 gtable_0.3.0
## [25] htmlwidgets_1.5.1 evaluate_0.14 labeling_0.3 knitr_1.28
## [29] crosstalk_1.1.0.1 maptools_1.0-1 class_7.3-17 Rcpp_1.0.4.6
## [33] KernSmooth_2.23-17 scales_1.1.1 classInt_0.4-3 jsonlite_1.6.1
## [37] ggplot2_3.3.0 digest_0.6.25 stringi_1.4.6 grid_4.0.0
## [41] tools_4.0.0 magrittr_1.5 lazyeval_0.2.2 tibble_3.0.1
## [45] crayon_1.3.4 tidyr_1.0.3 pkgconfig_2.0.3 ellipsis_0.3.0
## [49] data.table_1.12.8 rmarkdown_2.1 httr_1.4.1 R6_2.4.1
## [53] units_0.6-6 compiler_4.0.0