fgeo.analyze provides functions to analyze ForestGEO data.

Installation

Install the latest stable version of fgeo.analyze from CRAN with:

install.packages("fgeo.analyze", repos = these_repos)

Install the development version of fgeo.analyze with:

Or install all fgeo packages in one step.

Example

Abundance

Your data may have multiple stems per treeid and even multiple measures per stemid (if trees have buttresses).

Fundamentally, abundance() counts rows. All of these results are the same:

But that result is likely not what you expect. Instead, you likely expect this:

As shown above, you can get a correct result by combining summarize() and n_distinct() (from the dplyr package). But abundance() includes some useful additional features (see ?abundance()). This code conveys your intention more clearly, i.e. to calculate tree abundance by counting the number of main stems:

If you have data from multiple censuses, then you can compute by census (or any other group).

Often you will need to first subset data (e.g. by status or DBH) and then count.

Basal area

If trees have buttresses, then you may need to pick the main stemid of each stem so you do not count the same stem more than once.

basal_area() also allows you to compute by groups.

But if you want to compute on a subset of data, then you need to pick the data first.

Abundance and basal area aggregated by year

Example data.

vft <- tibble(
  PlotName = c("luq", "luq", "luq", "luq", "luq", "luq", "luq", "luq"),
  CensusID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L),
  TreeID = c(1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L),
  StemID = c(1.1, 1.2, 2.1, 2.2, 1.1, 1.2, 2.1, 2.2),
  Status = c("alive", "dead", "alive", "alive", "alive", "gone",
    "dead", "dead"),
  DBH = c(10L, NA, 20L, 30L, 20L, NA, NA, NA),
  Genus = c("Gn", "Gn", "Gn", "Gn", "Gn", "Gn", "Gn", "Gn"),
  SpeciesName = c("spp", "spp", "spp", "spp", "spp", "spp", "spp", "spp"),
  ExactDate = c("2001-01-01", "2001-01-01", "2001-01-01", "2001-01-01",
    "2002-01-01", "2002-01-01", "2002-01-01",
    "2002-01-01"),
  PlotCensusNumber = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L),
  Family = c("f", "f", "f", "f", "f", "f", "f", "f"),
  Tag = c(1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L),
  HOM = c(130L, 130L, 130L, 130L, 130L, 130L, 130L, 130L)
)

vft
#> # A tibble: 8 x 13
#>   PlotName CensusID TreeID StemID Status   DBH Genus SpeciesName ExactDate
#>   <chr>       <int>  <int>  <dbl> <chr>  <int> <chr> <chr>       <chr>    
#> 1 luq             1      1    1.1 alive     10 Gn    spp         2001-01-…
#> 2 luq             1      1    1.2 dead      NA Gn    spp         2001-01-…
#> 3 luq             1      2    2.1 alive     20 Gn    spp         2001-01-…
#> 4 luq             1      2    2.2 alive     30 Gn    spp         2001-01-…
#> 5 luq             2      1    1.1 alive     20 Gn    spp         2002-01-…
#> 6 luq             2      1    1.2 gone      NA Gn    spp         2002-01-…
#> 7 luq             2      2    2.1 dead      NA Gn    spp         2002-01-…
#> 8 luq             2      2    2.2 dead      NA Gn    spp         2002-01-…
#> # … with 4 more variables: PlotCensusNumber <int>, Family <chr>,
#> #   Tag <int>, HOM <int>

Abundance by year.

Basal area by year.

Demography

Demography functions output a list that you can convert to a more convenient dataframe with as_tibble().

Except if you use split2: This argument creates a complex data structure that as_tibble() cannot handle.

Instead, pass the multiple grouping variables to split via interaction(). This approach allows you to use any number of grouping variables and the output always works with as_tibble().

The same applies for other demography functions.

A simple way to separate the grouping variables is with tidyr::separate().

Species-habitat associations

# Pick alive trees, of 10 mm or more
tree <- download_data("luquillo_tree5_random")
census <- filter(tree, status == "A", dbh >= 10)
# Pick sufficiently abundant species
pick <- filter(add_count(census, sp), n > 50)

# Use your habitat data or create it from elevation data
elevation <- download_data("luquillo_elevation")
habitat <- fgeo_habitat(elevation, gridsize = 20, n = 4)

tt_test_result <- tt_test(pick, habitat)
#> Using `plotdim = c(320, 500)`. To change this value see `?tt_test()`.
#> Using `gridsize = 20`. To change this value see `?tt_test()`.
#> Warning: Is `census` a tree table (not a stem table)? See `?tt_test()`.

