Required current contributed CRAN packages:

I am running R 3.6.1, with recent update.packages().

needed <- c("rgdal", "spdep", "sf", "spData", "sp", "WDI", "wbstats", "eurostat",
            "SmarterPoland", "htmltools", "httr", "ggplot2", "rbenchmark",
            "readstata13", "foreign", "DBI", "RSQLite", "feather", "data.table", "readr")

Script

Script and data at https://github.com/rsbivand/ban421_h19/raw/master/ban421_h19_wed.zip. Download to suitable location, unzip and use as basis.

Data output

Data output

  • We’ll examine output first, to give something to import without needing external files

  • We’ll use this blog post to prime the files, but with a broader selection of interfaces

  • The blog uses a number of contributed packages, but there are too many rows to try Excel

  • There is a lot of room for experimentation here

if (!file.exists("outdata")) dir.create("outdata")
set.seed(123)
df <- data.frame(replicate(10, sample(0:2000, 15 * 10^5, rep = TRUE)),
                 replicate(10, stringi::stri_rand_strings(1000, 5)))
dim(df)
## [1] 1500000      20

Data output: plain text files

system.time(write.table(df, file="outdata/df.txt", row.names = FALSE))
##    user  system elapsed 
##   8.856   0.129   9.077

Data output: csv text files

system.time(write.csv2(df, file = "outdata/df2.csv", row.names = FALSE))
##    user  system elapsed 
##   8.867   0.118   9.073
library(readr)
system.time(write_csv(df, path = "outdata/df.csv"))
##    user  system elapsed 
##   4.047   0.107   4.203
library(data.table)
system.time(fwrite(df, file = "outdata/df_dt.csv", row.names=FALSE))
##    user  system elapsed 
##   1.451   0.068   0.766
file.info(paste("outdata", list.files("outdata"), sep="/"))[,1, drop=FALSE]
##                        size
## outdata/df_dt.csv 156678659
## outdata/df.csv    156678659
## outdata/df.txt    186678699
## outdata/df2.csv   186678699
system.time(save(df, file="outdata/df_gz6.rda", compress="gzip", compression_level=6))
##    user  system elapsed 
##   7.804   0.030   7.904
system.time(save(df, file="outdata/df_gz0.rda", compress="gzip", compression_level=0))
##    user  system elapsed 
##   0.274   0.038   0.315

Data output: binary files

system.time(saveRDS(df, file="outdata/df.rds"))
##    user  system elapsed 
##   7.863   0.044   7.993
library(feather)
system.time(write_feather(df, "outdata/df.feather"))
##    user  system elapsed 
##   0.136   0.048   0.187
file.info(paste("outdata", list.files("outdata"), sep="/"))[,1, drop=FALSE]
##                         size
## outdata/df_dt.csv  156678659
## outdata/df_gz0.rda 120150055
## outdata/df_gz6.rda  29936378
## outdata/df.csv     156678659
## outdata/df.feather 120092160
## outdata/df.rds      29936369
## outdata/df.txt     186678699
## outdata/df2.csv    186678699

Data output: database tables

library(RSQLite)
library(DBI)
con <- dbConnect(RSQLite::SQLite(), "outdata/df.sqlite")
system.time(dbWriteTable(con, "df", df, overwrite=TRUE))
##    user  system elapsed 
##   2.996   0.099   3.144
dbDisconnect(con)

Data output: Stata file

library(foreign)
system.time(write.dta(df, file="outdata/df.dta"))
##    user  system elapsed 
##   0.979   0.052   1.033
library(readstata13)
system.time(save.dta13(df, file="outdata/df_s13.dta"))
##    user  system elapsed 
##   3.272   0.112   3.390

Data output

