feo.map

Mauro Lepore
2018-04-13 17:31:23

Overview

This document shows how to map specific species and tree-tags using a ViewFullTable.

Info:

Setup

Install.

# General purpose functions for data science
install.packages("tidyverse")

# Allow installation form GitHub
install.packages("remotes")

# More info: https://forestgeo.github.io/fgeo.map/
remotes::install_github("forestgeo/fgeo")

# Example data
remotes::install_github("forestgeo/fgeo.data")
library(tidyverse)
#> ── Attaching packages ─────────────────────────────────────────────────────────────────────── tidyverse 1.2.1 ──
#> ✔ ggplot2 2.2.1     ✔ purrr   0.2.4
#> ✔ tibble  1.4.2     ✔ dplyr   0.7.4
#> ✔ tidyr   0.8.0     ✔ stringr 1.3.0
#> ✔ readr   1.1.1     ✔ forcats 0.3.0
#> ── Conflicts ────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
#> ✖ dplyr::filter() masks stats::filter()
#> ✖ dplyr::lag()    masks stats::lag()
library(fgeo)
#> ── Attaching packages ─────────────────────────────────────────────────────────────────────── fgeo 0.0.0.9000 ──
#> ✔ bciex           0.0.0.9000     ✔ fgeo.habitat    0.0.0.9001
#> ✔ fgeo.abundance  0.0.0.9002     ✔ fgeo.map        0.0.0.9203
#> ✔ fgeo.demography 0.0.0.9000     ✔ fgeo.tool       0.0.0.9002
#> Warning in fun(libname, pkgname): couldn't connect to display ":0"
#> ── Conflicts ─────────────────────────────────────────────────────────────────────────────── fgeo_conflicts() ──
#> ✖ dplyr::filter()    masks stats::filter()
#> ✖ dplyr::intersect() masks base::intersect()
#> ✖ dplyr::lag()       masks stats::lag()
#> ✖ dplyr::setdiff()   masks base::setdiff()
#> ✖ dplyr::setequal()  masks base::setequal()
#> ✖ dplyr::union()     masks base::union()

Data

Data must be a ViewFullTable. Get it via ForestGEO's database.

# Example data from Barro Colorado Island
vft <- as.tibble(fgeo.data::bci_vft_random)
# Writing a .csv to demonstrate how to read a file sent by the database
write_csv(vft, "vft_from_database_for_examples.csv")
vft <- read_csv("vft_from_database_for_examples.csv")
#> Parsed with column specification:
#> cols(
#>   .default = col_integer(),
#>   PlotName = col_character(),
#>   Family = col_character(),
#>   Genus = col_character(),
#>   SpeciesName = col_character(),
#>   Mnemonic = col_character(),
#>   Subspecies = col_character(),
#>   QuadratName = col_character(),
#>   PX = col_double(),
#>   PY = col_double(),
#>   QX = col_double(),
#>   QY = col_double(),
#>   Tag = col_character(),
#>   PrimaryStem = col_character(),
#>   HOM = col_double(),
#>   ExactDate = col_date(format = ""),
#>   ListOfTSM = col_character(),
#>   LargeStem = col_character(),
#>   Status = col_character()
#> )
#> See spec(...) for full column specifications.

# Also `View(vft)`
vft
#> # A tibble: 2,257 x 32
#>      DBHID PlotName PlotID Family   Genus  SpeciesName Mnemonic Subspecies
#>      <int> <chr>     <int> <chr>    <chr>  <chr>       <chr>    <chr>     
#>  1 1621522 bci           1 Violace… Hyban… prunifolius hybapr   <NA>      
#>  2 1619521 bci           1 Violace… Hyban… prunifolius hybapr   <NA>      
#>  3 1632477 bci           1 Fabacea… Lonch… heptaphyll… loncla   <NA>      
#>  4 1630644 bci           1 Fabacea… Lonch… heptaphyll… loncla   <NA>      
#>  5 1077531 bci           1 Laurace… Beils… pendula     beilpe   <NA>      
#>  6 1074697 bci           1 Laurace… Beils… pendula     beilpe   <NA>      
#>  7  826469 bci           1 Violace… Rinor… sylvatica   rinosy   <NA>      
#>  8  823306 bci           1 Violace… Rinor… sylvatica   rinosy   <NA>      
#>  9 1006845 bci           1 Fabacea… Swart… simplex     swars2   ochnacea  
#> 10 1003843 bci           1 Fabacea… Swart… simplex     swars2   ochnacea  
#> # ... with 2,247 more rows, and 24 more variables: SpeciesID <int>,
#> #   SubspeciesID <int>, QuadratName <chr>, QuadratID <int>, PX <dbl>,
#> #   PY <dbl>, QX <dbl>, QY <dbl>, TreeID <int>, Tag <chr>, StemID <int>,
#> #   StemNumber <int>, StemTag <int>, PrimaryStem <chr>, CensusID <int>,
#> #   PlotCensusNumber <int>, DBH <int>, HOM <dbl>, ExactDate <date>,
#> #   Date <int>, ListOfTSM <chr>, HighHOM <int>, LargeStem <chr>,
#> #   Status <chr>

