The genoscape can be thought of as the bright colors smeared across space that show where different genetically identifiable groups of birds reside on the breeding grounds. These genoscapes are stored as rasters, and transparency is used to indicate how much confidence one has in the genetic identification of individuals in different areas. These rasters are made by interpolating Q-values from a program like STRUCTURE or ADMIXTURE between individuals that were sampled in space.
The steps to making a genoscape from a matrix of Q-values (i.e., like those estimated from structure) followed here are those that appear on GitHub Pages, here. We reiterate that treatment here, having updated all the links and dependencies to work in this repository.
This chronicles the steps taken whilst making a genoscape for willow flycatchers. The order in which we discuss building up this map is different from the order in which we put layers down to actually make the map. Here, we will start with making the genoscape, which is actually the part that sits atop the whole map. We do this, because it doesn't take too long to plot these features, and using them is a good way to figure out the desired extent of your map and to decide upon a projection. Finally, we will talk about the bottom layer of the map, which is the raster with earthforms and shading from Natural Earth Data.
This work draws on a few functions that I have in packages that I have up on GitHub, namely:
tess3r
. Note that you can't use the default version of tess3r
, you have to use my fork of it, which has some extra functionality.genoscapeRtools
You should have already installed those packages as part of the ruegg-et-al-wifl-genoscape
depencies. But, if you have not:
remotes::install_github("eriqande/TESS3_encho_sen") # for special version of tess3r
remotes::install_github("eriqande/genoscapeRtools") # for Eric's genoscapeRtools
The rest of the packages you need can be downloaded from CRAN. Again, you should have already gotten them as dependencies for the repo, but if not, get raster
, sf
, fields
, ggspatial
, downloader
, and tidyverse
. The last one there gets ggplot2 and a number of other packages by Hadley Wickham.
You can get those like this:
install.packages(c("raster", "sf", "tidyverse", "fields", "ggspatial", "downloader"))
library(raster) # important to load before tidyverse, otherwise it masks select()
library(tidyverse)
library(sf)
library(ggspatial)
In 004-combine-RAD-and-fludigm-breeders-and-run-STRUCTURE.Rmd
we set up the structure runs to get the \(Q\)-values. Of all the runs done there and depicted in Supporting Information Figure 2, the run that had converged (without any prior information about sampling location) to the best representation of the spatial arrangement of the samples was \(K=7\), replicate run #4. That run was chosen to make the genoscape. The Q-values from that run are stored in this repository in ./stored_results/004/Struct-q-values-k007_Rep004.txt
.
We read them in and work with them.
Q_tibble <- read_table2("stored_results/004/Struct-q-values-k007_Rep004.txt", col_names = FALSE)
names(Q_tibble) <- c(
"id",
"INW",
"EST",
"PNW",
"SSW",
"SCC",
"KER",
"WMT"
)
Here is a quick look at the top of that Q_tibble:
head(Q_tibble)
Column id
is the sample name and the rest are ancestry fractions to different clusters (named with three characters) estimated by STRUCTURE.
Get the colors as well:
# we also have colors for those stored in the repo:
source("R/colors.R")
# that has defined this:
cluster_colors
## INW EST PNW SSW SCC KER WMT
## "#984ea3" "#377eb8" "#4daf4a" "#ff7f00" "#ffff33" "#e41a1c" "#00ffff"
First, let us just make a distruct-like plot to remind us of this. We can use ggplot2 to do that:
# first, we want to get the region from the names of the samples, so we can
# print these atop the plot
region_names_and_positions <- Q_tibble %>%
mutate(
idx = 1:n(),
region = str_replace(id, "[rf][0-9]+$", "")
) %>%
group_by(region) %>%
summarise(
first = min(idx),
last = max(idx),
mid = (min(idx) + max(idx)) / 2
) %>%
arrange(first)
# then we have to pivot the data frame into longer format:
qlong <- Q_tibble %>%
mutate(idx = 1:n()) %>%
pivot_longer(
cols = -c(id, idx),
names_to = "cluster",
values_to = "q"
)
# then plot that dude
g <- ggplot() +
geom_col(
data = qlong,
mapping = aes(x = idx, y = q, fill = cluster),
colour = NA
) +
scale_fill_manual(values = cluster_colors) +
geom_segment(
data = region_names_and_positions,
mapping = aes(
x = first,
xend = first,
y = 0,
yend = 1
),
size = 0.5
) +
geom_text(
data = region_names_and_positions,
mapping = aes(
x = mid,
y = 1.05,
label = region
),
angle = 70
)
g
We also need to know where those individuals were sampled in space. We have that here:
LatLong_tibble <- read_csv("data/appendices/app1-SITable1_Breed_IndvAssigwgenos.csv") %>%
select(group_af_short_name, Lat, Long) %>%
rename(
id = group_af_short_name
)
head(LatLong_tibble)
Finally, we need to have a GIS Shapefile that tells us the range of the breeding birds, so that genoscape can be clipped properly. We read this shapefile with the st_read()
function from package sf
.
breeding_range <- st_read("data/WIFL_RangeMap/WIFLrev.shp")
We can plot those polygons to see what they look like:
ggplot(breeding_range) +
geom_sf() +
theme_bw()
Within Eric's fork of tess3r
is a function called tess3Q_map_rasters
. It takes input from the objects we have above, but it takes that input as matrices rather than data frames, etc. so there is a little finagling to be done.
We need to ensure that we have values for birds in the right order (a job for aleft_join
), and we also have to make it a matrix with Longitude in the first column and Lat in the second.
long_lat_tibble <- Q_tibble %>%
select(id) %>%
left_join(LatLong_tibble, by = "id") %>%
select(Long, Lat)
long_lat_matrix <- long_lat_tibble %>%
as.matrix()
Pull off the names of individuals and make a matrix of it:
Q_matrix <- Q_tibble %>%
select(-id) %>%
as.matrix()
For this, we use the above variables in tess3r::tess3Q_map_rasters()
. Note the use of namespace addressing for this function rather than loading the whole tess3r
package with the library()
command.
genoscape_brick <- tess3r::tess3Q_map_rasters(
x = Q_matrix,
coord = long_lat_matrix,
map.polygon = breeding_range,
window = extent(breeding_range)[1:4],
resolution = c(300,300), # if you want more cells in your raster, set higher
# this next lines need to to be here, but don't do much...
col.palette = tess3r::CreatePalette(cluster_colors, length(cluster_colors)),
method = "map.max",
interpol = tess3r::FieldsKrigModel(10),
main = "Ancestry coefficients",
xlab = "Longitude",
ylab = "Latitude",
cex = .4
)
# after that, we need to add names of the clusters back onto this raster brick
names(genoscape_brick) <- names(Q_tibble)[-1]
That gives us a raster brick of Q-values associated with each cell in the raster, but those values are not always constrained between 0 and 1, so we have to massage them a little bit in the next section.
For this we use the function genoscapeRtools::qprob_rando_raster()
. This takes the raster brick that comes out of tess3Q_map_rasters() and does some rescaling and (maybe) some random sampling to return a raster of colors that I hope will do a reliable job of representing (in some way) predicted assignment accuracy over space. See ?genoscapeRtools::qprob_rando_raster
to learn about the scaling options, etc.
This will squash the raster brick down to a single RGBA (i.e., four channels, red, green, blue and alpha) raster brick.
genoscape_rgba <- genoscapeRtools::qprob_rando_raster(
TRB = genoscape_brick,
cols = cluster_colors,
alpha_scale = 2.0,
abs_thresh = 0.0,
alpha_exp = 1.55,
alpha_chop_max = 230
)
# at this point, we must be explicit about adding a projection to the raster.
# This adds the info for a regular lat-long projection
crs(genoscape_rgba) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
We can easily plot this with the function layer_spatial
from the ggspatial
package:
ggplot() +
ggspatial::layer_spatial(genoscape_rgba) +
theme_bw() +
coord_sf()
From this plot it is clear which sampling location belong to which regions/clusters/colors of the genoscape. Breeding birds were placed into such colors/clusters according to their spatial location (and not by their individual Structure Q-values, etc.) We do that here:
source("R/assign_points_to_raster_regions.R")
# let's get the ids and the lat-longs of all these birds
# again, so we can check what we have in the appendix
LLG_tibble <- read_csv("data/appendices/app1-SITable1_Breed_IndvAssigwgenos.csv") %>%
select(group_af_short_name, Lat, Long, repunit, Stage) %>%
rename(
id = group_af_short_name
)
# now, we find which section of the genoscape each point is in
LLG_with_spatial <- assign_points_to_raster_regions(
genoscape_brick,
LLG_tibble
)
The results here have been recorded in the data supplement: app1-SITable1_Breed_IndvAssigwgenos.csv
in the repunit
column.
We show here that the repunit
column and the spatial_group
(just computed) are same for all birds except for the samples from Bishop, CA:
LLG_with_spatial %>%
filter(repunit != spatial_group)
This one sampling location was indeterminate in the genoscape, lying at the intersection of four different clusters/colors. Further, the sample was populated with individuals that showed genetic affiliation to a number of different groups, suggesting that some may have been migrants. Furthermore, the population in Bishop is very small and thus would not be expected to contribute birds to the wintering samples. Therefore, in app1-SITable1_Breed_IndvAssigwgenos.csv
, their repunit is designated as BIS
, but they will be removed from the reference data set for identification of wintering birds.
The following plot shows the location of the Bishop samples highlighted by a large, black circle. Note that it does not show clear affiliation with any of the other regions, unlike the other sampling points.
ggplot() +
layer_spatial(genoscape_rgba) +
geom_spatial_point(
data = long_lat_tibble,
mapping = aes(x = Long, y = Lat), size = 0.2
) +
annotate(
"point",
x = -118.4800,
y = 37.4083,
size = 9,
shape = 21,
fill = NA
) +
theme_bw() +
coord_sf()
Since we will be using the Natural Earth Data Set for the raster background of our map, we will also use the Natural Earth lines and polygons. The Natural Earth data set is an amazing, open-source resource for making beautiful maps. Check it out at naturalearthdata.com.
For coastlines, countries, and states/provinces, you will need to download three different shape files. We will be working with the highest resolution Natural Earth data sets which are the 10m
versions. According to the dependencies, (see the README), you should have already downloaded these and unzipped them to a directory within the top level of the RStudio project called geo-spatial
.
First read it in:
coastlines <- st_read("geo-spatial/ne_10m_coastline/ne_10m_coastline.shp")
## Reading layer `ne_10m_coastline' from data source `/Users/eriq/Documents/git-repos/ruegg-et-al-wifl-genoscape/geo-spatial/ne_10m_coastline/ne_10m_coastline.shp' using driver `ESRI Shapefile'
## Simple feature collection with 4133 features and 3 fields
## geometry type: LINESTRING
## dimension: XY
## bbox: xmin: -180 ymin: -85.22194 xmax: 180 ymax: 83.6341
## geographic CRS: WGS 84
Now, let's just crop out the part that we want. This is somewhat key: right here we will define the extent in lat-long of the region that we want to plot:
# note! it is important to put the elements of domain in this
# order, because the function raster::extent() is expecting things
# to be in this order, and doesn't parse the names of the vectors
# the way sf::st_crop() does.
domain <- c(
xmin = -135,
xmax = -60,
ymin = 22,
ymax = 60
)
coast_cropped <- st_crop(coastlines, domain)
## Warning: attribute variables are assumed to be spatially constant throughout all
## geometries
Then plot the cropped part:
ggplot(coast_cropped) +
geom_sf() +
coord_sf()
OK, that was pretty reasonable. Now crop all the lines to domain
and plot them, and put the genoscape on top of that, too.
countries_cropped <- st_read("geo-spatial/ne_10m_admin_0_boundary_lines_land/ne_10m_admin_0_boundary_lines_land.shp") %>%
st_crop(domain)
## Reading layer `ne_10m_admin_0_boundary_lines_land' from data source `/Users/eriq/Documents/git-repos/ruegg-et-al-wifl-genoscape/geo-spatial/ne_10m_admin_0_boundary_lines_land/ne_10m_admin_0_boundary_lines_land.shp' using driver `ESRI Shapefile'
## Simple feature collection with 462 features and 18 fields
## geometry type: MULTILINESTRING
## dimension: XY
## bbox: xmin: -141.0055 ymin: -55.12092 xmax: 140.9776 ymax: 70.07531
## geographic CRS: WGS 84
## Warning: attribute variables are assumed to be spatially constant throughout all
## geometries
states_cropped <- st_read("geo-spatial/ne_10m_admin_1_states_provinces_lines/ne_10m_admin_1_states_provinces_lines.shp") %>%
st_crop(domain)
## Reading layer `ne_10m_admin_1_states_provinces_lines' from data source `/Users/eriq/Documents/git-repos/ruegg-et-al-wifl-genoscape/geo-spatial/ne_10m_admin_1_states_provinces_lines/ne_10m_admin_1_states_provinces_lines.shp' using driver `ESRI Shapefile'
## Simple feature collection with 10114 features and 21 fields
## geometry type: MULTILINESTRING
## dimension: XY
## bbox: xmin: -178.1371 ymin: -49.25087 xmax: 178.4486 ymax: 81.12853
## geographic CRS: WGS 84
## Warning: attribute variables are assumed to be spatially constant throughout all
## geometries
Now, plot it all. Notice we do it by just adding layers.
mapg <- ggplot() +
geom_sf(data = coast_cropped) +
geom_sf(data = countries_cropped, fill = NA) +
geom_sf(data = states_cropped, fill = NA) +
ggspatial::layer_spatial(genoscape_rgba) +
theme_bw()
# now plot it under default lat-long projection
mapg +
coord_sf()
That is looking like it should, but the projection is pretty ugly. In the next section we will consider projection.
The new version of ggplot2
makes it super easy to project everything on the fly by passing the projection to coord_sf()
. For things in North America, it seems that a Lambert conic projection does a nice job of keeping British Columbia and Alaska from looking way too big. We can define such a projection with a string, like this:
lamproj <- "+proj=lcc +lat_1=20 +lat_2=60 +lat_0=40 +lon_0=-100 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs"
Now, let's see how our developing map looks under such a projection. We just define lamproj
as a coordinate reference system and pass it in to coord_sf()
:
mapg +
coord_sf(crs = st_crs(lamproj))
I would call that decidedly better.
Now, all that remains is to put all of this on top of a nicely tinted map that shows landforms and things. Note that once we have such a layer under the rest of this stuff, we will probably omit the coastline layer, since it gets a little dark where the coastline is highly dissected.
The raster data should already have been downloaded and placed in the appropriate location by dealing with the dependencies in the README.
Reading a large raster in with the raster package does not take up much memory, because it leaves it on disk. So we will open a connection to the big, massive raster using the brick
function from the raster
package and then crop it:
hypso <- brick("geo-spatial/HYP_HR_SR_OB_DR/HYP_HR_SR_OB_DR.tif")
hypso_cropped <- crop(hypso, extent(domain))
Now, we just add hypso_cropped
in with ggspatial::spatial_layer()
below all of our other layers (dropping the coastlines), and we might make country and state lines thinner (and different sizes):
big_one <- ggplot() +
ggspatial::layer_spatial(hypso_cropped) +
geom_sf(data = countries_cropped, fill = NA, size = 0.15) +
geom_sf(data = states_cropped, fill = NA, size = 0.1) +
ggspatial::layer_spatial(genoscape_rgba) +
theme_bw() +
coord_sf(crs = st_crs(lamproj))
big_one
Seeing that sort of small on the screen does not really do justice to it. You can ggsave
it in whatever size is desired. For whatever the final product is going to be, you will want to mess with the line thickness on those country and state borders...
While that looks nice, most people might prefer to have the background part there in a rectangle, rather than a conic surface. We can do that by setting the xlim and ylim to coord_sf()
. But, note that we have to do that in terms of the units that the Lambert projection is referring to, not just in simple lat-long coordinates (i.e. we have to project those too!)
So, imagine that we want to chop out a rectangle from Haida Gwai, off the coast of British Columbia, straight down and straight across to the right (on the image). And we would want the bottom and right sides determined by a point in the bottom right that has the y-value of the tip of Florida, and an x-value which is essentially at St. John, New Brunswick. Then, we need to determine the x and y coordinates of those points under our Lambert conformal conic projection. We do that by making a simple features tibble of the lat-longs for those points and then projecting it.
# Here are lat longs for those points
pts <- tribble(
~place, ~long, ~lat,
"HaidaGwai", -132.3143526, 53.7298050,
"FloridaTip", -80.8032237, 25.0909780,
"St.Johns", -65.943453, 45.291222
)
# here we turn that into an sf object
pts_sf <- st_as_sf(pts, coords = c("long", "lat"),
crs = 4326) # 4326 is shorthand for "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
# and now we transform it to lambert
pts_lambert <- st_transform(pts_sf, crs = lamproj)
# when we print it in a notebook, we can see that the geometry is a list
# column, but can't see the values:
pts_lambert
So, for you to be able to see the values we can just print it like this:
# just note the values:
st_as_text(pts_lambert$geometry)
## [1] "POINT (-2010114 1821869)" "POINT (1871262 -1366911)"
## [3] "POINT (2452877 1037658)"
That means we want xlim = c(-2010114, 2452877) and ylim = c(-1366911, 1821869). Let's try that:
rectangled <- ggplot() +
ggspatial::layer_spatial(hypso_cropped) +
geom_sf(data = countries_cropped, fill = NA, size = 0.15) +
geom_sf(data = states_cropped, fill = NA, size = 0.1) +
ggspatial::layer_spatial(genoscape_rgba) +
theme_bw() +
coord_sf(
crs = st_crs(lamproj),
xlim = c(-2010114, 2452877),
ylim = c(-1366911, 1821869),
expand = FALSE) # expand = FALSE means put the axes right at the xlim and ylim
rectangled
Okay, that does it. In reality, you would probably want to expand the original domain
to be a bigger chunk of the earth, so that when you cut stuff off there was more left...
If you want to add more elements to the figure you can do so by giving them a lat-long and making a simple features tibble out of it and then putting them there using geom_sf(). It all fits nicely into the ggplot framework.
Also, the final genoscape figure in the paper included the wintering birds as well. For reasons of computing time, we aren't going to show the exact code for putting that together---it takes a long time to render. But, it should be obvious from the above how it was done.
Running the code and rendering this notebook required approximately this much time on a Mac laptop of middling speed, listed in HH:MM:SS
.
td <- Sys.time() - start_time
tdf <- hms::as_hms(ceiling(hms::as_hms(td)))
dir.create("stored_run_times", showWarnings = FALSE, recursive = TRUE)
write_rds(tdf, "stored_run_times/006.rds")
tdf
## 00:02:55
sessioninfo::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────
## setting value
## version R version 4.0.3 (2020-10-10)
## os macOS Mojave 10.14.6
## system x86_64, darwin17.0
## ui X11
## language (EN)
## collate en_US.UTF-8
## ctype en_US.UTF-8
## tz America/Denver
## date 2021-03-04
##
## ─ Packages ───────────────────────────────────────────────────────────────────
## package * version date lib
## abind 1.4-5 2016-07-21 [1]
## assertthat 0.2.1 2019-03-21 [1]
## backports 1.2.1 2020-12-09 [1]
## broom 0.7.3 2020-12-16 [1]
## cellranger 1.1.0 2016-07-27 [1]
## class 7.3-17 2020-04-26 [2]
## classInt 0.4-3 2020-04-07 [1]
## cli 2.2.0 2020-11-20 [1]
## codetools 0.2-16 2018-12-24 [2]
## colorspace 2.0-0 2020-11-11 [1]
## crayon 1.3.4 2017-09-16 [1]
## DBI 1.1.0 2019-12-15 [1]
## dbplyr 2.0.0 2020-11-03 [1]
## digest 0.6.27 2020-10-24 [1]
## dotCall64 1.0-0 2018-07-30 [1]
## dplyr * 1.0.2 2020-08-18 [1]
## e1071 1.7-4 2020-10-14 [1]
## ellipsis 0.3.1 2020-05-15 [1]
## evaluate 0.14 2019-05-28 [1]
## fansi 0.4.1 2020-01-08 [1]
## farver 2.0.3 2020-01-16 [1]
## fields 11.6 2020-10-09 [1]
## forcats * 0.5.0 2020-03-01 [1]
## fs 1.5.0 2020-07-31 [1]
## generics 0.1.0 2020-10-31 [1]
## genoscapeRtools 0.1.0 2021-01-17 [1]
## ggplot2 * 3.3.2 2020-06-19 [1]
## ggspatial * 1.1.5 2021-01-04 [1]
## glue 1.4.2 2020-08-27 [1]
## gtable 0.3.0 2019-03-25 [1]
## haven 2.3.1 2020-06-01 [1]
## hms 0.5.3 2020-01-08 [1]
## htmltools 0.5.0 2020-06-16 [1]
## httr 1.4.2 2020-07-20 [1]
## jsonlite 1.7.2 2020-12-09 [1]
## KernSmooth 2.23-17 2020-04-26 [2]
## knitr 1.30 2020-09-22 [1]
## labeling 0.4.2 2020-10-20 [1]
## lattice 0.20-41 2020-04-02 [2]
## lifecycle 0.2.0 2020-03-06 [1]
## lubridate 1.7.9.2 2020-11-13 [1]
## magrittr 2.0.1 2020-11-17 [1]
## maps 3.3.0 2018-04-03 [1]
## Matrix 1.2-18 2019-11-27 [2]
## modelr 0.1.8 2020-05-19 [1]
## munsell 0.5.0 2018-06-12 [1]
## pillar 1.4.7 2020-11-20 [1]
## pkgconfig 2.0.3 2019-09-22 [1]
## ps 1.5.0 2020-12-05 [1]
## purrr * 0.3.4 2020-04-17 [1]
## R6 2.5.0 2020-10-28 [1]
## raster * 3.4-5 2020-11-14 [1]
## Rcpp 1.0.5 2020-07-06 [1]
## RcppEigen 0.3.3.9.1 2020-12-17 [1]
## readr * 1.4.0 2020-10-05 [1]
## readxl 1.3.1 2019-03-13 [1]
## reprex 0.3.0 2019-05-16 [1]
## rgdal 1.5-19 2021-01-05 [1]
## rlang 0.4.9 2020-11-26 [1]
## rmarkdown 2.6 2020-12-14 [1]
## rstudioapi 0.13 2020-11-12 [1]
## rvest 0.3.6 2020-07-25 [1]
## scales 1.1.1 2020-05-11 [1]
## sessioninfo 1.1.1 2018-11-05 [1]
## sf * 0.9-6 2020-09-13 [1]
## sp * 1.4-4 2020-10-07 [1]
## spam 2.6-0 2020-12-14 [1]
## stringi 1.5.3 2020-09-09 [1]
## stringr * 1.4.0 2019-02-10 [1]
## tess3r 1.1.0 2021-01-17 [1]
## tibble * 3.0.4 2020-10-12 [1]
## tidyr * 1.1.2 2020-08-27 [1]
## tidyselect 1.1.0 2020-05-11 [1]
## tidyverse * 1.3.0 2019-11-21 [1]
## units 0.6-7 2020-06-13 [1]
## vctrs 0.3.6 2020-12-17 [1]
## withr 2.3.0 2020-09-22 [1]
## xfun 0.19 2020-10-30 [1]
## xml2 1.3.2 2020-04-23 [1]
## yaml 2.2.1 2020-02-01 [1]
## source
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.3)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.3)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.1)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## Github (eriqande/genoscapeRtools@3e1dbfc)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.3)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.3)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.3)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## Github (eriqande/TESS3_encho_sen@2a0ce6c)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
## CRAN (R 4.0.2)
##
## [1] /Users/eriq/Library/R/4.0/library
## [2] /Library/Frameworks/R.framework/Versions/4.0/Resources/library