file.info(paste("outdata", list.files("outdata"), sep="/"))[,1, drop=FALSE]
##                         size
## outdata/df_dt.csv  156678659
## outdata/df_gz0.rda 120150055
## outdata/df_gz6.rda  29936378
## outdata/df_s13.dta 120145152
## outdata/df.csv     156678659
## outdata/df.dta     120143836
## outdata/df.feather 120092160
## outdata/df.rds      29936369
## outdata/df.sqlite  146665472
## outdata/df.txt     186678699
## outdata/df2.csv    186678699

Data input

Data input

  • Many of the alternatives are the same for input for obvious reasons

  • For text and csv files, readr and data.table complement functions in the base package utils

  • Many of the binary variants read uncompressed files, so importing from compressed should take longer

  • importing from databases should take longer, but may permit subsetting prior to import

Data input: text files

system.time(df_in <- read.table("outdata/df.txt", header=TRUE))
##    user  system elapsed 
##   6.230   0.178   6.418
class(df_in)
## [1] "data.frame"
head(df_in[,c(1, 11)])
##    X1  X1.1
## 1 414 mJ55t
## 2 462 9V9dp
## 3 178 e12rf
## 4 525 VRfYu
## 5 194 PZjfT
## 6 937 lhWUD
system.time(df_in <- read.table("outdata/df.txt", header=TRUE, stringsAsFactors=FALSE))
##    user  system elapsed 
##   5.520   0.082   5.613
class(df_in)
## [1] "data.frame"
head(df_in[,c(1,11)])
##    X1  X1.1
## 1 414 mJ55t
## 2 462 9V9dp
## 3 178 e12rf
## 4 525 VRfYu
## 5 194 PZjfT
## 6 937 lhWUD
system.time(df_in <- read.csv2("outdata/df2.csv"))
##    user  system elapsed 
##   5.841   0.066   5.917
class(df_in)
## [1] "data.frame"
head(df_in[,c(1,11)])
##    X1  X1.1
## 1 414 mJ55t
## 2 462 9V9dp
## 3 178 e12rf
## 4 525 VRfYu
## 5 194 PZjfT
## 6 937 lhWUD
system.time(df_in <- read.csv2("outdata/df2.csv", stringsAsFactors=FALSE))
##    user  system elapsed 
##   6.235   0.045   6.293
class(df_in)
## [1] "data.frame"
head(df_in[,c(1,11)])
##    X1  X1.1
## 1 414 mJ55t
## 2 462 9V9dp
## 3 178 e12rf
## 4 525 VRfYu
## 5 194 PZjfT
## 6 937 lhWUD
library(readr)
system.time(suppressMessages(df_in <- read_csv2("outdata/df2.csv", progress = FALSE)))
##    user  system elapsed 
##   2.483   0.020   2.580
class(df_in)
## [1] "spec_tbl_df" "tbl_df"      "tbl"         "data.frame"
head(df_in[,c(1,11)])
## # A tibble: 6 x 2
##      X1 X1.1 
##   <dbl> <chr>
## 1   414 mJ55t
## 2   462 9V9dp
## 3   178 e12rf
## 4   525 VRfYu
## 5   194 PZjfT
## 6   937 lhWUD
library(data.table)
system.time(df_in <- fread("outdata/df_dt.csv", showProgress = FALSE))
##    user  system elapsed 
##   1.226   0.015   0.678
class(df_in)
## [1] "data.table" "data.frame"
head(df_in[,c(1,11)])
##     X1  X1.1
## 1: 414 mJ55t
## 2: 462 9V9dp
## 3: 178 e12rf
## 4: 525 VRfYu
## 5: 194 PZjfT
## 6: 937 lhWUD

Comparison: text

library(rbenchmark);
res <- benchmark("CSV_factor"=read.csv2("outdata/df2.csv"),
          "CSV"=read.csv2("outdata/df2.csv", stringsAsFactors=FALSE),
          "readr_CSV"=suppressMessages(read_csv2("outdata/df2.csv", progress = FALSE)),
          "fread_CSV"=fread("outdata/df_dt.csv", showProgress = FALSE),
          replications=10, order="elapsed")