Demo maply_sp()

Wrangle

# Optional: Copy `Mnemonic` into `sp` -- a more intuitive name
vft <- vft %>% 
  mutate(sp = Mnemonic)

vft %>% select(sp, everything())
#> # A tibble: 2,257 x 33
#>    sp       DBHID PlotName PlotID Family      Genus   SpeciesName Mnemonic
#>    <chr>    <int> <chr>     <int> <chr>       <chr>   <chr>       <chr>   
#>  1 hybapr 1621522 bci           1 Violaceae   Hybant… prunifolius hybapr  
#>  2 hybapr 1619521 bci           1 Violaceae   Hybant… prunifolius hybapr  
#>  3 loncla 1632477 bci           1 Fabaceae-p… Loncho… heptaphyll… loncla  
#>  4 loncla 1630644 bci           1 Fabaceae-p… Loncho… heptaphyll… loncla  
#>  5 beilpe 1077531 bci           1 Lauraceae   Beilsc… pendula     beilpe  
#>  6 beilpe 1074697 bci           1 Lauraceae   Beilsc… pendula     beilpe  
#>  7 rinosy  826469 bci           1 Violaceae   Rinorea sylvatica   rinosy  
#>  8 rinosy  823306 bci           1 Violaceae   Rinorea sylvatica   rinosy  
#>  9 swars2 1006845 bci           1 Fabaceae-p… Swartz… simplex     swars2  
#> 10 swars2 1003843 bci           1 Fabaceae-p… Swartz… simplex     swars2  
#> # ... with 2,247 more rows, and 25 more variables: Subspecies <chr>,
#> #   SpeciesID <int>, SubspeciesID <int>, QuadratName <chr>,
#> #   QuadratID <int>, PX <dbl>, PY <dbl>, QX <dbl>, QY <dbl>, TreeID <int>,
#> #   Tag <chr>, StemID <int>, StemNumber <int>, StemTag <int>,
#> #   PrimaryStem <chr>, CensusID <int>, PlotCensusNumber <int>, DBH <int>,
#> #   HOM <dbl>, ExactDate <date>, Date <int>, ListOfTSM <chr>,
#> #   HighHOM <int>, LargeStem <chr>, Status <chr>

Store chosen species in a vector.

# Choosing, for example, a few, large trees
chosen_dbh <- 300
sp_chosen <- vft %>% 
  filter(DBH > chosen_dbh) %>% 
  select(DBH, sp, everything()) %>% 
  arrange(sp) %>% 
  pull(sp) %>% 
  unique()

sp_chosen
#>  [1] "alsebl" "brosal" "cecrin" "cordal" "eugene" "guapst" "heisco"
#>  [8] "huracr" "ingama" "jac1co" "poutre" "quaras" "tab2ar" "tri2tu"
#> [15] "virosp"

Subset the data to keep the observations that match the chosen species.

vft_chosen <- vft %>% 
  filter(sp %in% sp_chosen)