# A list or matrices
tt_test_result
#> [[1]]
#>        N.Hab.1 Gr.Hab.1 Ls.Hab.1 Eq.Hab.1 Rep.Agg.Neut.1 Obs.Quantile.1
#> CASARB      35     1313      282        5              0       0.820625
#>        N.Hab.2 Gr.Hab.2 Ls.Hab.2 Eq.Hab.2 Rep.Agg.Neut.2 Obs.Quantile.2
#> CASARB      24      394     1204        2              0        0.24625
#>        N.Hab.3 Gr.Hab.3 Ls.Hab.3 Eq.Hab.3 Rep.Agg.Neut.3 Obs.Quantile.3
#> CASARB      11      482     1114        4              0        0.30125
#>        N.Hab.4 Gr.Hab.4 Ls.Hab.4 Eq.Hab.4 Rep.Agg.Neut.4 Obs.Quantile.4
#> CASARB       8     1217      377        6              0       0.760625
#> 
#> [[2]]
#>        N.Hab.1 Gr.Hab.1 Ls.Hab.1 Eq.Hab.1 Rep.Agg.Neut.1 Obs.Quantile.1
#> PREMON      94     1005      594        1              0       0.628125
#>        N.Hab.2 Gr.Hab.2 Ls.Hab.2 Eq.Hab.2 Rep.Agg.Neut.2 Obs.Quantile.2
#> PREMON      97     1478      120        2              0        0.92375
#>        N.Hab.3 Gr.Hab.3 Ls.Hab.3 Eq.Hab.3 Rep.Agg.Neut.3 Obs.Quantile.3
#> PREMON      39      230     1367        3              0        0.14375
#>        N.Hab.4 Gr.Hab.4 Ls.Hab.4 Eq.Hab.4 Rep.Agg.Neut.4 Obs.Quantile.4
#> PREMON      15      130     1465        5              0        0.08125
#> 
#> [[3]]
#>        N.Hab.1 Gr.Hab.1 Ls.Hab.1 Eq.Hab.1 Rep.Agg.Neut.1 Obs.Quantile.1
#> SLOBER      21      270     1328        2              0        0.16875
#>        N.Hab.2 Gr.Hab.2 Ls.Hab.2 Eq.Hab.2 Rep.Agg.Neut.2 Obs.Quantile.2
#> SLOBER      25      516     1082        2              0         0.3225
#>        N.Hab.3 Gr.Hab.3 Ls.Hab.3 Eq.Hab.3 Rep.Agg.Neut.3 Obs.Quantile.3
#> SLOBER      21     1336      260        4              0          0.835
#>        N.Hab.4 Gr.Hab.4 Ls.Hab.4 Eq.Hab.4 Rep.Agg.Neut.4 Obs.Quantile.4
#> SLOBER       8     1193      396       11              0       0.745625

# A dataframe
as_tibble(tt_test_result)
#> # A tibble: 12 x 8
#>    habitat sp     N.Hab Gr.Hab Ls.Hab Eq.Hab Rep.Agg.Neut Obs.Quantile
#>  * <chr>   <chr>  <dbl>  <dbl>  <dbl>  <dbl>        <dbl>        <dbl>
#>  1 1       CASARB    35   1313    282      5            0       0.821 
#>  2 2       CASARB    24    394   1204      2            0       0.246 
#>  3 3       CASARB    11    482   1114      4            0       0.301 
#>  4 4       CASARB     8   1217    377      6            0       0.761 
#>  5 1       PREMON    94   1005    594      1            0       0.628 
#>  6 2       PREMON    97   1478    120      2            0       0.924 
#>  7 3       PREMON    39    230   1367      3            0       0.144 
#>  8 4       PREMON    15    130   1465      5            0       0.0812
#>  9 1       SLOBER    21    270   1328      2            0       0.169 
#> 10 2       SLOBER    25    516   1082      2            0       0.322 
#> 11 3       SLOBER    21   1336    260      4            0       0.835 
#> 12 4       SLOBER     8   1193    396     11            0       0.746

# A simple summary to help you interpret the results
summary(tt_test_result)
#> # A tibble: 12 x 3
#>    sp     habitat association
#>    <chr>  <chr>   <chr>      
#>  1 CASARB 1       neutral    
#>  2 CASARB 2       neutral    
#>  3 CASARB 3       neutral    
#>  4 CASARB 4       neutral    
#>  5 PREMON 1       neutral    
#>  6 PREMON 2       neutral    
#>  7 PREMON 3       neutral    
#>  8 PREMON 4       neutral    
#>  9 SLOBER 1       neutral    
#> 10 SLOBER 2       neutral    
#> 11 SLOBER 3       neutral    
#> 12 SLOBER 4       neutral

Get started with fgeo