res[,1:4]
##         test replications elapsed relative
## 4  fread_CSV           10   7.565    1.000
## 3  readr_CSV           10  26.637    3.521
## 2        CSV           10  59.065    7.808
## 1 CSV_factor           10  63.247    8.360

Data input: binary files

system.time({load("outdata/df_gz6.rda"); df_in <- df})
##    user  system elapsed 
##   0.482   0.004   0.487
class(df_in)
## [1] "data.frame"
head(df_in[,c(1,11)])
##    X1  X1.1
## 1 414 mJ55t
## 2 462 9V9dp
## 3 178 e12rf
## 4 525 VRfYu
## 5 194 PZjfT
## 6 937 lhWUD
system.time({load("outdata/df_gz0.rda"); df_in <- df})
##    user  system elapsed 
##   0.242   0.021   0.263
class(df_in)
## [1] "data.frame"
head(df_in[,c(1,11)])
##    X1  X1.1
## 1 414 mJ55t
## 2 462 9V9dp
## 3 178 e12rf
## 4 525 VRfYu
## 5 194 PZjfT
## 6 937 lhWUD
system.time(df_in <- readRDS("outdata/df.rds"))
##    user  system elapsed 
##   0.496   0.017   0.514
class(df_in)
## [1] "data.frame"
head(df_in[,c(1,11)])
##    X1  X1.1
## 1 414 mJ55t
## 2 462 9V9dp
## 3 178 e12rf
## 4 525 VRfYu
## 5 194 PZjfT
## 6 937 lhWUD
library(feather)
system.time(df_in <- read_feather("outdata/df.feather"))
##    user  system elapsed 
##   0.032   0.025   0.058
class(df_in)
## [1] "tbl_df"     "tbl"        "data.frame"
head(df_in[,c(1,11)])
## # A tibble: 6 x 2
##      X1 X1.1 
##   <int> <fct>
## 1   414 mJ55t
## 2   462 9V9dp
## 3   178 e12rf
## 4   525 VRfYu
## 5   194 PZjfT
## 6   937 lhWUD
library(foreign)
system.time(df_in <- read.dta("outdata/df.dta"))
##    user  system elapsed 
##   3.594   0.170   3.777
class(df_in)
## [1] "data.frame"
head(df_in[,c(1,11)])
##    X1  X1_1
## 1 414 mJ55t
## 2 462 9V9dp
## 3 178 e12rf
## 4 525 VRfYu
## 5 194 PZjfT
## 6 937 lhWUD
library(readstata13)
system.time(df_in <- read.dta13("outdata/df_s13.dta"))
##    user  system elapsed 
##   3.787   0.030   3.823
class(df_in)
## [1] "data.frame"
head(df_in[,c(1,11)])
##    X1  X1.1
## 1 414 mJ55t
## 2 462 9V9dp
## 3 178 e12rf
## 4 525 VRfYu
## 5 194 PZjfT
## 6 937 lhWUD

Data input: database tables

library(RSQLite)
library(DBI)
con <- dbConnect(RSQLite::SQLite(), "outdata/df.sqlite")
system.time(df_in <- dbReadTable(con, "df"))
##    user  system elapsed 
##   6.149   0.037   6.205
dbDisconnect(con)
class(df_in)
## [1] "data.frame"
head(df_in[,c(1,11)])
##    X1  X1.1
## 1 414 mJ55t
## 2 462 9V9dp
## 3 178 e12rf
## 4 525 VRfYu
## 5 194 PZjfT
## 6 937 lhWUD

Comparison: binary

res <- benchmark("SQLite"={con <- dbConnect(RSQLite::SQLite(), "outdata/df.sqlite");
       system.time(df_in <- dbReadTable(con, "df")); dbDisconnect(con)},
       "Stata"=read.dta("outdata/df.dta"),
       "Stata13"=read.dta("outdata/df.dta"),
       "feather"=read_feather("outdata/df.feather"),
       "RDS"=readRDS("outdata/df.rds"),
       "RDA0"=load("outdata/df_gz0.rda"),
       "RDA6"=load("outdata/df_gz6.rda"),
       replications=10, order="elapsed")