vft_chosen
#> # A tibble: 314 x 33
#>      DBHID PlotName PlotID Family   Genus  SpeciesName Mnemonic Subspecies
#>      <int> <chr>     <int> <chr>    <chr>  <chr>       <chr>    <chr>     
#>  1  828597 bci           1 Meliace… Trich… tuberculata tri2tu   <NA>      
#>  2  825434 bci           1 Meliace… Trich… tuberculata tri2tu   <NA>      
#>  3 1876882 bci           1 Erythro… Heist… concinna    heisco   <NA>      
#>  4 1877443 bci           1 Erythro… Heist… concinna    heisco   <NA>      
#>  5  440509 bci           1 Meliace… Trich… tuberculata tri2tu   <NA>      
#>  6  439821 bci           1 Meliace… Trich… tuberculata tri2tu   <NA>      
#>  7 1955821 bci           1 Sapotac… Poute… reticulata  poutre   <NA>      
#>  8 1957474 bci           1 Sapotac… Poute… reticulata  poutre   <NA>      
#>  9  742469 bci           1 Malvace… Quara… asterolepis quaras   <NA>      
#> 10  740125 bci           1 Malvace… Quara… asterolepis quaras   <NA>      
#> # ... with 304 more rows, and 25 more variables: SpeciesID <int>,
#> #   SubspeciesID <int>, QuadratName <chr>, QuadratID <int>, PX <dbl>,
#> #   PY <dbl>, QX <dbl>, QY <dbl>, TreeID <int>, Tag <chr>, StemID <int>,
#> #   StemNumber <int>, StemTag <int>, PrimaryStem <chr>, CensusID <int>,
#> #   PlotCensusNumber <int>, DBH <int>, HOM <dbl>, ExactDate <date>,
#> #   Date <int>, ListOfTSM <chr>, HighHOM <int>, LargeStem <chr>,
#> #   Status <chr>, sp <chr>

Map

Store maps in a list.

maps <- maply_tag(vft_chosen)
#> Warning in do.call(cond, list(customized)): Duplicated values were detected
#> * Likely you want only the last 2 censuses
#> * Detected censuses: 6, 171

# Showing only one map
first(maps)

Print each map in the list onto a .pdf

# Printing all plots of `p` to .pdf, with parameters optimized for size letter
pdf("maps.pdf", paper = "letter", height = 10.5, width = 8)
maps
dev.off()

Explore further

Exploring data by tag number.

vft %>% 
  filter(Tag == "260255") %>% 
  select(Tag, matches("census"), everything())
#> # A tibble: 3 x 33
#>   Tag    CensusID PlotCensusNumber   DBHID PlotName PlotID Family    Genus
#>   <chr>     <int>            <int>   <int> <chr>     <int> <chr>     <chr>
#> 1 260255        6                6 1438276 bci           1 Rubiaceae Alse…
#> 2 260255        6                6 1438283 bci           1 Rubiaceae Alse…
#> 3 260255      171                7 1435155 bci           1 Rubiaceae Alse…
#> # ... with 25 more variables: SpeciesName <chr>, Mnemonic <chr>,
#> #   Subspecies <chr>, SpeciesID <int>, SubspeciesID <int>,
#> #   QuadratName <chr>, QuadratID <int>, PX <dbl>, PY <dbl>, QX <dbl>,
#> #   QY <dbl>, TreeID <int>, StemID <int>, StemNumber <int>, StemTag <int>,
#> #   PrimaryStem <chr>, DBH <int>, HOM <dbl>, ExactDate <date>, Date <int>,
#> #   ListOfTSM <chr>, HighHOM <int>, LargeStem <chr>, Status <chr>,
#> #   sp <chr>
tags <- c("257260", "260255")
vft %>% 
  filter(Tag %in% tags) %>% 
  select(Tag, matches("quadrat"),  everything())
#> # A tibble: 5 x 33
#>   Tag    QuadratName QuadratID   DBHID PlotName PlotID Family    Genus    
#>   <chr>  <chr>           <int>   <int> <chr>     <int> <chr>     <chr>    
#> 1 257260 0112             1471 1425858 bci           1 Meliaceae Trichilia
#> 2 257260 0112             1471 1422534 bci           1 Meliaceae Trichilia
#> 3 260255 0001               64 1438276 bci           1 Rubiaceae Alseis   
#> 4 260255 0001               64 1438283 bci           1 Rubiaceae Alseis   
#> 5 260255 0001               64 1435155 bci           1 Rubiaceae Alseis   
#> # ... with 25 more variables: SpeciesName <chr>, Mnemonic <chr>,
#> #   Subspecies <chr>, SpeciesID <int>, SubspeciesID <int>, PX <dbl>,
#> #   PY <dbl>, QX <dbl>, QY <dbl>, TreeID <int>, StemID <int>,
#> #   StemNumber <int>, StemTag <int>, PrimaryStem <chr>, CensusID <int>,
#> #   PlotCensusNumber <int>, DBH <int>, HOM <dbl>, ExactDate <date>,
#> #   Date <int>, ListOfTSM <chr>, HighHOM <int>, LargeStem <chr>,
#> #   Status <chr>, sp <chr>