res[,1:4]
##      test replications elapsed relative
## 4 feather           10   0.458    1.000
## 6    RDA0           10   2.754    6.013
## 5     RDS           10   4.917   10.736
## 7    RDA6           10   4.996   10.908
## 3 Stata13           10  32.368   70.672
## 2   Stata           10  32.966   71.978
## 1  SQLite           10  81.519  177.989

Access to data

  • So far we’ve accessed public data from files downloaded from data providers

  • Many data providers now also offer application programming interfaces (APIs)

  • R contributed packages are providing access to these data catalogues and data repositories

  • Some require that users acquire an API key first, so that they can record activity

Some local data

The interfaces are not simple, because we have to ask for data using codes:

suppressMessages(library(SmarterPoland))
tmp <- grepEurostatTOC("regional")
str(tmp)
## 'data.frame':    24 obs. of  8 variables:
##  $ title                      : Factor w/ 8777 levels "                                Broadband and connectivity - households",..: 5018 3031 5183 4800 4799 3349 3350 3032 3033 2464 ...
##  $ code                       : Factor w/ 7976 levels "aact","aact_ali",..: 710 4830 4825 1247 1248 4304 4305 4573 7857 4825 ...
##  $ type                       : Factor w/ 4 levels "comext","dataset",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ last.update.of.data        : Factor w/ 482 levels " ","01.02.2018",..: 265 80 80 65 183 113 131 274 274 80 ...
##  $ last.table.structure.change: Factor w/ 348 levels " ","01.02.2018",..: 95 8 285 47 106 89 89 197 197 285 ...
##  $ data.start                 : Factor w/ 165 levels " ","1850","1925",..: 103 103 87 145 144 98 98 103 103 87 ...
##  $ data.end                   : Factor w/ 81 levels " ","1984","1991",..: 58 55 55 55 55 58 58 55 55 55 ...
##  $ values                     : logi  NA NA NA NA NA NA ...
demo_r_gind3 <- getEurostatRCV(kod="demo_r_gind3")
levels(demo_r_gind3$indic_de)
##  [1] "CNMIGRAT"   "CNMIGRATRT" "DEATH"      "GBIRTHRT"   "GDEATHRT"  
##  [6] "GROW"       "GROWRT"     "JAN"        "LBIRTH"     "NATGROW"   
## [11] "NATGROWRT"

The eurostat package

The eurostat package extends the handling of Eurostat data found in SmarterPoland:

suppressMessages(library(eurostat))
toc <- get_eurostat_toc()
str(toc)
## Classes 'spec_tbl_df', 'tbl_df', 'tbl' and 'data.frame': 9819 obs. of  8 variables:
##  $ title                      : chr  "Database by themes" "General and regional statistics" "European and national indicators for short-term analysis" "Business and consumer surveys (source: DG ECFIN)" ...
##  $ code                       : chr  "data" "general" "euroind" "ei_bcs" ...
##  $ type                       : chr  "folder" "folder" "folder" "folder" ...
##  $ last update of data        : chr  NA NA NA NA ...
##  $ last table structure change: chr  NA NA NA NA ...
##  $ data start                 : chr  NA NA NA NA ...
##  $ data end                   : chr  NA NA NA NA ...
##  $ values                     : chr  NA NA NA NA ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   .default = col_character(),
##   ..   title = col_character(),
##   ..   code = col_character(),
##   ..   type = col_character(),
##   ..   `last update of data` = col_character(),
##   ..   `last table structure change` = col_character(),
##   ..   `data start` = col_character(),
##   ..   `data end` = col_character(),
##   ..   values = col_character()
##   .. )

Disposable income example

The examples site has a spatial example:

df <- get_eurostat("tgs00026", time_format = "raw")
## Table tgs00026 cached at /tmp/RtmpING71M/eurostat/tgs00026_raw_code_TF.rds
df$time <- eurotime2num(df$time)

World Bank data

suppressMessages(library("wbstats"))
pop_gdp_data <- wb(country = c("PL"), indicator = c("SP.POP.TOTL", "NY.GDP.MKTP.CD"),
startdate = 1990, enddate = 2016)
head(pop_gdp_data)
##   iso3c date    value indicatorID         indicator iso2c country
## 1   POL 2016 37970087 SP.POP.TOTL Population, total    PL  Poland
## 2   POL 2015 37986412 SP.POP.TOTL Population, total    PL  Poland
## 3   POL 2014 38011735 SP.POP.TOTL Population, total    PL  Poland
## 4   POL 2013 38040196 SP.POP.TOTL Population, total    PL  Poland
## 5   POL 2012 38063164 SP.POP.TOTL Population, total    PL  Poland
## 6   POL 2011 38063255 SP.POP.TOTL Population, total    PL  Poland

World Development Index data

The WDI package also accesses World Bank WDI data:

suppressMessages(library("WDI"))
res <- WDIsearch('gdp')
str(res)
##  chr [1:493, 1:2] "BX.TRF.PWKR.GD.ZS" "BX.TRF.PWKR.DT.GD.ZS" ...
##  - attr(*, "dimnames")=List of 2
##   ..$ : NULL
##   ..$ : chr [1:2] "indicator" "name"

Parallel computing

Parallel computing

  • The HPC Task View is a good place to start, with the parallel package

  • I have a working paper from 2010 pointing to issues in choosing where to parallelize (bottom up or top down)

  • Exchanging the reference BLAS for a threaded BLAS is possible

Parallel computing: comparison

suppressMessages(library(spdep))
suppressMessages(require(rgdal, quietly=TRUE))
wheat <- readOGR(system.file("shapes/wheat.shp", package="spData"), verbose=FALSE)
nbr1 <- poly2nb(wheat, queen=FALSE)
nbrl <- nblag(nbr1, 2)
nbr12 <- nblag_cumul(nbrl)
cms0 <- with(as(wheat, "data.frame"), tapply(yield, c, median))
cms1 <- c(model.matrix(~ factor(c) -1, data=wheat) %*% cms0)
wheat$yield_detrend <- wheat$yield - cms1
RNGkind("L'Ecuyer-CMRG")
set.seed(1L)
system.time(boot_out_ser <- aple.mc(as.vector(scale(wheat$yield_detrend, scale=FALSE)),
 nb2listw(nbr12, style="W"), nsim=10000))
## Registered S3 methods overwritten by 'spatialreg':
##   method                   from 
##   residuals.stsls          spdep
##   deviance.stsls           spdep
##   coef.stsls               spdep
##   print.stsls              spdep
##   summary.stsls            spdep
##   print.summary.stsls      spdep
##   residuals.gmsar          spdep
##   deviance.gmsar           spdep
##   coef.gmsar               spdep
##   fitted.gmsar             spdep
##   print.gmsar              spdep
##   summary.gmsar            spdep
##   print.summary.gmsar      spdep
##   print.lagmess            spdep
##   summary.lagmess          spdep
##   print.summary.lagmess    spdep
##   residuals.lagmess        spdep
##   deviance.lagmess         spdep
##   coef.lagmess             spdep
##   fitted.lagmess           spdep
##   logLik.lagmess           spdep
##   fitted.SFResult          spdep
##   print.SFResult           spdep
##   fitted.ME_res            spdep
##   print.ME_res             spdep
##   print.lagImpact          spdep
##   plot.lagImpact           spdep
##   summary.lagImpact        spdep
##   HPDinterval.lagImpact    spdep
##   print.summary.lagImpact  spdep
##   print.sarlm              spdep
##   summary.sarlm            spdep
##   residuals.sarlm          spdep
##   deviance.sarlm           spdep
##   coef.sarlm               spdep
##   vcov.sarlm               spdep
##   fitted.sarlm             spdep
##   logLik.sarlm             spdep
##   anova.sarlm              spdep
##   predict.sarlm            spdep
##   print.summary.sarlm      spdep
##   print.sarlm.pred         spdep
##   as.data.frame.sarlm.pred spdep
##   residuals.spautolm       spdep
##   deviance.spautolm        spdep
##   coef.spautolm            spdep
##   fitted.spautolm          spdep
##   print.spautolm           spdep
##   summary.spautolm         spdep
##   logLik.spautolm          spdep
##   print.summary.spautolm   spdep
##   print.WXImpact           spdep
##   summary.WXImpact         spdep
##   print.summary.WXImpact   spdep
##   predict.SLX              spdep
##    user  system elapsed 
##   7.447   0.031   7.542