Demo add_sp() with a ViewFullTable

Choosing some some species

some_sp <- sample(vft$sp, 3)
some_sp
#> [1] "poular" "hybapr" "swars2"

vft <- filter(vft, sp %in% some_sp)
vft
#> # A tibble: 467 x 33
#>      DBHID PlotName PlotID Family    Genus SpeciesName Mnemonic Subspecies
#>      <int> <chr>     <int> <chr>     <chr> <chr>       <chr>    <chr>     
#>  1 1621522 bci           1 Violaceae Hyba… prunifolius hybapr   <NA>      
#>  2 1619521 bci           1 Violaceae Hyba… prunifolius hybapr   <NA>      
#>  3 1006845 bci           1 Fabaceae… Swar… simplex     swars2   ochnacea  
#>  4 1003843 bci           1 Fabaceae… Swar… simplex     swars2   ochnacea  
#>  5 1542121 bci           1 Violaceae Hyba… prunifolius hybapr   <NA>      
#>  6 1539889 bci           1 Violaceae Hyba… prunifolius hybapr   <NA>      
#>  7 2017665 bci           1 Violaceae Hyba… prunifolius hybapr   <NA>      
#>  8 2019766 bci           1 Violaceae Hyba… prunifolius hybapr   <NA>      
#>  9 1002106 bci           1 Violaceae Hyba… prunifolius hybapr   <NA>      
#> 10  998978 bci           1 Violaceae Hyba… prunifolius hybapr   <NA>      
#> # ... with 457 more rows, and 25 more variables: SpeciesID <int>,
#> #   SubspeciesID <int>, QuadratName <chr>, QuadratID <int>, PX <dbl>,
#> #   PY <dbl>, QX <dbl>, QY <dbl>, TreeID <int>, Tag <chr>, StemID <int>,
#> #   StemNumber <int>, StemTag <int>, PrimaryStem <chr>, CensusID <int>,
#> #   PlotCensusNumber <int>, DBH <int>, HOM <dbl>, ExactDate <date>,
#> #   Date <int>, ListOfTSM <chr>, HighHOM <int>, LargeStem <chr>,
#> #   Status <chr>, sp <chr>

Map with fgeo.map

The functions expect census tables (tree and stem) but we can adapt our ViewFullTable accordingly:

vft <- rename(vft, gx = PX, gy = PY)
select(vft, matches("sp"))
#> # A tibble: 467 x 5
#>    SpeciesName Subspecies SpeciesID SubspeciesID sp    
#>    <chr>       <chr>          <int>        <int> <chr> 
#>  1 prunifolius <NA>             494           NA hybapr
#>  2 prunifolius <NA>             494           NA hybapr
#>  3 simplex     ochnacea         980            8 swars2
#>  4 simplex     ochnacea         980            8 swars2
#>  5 prunifolius <NA>             494           NA hybapr
#>  6 prunifolius <NA>             494           NA hybapr
#>  7 prunifolius <NA>             494           NA hybapr
#>  8 prunifolius <NA>             494           NA hybapr
#>  9 prunifolius <NA>             494           NA hybapr
#> 10 prunifolius <NA>             494           NA hybapr
#> # ... with 457 more rows
vft %>% 
  map_gx_gy() %>% 
  limit_gx_gy(xlim = c(0, 1000), ylim = c(0, 500)) %>% 
  add_sp() %>% 
  wrap("sp", scales = "fixed")

fgeo.map wraps ggplot2 to provide some handy shortcuts for common actions. But it is wise to learn ggplot2 because with it you will be able to do a lot more.

Map with ggplot2

ggplot(vft, aes(gx, gy)) +
  coord_fixed(xlim = c(0, 1000), ylim = c(0, 500)) +
  geom_point(aes(color = sp)) +
  facet_wrap("sp", scales = "fixed")