Parallel computing: socket cluster

suppressMessages(library(spdep))
library(parallel)
nc <- detectCores(logical=FALSE)
nc
## [1] 2
invisible(set.coresOption(nc))
set.seed(1L)
system.time({if (!get.mcOption()) {
  cl <- makeCluster(nc, "PSOCK")
  set.ClusterOption(cl)
} else{
  mc.reset.stream()
}
boot_out_par <- aple.mc(as.vector(scale(wheat$yield_detrend, scale=FALSE)),
    nb2listw(nbr12, style="W"), nsim=10000)
if (!get.mcOption()) {
  set.ClusterOption(NULL)
  stopCluster(cl)
}})
## Registered S3 methods overwritten by 'spatialreg':
##   method                   from 
##   residuals.stsls          spdep
##   deviance.stsls           spdep
##   coef.stsls               spdep
##   print.stsls              spdep
##   summary.stsls            spdep
##   print.summary.stsls      spdep
##   residuals.gmsar          spdep
##   deviance.gmsar           spdep
##   coef.gmsar               spdep
##   fitted.gmsar             spdep
##   print.gmsar              spdep
##   summary.gmsar            spdep
##   print.summary.gmsar      spdep
##   print.lagmess            spdep
##   summary.lagmess          spdep
##   print.summary.lagmess    spdep
##   residuals.lagmess        spdep
##   deviance.lagmess         spdep
##   coef.lagmess             spdep
##   fitted.lagmess           spdep
##   logLik.lagmess           spdep
##   fitted.SFResult          spdep
##   print.SFResult           spdep
##   fitted.ME_res            spdep
##   print.ME_res             spdep
##   print.lagImpact          spdep
##   plot.lagImpact           spdep
##   summary.lagImpact        spdep
##   HPDinterval.lagImpact    spdep
##   print.summary.lagImpact  spdep
##   print.sarlm              spdep
##   summary.sarlm            spdep
##   residuals.sarlm          spdep
##   deviance.sarlm           spdep
##   coef.sarlm               spdep
##   vcov.sarlm               spdep
##   fitted.sarlm             spdep
##   logLik.sarlm             spdep
##   anova.sarlm              spdep
##   predict.sarlm            spdep
##   print.summary.sarlm      spdep
##   print.sarlm.pred         spdep
##   as.data.frame.sarlm.pred spdep
##   residuals.spautolm       spdep
##   deviance.spautolm        spdep
##   coef.spautolm            spdep
##   fitted.spautolm          spdep
##   print.spautolm           spdep
##   summary.spautolm         spdep
##   logLik.spautolm          spdep
##   print.summary.spautolm   spdep
##   print.WXImpact           spdep
##   summary.WXImpact         spdep
##   print.summary.WXImpact   spdep
##   predict.SLX              spdep
##    user  system elapsed 
##   4.429   0.126   5.276

Parallel computing: forked cluster

system.time({if (!get.mcOption()) {
  cl <- makeCluster(nc, "FORK")
  set.ClusterOption(cl)
} else{
  mc.reset.stream()
}
boot_out_par <- aple.mc(as.vector(scale(wheat$yield_detrend, scale=FALSE)),
    nb2listw(nbr12, style="W"), nsim=10000)
if (!get.mcOption()) {
  set.ClusterOption(NULL)
  stopCluster(cl)
}})
##    user  system elapsed 
##   4.500   0.149   5.557

R’s sessionInfo()

sessionInfo()
## R version 3.6.1 (2019-07-05)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Fedora 30 (Workstation Edition)
## 
## Matrix products: default
## BLAS:   /home/rsb/topics/R/R361-share/lib64/R/lib/libRblas.so
## LAPACK: /home/rsb/topics/R/R361-share/lib64/R/lib/libRlapack.so
## 
## Random number generation:
##  RNG:     L'Ecuyer-CMRG 
##  Normal:  Inversion 
##  Sample:  Rejection 
##  
## locale:
##  [1] LC_CTYPE=en_GB.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_GB.UTF-8        LC_COLLATE=en_GB.UTF-8    
##  [5] LC_MONETARY=en_GB.UTF-8    LC_MESSAGES=en_GB.UTF-8   
##  [7] LC_PAPER=en_GB.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] parallel  stats     graphics  grDevices utils     datasets  methods  
## [8] base     
## 
## other attached packages:
##  [1] spdep_1.1-3       sf_0.8-1          spData_0.3.2     
##  [4] sp_1.3-1          WDI_2.6.0         wbstats_0.2      
##  [7] eurostat_3.3.5    SmarterPoland_1.7 htmltools_0.3.6  
## [10] httr_1.4.1        ggplot2_3.2.1    
## 
## loaded via a namespace (and not attached):
##  [1] Rcpp_1.0.2         lubridate_1.7.4    lattice_0.20-38   
##  [4] tidyr_1.0.0        deldir_0.1-23      gtools_3.8.1      
##  [7] class_7.3-15       assertthat_0.2.1   zeallot_0.1.0     
## [10] digest_0.6.21      spDataLarge_0.3.1  R6_2.4.0          
## [13] plyr_1.8.4         backports_1.1.4    coda_0.19-3       
## [16] evaluate_0.14      e1071_1.7-2        pillar_1.4.2      
## [19] rlang_0.4.0        lazyeval_0.2.2     curl_4.2          
## [22] gdata_2.18.0       gmodels_2.18.1     Matrix_1.2-17     
## [25] rmarkdown_1.15     splines_3.6.1      RefManageR_1.2.12 
## [28] readr_1.3.1        stringr_1.4.0      munsell_0.5.0     
## [31] broom_0.5.2        compiler_3.6.1     xfun_0.9          
## [34] pkgconfig_2.0.3    tidyselect_0.2.5   expm_0.999-4      
## [37] tibble_2.1.3       crayon_1.3.4       dplyr_0.8.3       
## [40] withr_2.1.2        spatialreg_1.1-3   MASS_7.3-51.4     
## [43] grid_3.6.1         nlme_3.1-141       jsonlite_1.6      
## [46] gtable_0.3.0       lifecycle_0.1.0    DBI_1.0.0         
## [49] magrittr_1.5       units_0.6-4        scales_1.0.0      
## [52] bibtex_0.4.2       KernSmooth_2.23-15 stringi_1.4.3     
## [55] LearnBayes_2.15.1  xml2_1.2.2         ellipsis_0.3.0    
## [58] vctrs_0.2.0        generics_0.0.2     boot_1.3-23       
## [61] RColorBrewer_1.1-2 tools_3.6.1        RJSONIO_1.3-1.2   
## [64] glue_1.3.1         purrr_0.3.2        hms_0.5.1         
## [67] yaml_2.2.0         colorspace_1.4-1   classInt_0.4-1    
## [70] knitr_1.25