Giter Site home page Giter Site logo

rudeboybert / forestecology Goto Github PK

View Code? Open in Web Editor NEW
11.0 4.0 2.0 82.62 MB

forestecology R package of Methods and Data for Forest Ecology Model Fitting and Assessment

Home Page: https://rudeboybert.github.io/forestecology/

License: Other

R 43.78% TeX 56.22%
forestecology tidyverse

forestecology's Introduction

forestecology

DOI Build Status Codecov test coverage CRAN status

Installation

You can install the released version of forestecology from CRAN with:

install.packages("forestecology")

And the development version from GitHub with:

# install.packages("remotes")
remotes::install_github("rudeboybert/forestecology")

This package is designed to work for spatially mapped, repeat censused forests plots. The package has commands to fit models of tree growth based on neighborhood competition which can be used to estimate species-specific competition coefficients. The model fits can then be evaluated using a spatial cross-validation scheme to detect possible overfitting. Additionally, these models can test whether the species identity of competitors matters using a permutation test-style shuffling of competitor identity (under the null hypothesis) and subsequently evaluating if model performance changes.

See Kim et al. (2021) The forestecology R package for fitting and assessing neighborhood models of the effect of interspecific competition on the growth of trees for a full description; the source code for this paper can be found in the paper/ folder.

Example analysis

We present an example analysis using toy data pre-loaded into the package where we will:

  1. Compute growth of trees based on census data
  2. Add spatial information
  3. Identify all focal and corresponding competitor trees
  4. Fit model and make predictions
  5. Run spatial cross-validation
library(tidyverse)
library(forestecology)
library(patchwork)
library(blockCV)

# Resolve conflicting functions
filter <- dplyr::filter

Compute growth of trees based on census data

The starting point of our analysis are data from two repeat censuses census_1_ex and census_2_ex. For example, consider the forest census data in census_1_ex.

census_1_ex
#> # A tibble: 10 × 7
#>       ID sp                gx    gy date       codes   dbh
#>    <int> <chr>          <dbl> <dbl> <date>     <chr> <dbl>
#>  1     1 sugar maple     0.75  2.5  2015-06-01 M         5
#>  2     2 American beech  1.5   2.5  2015-06-01 M        20
#>  3     3 sugar maple     1.75  2.25 2015-06-01 M        15
#>  4     4 American beech  3     1.5  2015-06-01 M        12
#>  5     5 sugar maple     3.25  1.75 2015-06-01 M        35
#>  6     6 American beech  5.5   4.5  2015-06-01 M         6
#>  7     7 sugar maple     8     1.5  2015-06-01 M        22
#>  8     8 American beech  8.5   0.75 2015-06-01 M        14
#>  9     9 sugar maple     8.75  1.5  2015-06-01 M        42
#> 10    10 American beech  8.75  1.75 2015-06-01 M         4

We convert the census_1_ex data frame to an object of type sf and then plot using geom_sf().

ggplot() +
  geom_sf(
    data = census_1_ex %>% sf::st_as_sf(coords = c("gx", "gy")),
    aes(col = sp, size = dbh)
  )

We first combine data from two repeat censuses into a single growth data frame that has the average annual growth of all trees alive at both censuses that aren’t resprouts at the second census per Allen and Kim (2020).

growth_ex <-
  compute_growth(
    census_1 = census_1_ex %>% 
      mutate(sp = to_any_case(sp)),
    census_2 = census_2_ex %>% 
      filter(!str_detect(codes, "R")) %>% 
      mutate(sp = to_any_case(sp)),
    id = "ID"
  ) %>% 
  # Compute basal area:
  mutate(basal_area = 0.0001 * pi * (dbh1 / 2)^2)

Add spatial information

Our growth model assumes that two individual trees compete if they are less than a pre-specified distance comp_dist apart. Furthermore, we define a buffer region of size comp_dist from the boundary of the study region.

# Set competitor distance
comp_dist <- 1

# Add buffer variable to growth data frame
growth_ex <- growth_ex %>%
  add_buffer_variable(size = comp_dist, region = study_region_ex)

# Optional: Create sf representation of buffer region
buffer_region <- study_region_ex %>% 
  compute_buffer_region(size = comp_dist)

In the visualization below, the solid line represents the boundary of the study region while the dashed line delimits the buffer region within. All trees outside this buffer region (in red) will be our “focal” trees of interest in our model since we have complete competitor information on all of them. All trees inside this buffer region (in blue) will only be considered as “competitor” trees to “focal” trees.

base_plot <- ggplot() +
  geom_sf(data = study_region_ex, fill = "transparent") +
  geom_sf(data = buffer_region, fill = "transparent", linetype = "dashed")

base_plot + 
  geom_sf(data = growth_ex, aes(col = buffer), size = 2)

Next we add information pertaining to our spatial cross-validation scheme. We first manually define the spatial blocks that will act as our cross-validation folds and convert them to an sf object using the sf_polygon() function from the sfheaders package.

fold1 <- rbind(c(0, 0), c(5, 0), c(5, 5), c(0, 5), c(0, 0))
fold2 <- rbind(c(5, 0), c(10, 0), c(10, 5), c(5, 5), c(5, 0))

blocks_ex <- bind_rows(
  sf_polygon(fold1),
  sf_polygon(fold2)
) %>%
  mutate(folds = c(1, 2) %>% factor())

Next we assign each tree to the correct folds using the foldID variable of the output returned by the spatialBlock() function from the blockCV package.

SpatialBlock_ex <- blockCV::spatialBlock(
  speciesData = growth_ex, k = 2, selection = "systematic", blocks = blocks_ex,
  showBlocks = FALSE, verbose = FALSE
)

growth_ex <- growth_ex %>%
  mutate(foldID = SpatialBlock_ex$foldID %>% factor())

In the visualization below, the spatial blocks that act as our cross-validation folds are delineated in orange. The shape of each point indicates which fold each tree has been assigned to.

base_plot + 
  geom_sf(data = growth_ex, aes(col = buffer, shape = foldID), size = 2) +
  geom_sf(data = blocks_ex, fill = "transparent", col = "orange")

Compute focal versus competitor tree information

Based on our growth data frame, we now explicitly define all “focal” trees and their respective “competitor” trees in a focal_vs_comp data frame. This data frame has rows corresponding to each focal tree, and all information about its competitors are saved in the list-column variable comp. We implemented this nested format using nest() in order to minimize redundancy, given that the same tree can act as a competitor multiple times.

focal_vs_comp_ex <- growth_ex %>%
  create_focal_vs_comp(comp_dist, blocks = blocks_ex, id = "ID", comp_x_var = "basal_area")
focal_vs_comp_ex
#> # A tibble: 6 × 7
#>   focal_ID focal_sp         dbh foldID    geometry growth comp            
#>      <dbl> <fct>          <dbl> <fct>      <POINT>  <dbl> <list>          
#> 1        2 american_beech    20 1        (1.5 2.5)  0.800 <tibble [2 × 4]>
#> 2        3 sugar_maple       15 1      (1.75 2.25)  1.00  <tibble [1 × 4]>
#> 3        4 american_beech    12 1          (3 1.5)  0.400 <tibble [1 × 4]>
#> 4        5 sugar_maple       35 1      (3.25 1.75)  1.40  <tibble [1 × 4]>
#> 5        7 sugar_maple       22 2          (8 1.5)  0.600 <tibble [3 × 4]>
#> 6        9 sugar_maple       42 2       (8.75 1.5)  1.40  <tibble [3 × 4]>

Using unnest() we can fully expand the competitor information saved in the focal_vs_comp data frame. For example, the tree with focal_ID equal to 2 located at (1.5, 2.5) has two competitors within comp_dist distance from it.

focal_vs_comp_ex %>% 
  unnest(cols = "comp")
#> # A tibble: 11 × 10
#>    focal_ID focal_sp         dbh foldID    geometry growth comp_ID  dist
#>       <dbl> <fct>          <dbl> <fct>      <POINT>  <dbl>   <dbl> <dbl>
#>  1        2 american_beech    20 1        (1.5 2.5)  0.800       1 0.75 
#>  2        2 american_beech    20 1        (1.5 2.5)  0.800       3 0.354
#>  3        3 sugar_maple       15 1      (1.75 2.25)  1.00        2 0.354
#>  4        4 american_beech    12 1          (3 1.5)  0.400       5 0.354
#>  5        5 sugar_maple       35 1      (3.25 1.75)  1.40        4 0.354
#>  6        7 sugar_maple       22 2          (8 1.5)  0.600       8 0.901
#>  7        7 sugar_maple       22 2          (8 1.5)  0.600       9 0.75 
#>  8        7 sugar_maple       22 2          (8 1.5)  0.600      10 0.791
#>  9        9 sugar_maple       42 2       (8.75 1.5)  1.40        7 0.75 
#> 10        9 sugar_maple       42 2       (8.75 1.5)  1.40        8 0.791
#> 11        9 sugar_maple       42 2       (8.75 1.5)  1.40       10 0.25 
#> # … with 2 more variables: comp_sp <fct>, comp_x_var <dbl>

Fit model and make predictions

We then fit our competitor growth model as specified in Allen and Kim (2020).

comp_bayes_lm_ex <- focal_vs_comp_ex %>%
  comp_bayes_lm(prior_param = NULL)

The resulting output is an comp_bayes_lm object containing the posterior distribution of all linear regression parameters, the intercept, the slope for dbh for each species, and a matrix of all species pairs competitive effects on growth. The S3 object class is associated with several methods.

# Print
comp_bayes_lm_ex
#> Bayesian linear regression model parameters with a multivariate Normal
#> likelihood. See ?comp_bayes_lm for details:
#> 
#>   parameter_type           prior posterior
#> 1 Inverse-Gamma on sigma^2 a_0   a_star   
#> 2 Inverse-Gamma on sigma^2 b_0   b_star   
#> 3 Multivariate t on beta   mu_0  mu_star  
#> 4 Multivariate t on beta   V_0   V_star   
#> 
#> Model formula:
#> growth ~ sp + dbh + dbh * sp + american_beech * sp + sugar_maple * sp

# Posterior distributions (plots combined with patchwork pkg)
p1 <- autoplot(comp_bayes_lm_ex, type = "intercepts")
p2 <- autoplot(comp_bayes_lm_ex, type = "dbh_slopes")
p3 <- autoplot(comp_bayes_lm_ex, type = "competition")
(p1 | p2) / p3

Furthermore, we can apply a predict() method to the resulting comp_bayes_lm object to obtain fitted/predicted values of this model. We append these growth_hat values to our focal_vs_comp data frame.

focal_vs_comp_ex <- focal_vs_comp_ex %>%
  mutate(growth_hat = predict(comp_bayes_lm_ex, newdata = focal_vs_comp_ex))
focal_vs_comp_ex
#> # A tibble: 6 × 8
#>   focal_ID focal_sp         dbh foldID    geometry growth comp            
#>      <dbl> <fct>          <dbl> <fct>      <POINT>  <dbl> <list>          
#> 1        2 american_beech    20 1        (1.5 2.5)  0.800 <tibble [2 × 4]>
#> 2        3 sugar_maple       15 1      (1.75 2.25)  1.00  <tibble [1 × 4]>
#> 3        4 american_beech    12 1          (3 1.5)  0.400 <tibble [1 × 4]>
#> 4        5 sugar_maple       35 1      (3.25 1.75)  1.40  <tibble [1 × 4]>
#> 5        7 sugar_maple       22 2          (8 1.5)  0.600 <tibble [3 × 4]>
#> 6        9 sugar_maple       42 2       (8.75 1.5)  1.40  <tibble [3 × 4]>
#> # … with 1 more variable: growth_hat <dbl>

We then compute the root mean squared error (RMSE) of the observed versus fitted growths as a measure of our model’s fit.

focal_vs_comp_ex %>%
  rmse(truth = growth, estimate = growth_hat) %>%
  pull(.estimate)
#> [1] 0.1900981

Run spatial cross-validation

Whereas in our example above we fit our model to the entirety of the data and then generate fitted/predicted growths on this same data, we now apply the same model with spatial cross-validation. All the trees in a given fold will be given a turn as the “test” data while the trees in all remaining folds will be the “training” data. We then fit the model to the training data, but compute fitted/predicted growths for the separate and independent data.

focal_vs_comp_ex <- focal_vs_comp_ex %>%
  run_cv(comp_dist = comp_dist, blocks = blocks_ex)

Note the increase in RMSE, reflecting the fact that our original estimate of model error was overly optimistic as it did not account for spatial autocorrelation.

focal_vs_comp_ex %>%
  rmse(truth = growth, estimate = growth_hat) %>%
  pull(.estimate)
#> [1] 0.4068709

forestecology's People

Contributors

dallenmidd avatar rudeboybert avatar simonpcouch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

forestecology's Issues

Incorporate trait-based competition into model (a la Kunstler)

Okay the idea here is to use traits of species rather than species identity themselves to model competition. This is an important idea in ecology these days, so makes sense that the reviewer wanted it. THere are different formulations of this, and I think the one from Kunstler et al. (2016) would be fairly straight forward to do.

Let Y_ik be the growth of the kth individual of species i. Let j be the species of competitors in the neighborhood. The betas are the same. C is an overall competition term, how much does growht decrease per BA of neighbors. And c_ij is a term that modifies it for this particular species pair and depends on the traits of the two species. Say we have l many traits and t_li is the value of species i for trait l. Then we can interpret a_tol,l is how trait l affects the way a species tolerates (or is sensitive too) competition. a_eff,l is how trait l is how much trait l affects how strong a competitor is, how much it effects the reduction in growht of its neighbors. Finally a_sim,l is about whether competition is stronger (or weaker) if the two species are similar. This is based on an idea that two species that are similar use the same resources and shoudl compete more.

Screen Shot 2021-04-30 at 10 39 55 AM

This seems pretty straightforward to implement?? And I think we even have trait values for SCBI species for two or three traits if we actually wanted to do this.

Making the package work with other types of forest inventories

Not all forest ecology research happens in large rectangular forest plots. In fact most of it doesn't and the approach of ForestGEO is fairly unique. The more common approach would be to have many small plots randomly or regularly spread out in an area. The most clear example of this is the US Forest Service's Forest Inventory plots. Data from these plots are publicly available as part of the USFS Forest Inventory and Analysis database (FIA). This is a HUGE dataset on the order of 10,000 plots across the US. Not every one is censused every year, they are on a rotation (seven yr?). But point is this is lots of stems which are measured on a regular basis. For these our competition model would work just fine, but it wouldn't work with our current spatial set up (buffer, folds, finding competitors,...).

Here is the layout of FIA plots:
FIA_layout
A plot has 4 subplots, each 24ft radius. In those subplots all stems >5 inches DBH are mapped. The 4 microplots, each 6.8ft radius, have all trees >1in DBH are mapped. Trees in either of those plots could be the focal trees. The plots themselves are then all scattered around in forests through the US (for example VT has ~900 of these plots). Figure from FIA documentation (which is HUNDREDS of pages because there is tons of stuff in it).

To my mind what would have to happen is the buffers would need to change, they would be a ring inside the circle so we get all the competitors. And then the folds would have to change. Each plot (with four subplots) would be in its own fold. All plots should be far enough away that they can be in different folds.

Making the package work with FIA data would really open up the number of users. But would be some real work to rework the spatial functions. Or maybe just have another set of spatial functions for FIA data (or data sets with distributed, not-contiguous plots).

SCBI readme

Re-write SCBI section of the readme with our new package functions, in the SCBI branch.

Dave TODO's

  • Investigate open access journal publishing funds
  • Brief literature review on species competition models that assume less coarse null hypothesis than we are

Extending to more models

Feedback of

  • Whether our package can handle models where outcome variable is (binary) mortality)
  • We can have less coarse null models for species competition (see #70)

all fall under umbrella feedback that model only works on single model. Accordingly:

  • See if there are any quick fixes to above specific points
  • Reframe discussion section in manuscript to lay a pathway for extending package to more models

Add datasets in SCBI branch pkg_todo.R to package

  1. Do we need to delete previous existing data?
  2. By editing data-raw/process_data_raw.R. In particular, add
    • bw_2008
    • bw_2014
    • bw_species
  3. Documenting via roxygen2 code in R/datasets.R:
    • bw_2008
    • bw_2014
    • bw_species
    • bigwoods_study_region

Move converting of data frame to sf object to compute_growth()

@dallenmidd mentioned in #15:

Little thing. This is about lines 131 and 150 of README.Rmd in the readme_edit branch. After we do compute_growth to both the BW and SCBI censuses we give the resulting df a geometry with st_as_sf(coords = c("gx", "gy")). Should this just be part of compute_growth?

Yes, you are correct. Could you make this change in the SCBI branch? Either:

  • by committing directly into SCBI, which IMO is fine since the change is rather small
  • by creating a new branch off SCBI, making the change, pull requesting, then tagging me for review?

We'll then update the readme-edit branch with all our changes in one shot later this PM.

Find max_dist function?

Any way we could write a function which would find the best value for max_dist? The user would have to specify a given model and then then a range of possible values for max_dist (e.g., 5 m to 20m). Then the function would test each one and find the one with the lowest RMSE? Would be cool because then we would know what is teh distance at which competition is felt. Of biological interest.

Not 100% necessary, but would be a cool function to include in the package if possible.

Note from CRAN

Dear maintainer,

You have file 'forestecology/man/forestecology.Rd' with
\docType{package}, likely intended as a package overview help file, but
without the appropriate PKGNAME-package \alias as per "Documenting
packages" in R-exts.

This seems to be the consequence of the breaking change

Using @doctype package no longer automatically adds a -package alias.
Instead document _PACKAGE to get all the defaults for package
documentation.

in roxygen2 7.0.0 (2019-11-12) having gone unnoticed, see
r-lib/roxygen2#1491.

As explained in the issue, to get the desired PKGNAME-package \alias
back, you should either change to the new approach and document the new
special sentinel

"_PACKAGE"

or manually add

@Aliases forestecology-package

if remaining with the old approach.

Please fix in your master sources as appropriate, and submit a fixed
version of your package within the next few months.

Error when running 'comp_bayes_lm' function

I am currently working on a study in which we want to model individual tree growth based on the local neighbourhood in a tree diversity experiment called FORBIO (https://treedivbelgium.ugent.be/pl_forbio.html).

I succeeded in constructing a datafile that looks identical to the “focal_vs_comp_ex” datafile from the package. However, when I try to run the ‘comp_bayes_lm’ function, I get an error.

Do you have any idea on how I could solve this issue? Is there still an issue in the architecture of my data frame?

Below a sample of my data (.rds in a zip file), the code I used and the error I received

Data:
sample_data.zip

Code:
comp_bayes_lm <- sample_data %>%
comp_bayes_lm(prior_param = NULL, run_shuffle = FALSE)

Error:
Error in summarise():
i In argument: geometry = .Primitive("sum")(geometry).
i In group 1: focal_ID = 1, comp_sp = "Acer".
Caused by error:
! invalid 'type' (list) of argument
Run rlang::last_trace() to see where the error occurred.

Thanks a lot!

Reviews

  • Bert investigates does 1 in #84
  • Dave does 2 in #81
  • Dave Bert does 3 in #84
  • Bert does 4 in #82

(1) In Allen & Kim (2020) we demonstrate how the package can be used to test whether taxonomic or trait-based groupings better explain competition. With clever application the package can be used in many different ways, even within the current structure of the model presented in Allen & Kim (2020).

So, the package already has an example in Allen and Kim. Perhaps you need to revisit this application or better yet, implement the suggestion embedded in the current MS: Thus an extension of the model would allow λ values from Equation 1 to be a function of the traits of competing species.

(2) The reviewer is correct that our model takes as an input the competitive distance. But it would be easier to iteratively run our model for a range of competitive distances, compute the RMSE estimate of out-of-sample model error for each distance, then perform basic model selection by opting for the model with the lowest RMSE value.

This seems a really straightforward example to code up. Even if it's just two distances and a comparison. Please do this.

(3) In Allen & Kim (2020) we show how our current structure can be used to test whether trait-based groups better explain competition than taxonomic groupings (e.g., species). So again with clever application of our package different theories of competition can be tested.

Is there an easy additional example of 'clever application' you can nudge readers along to understand? I'd like to see one implemented.

Ultimately, we would appreciate you making an effort to showcase the package with respect to how it allows fundamental questions to be addressed and hypotheses generated. Judicious use of GitHub/Zenodo based code and appendices can make for an efficient expansion of the examples.

(4) The sf simple features package is a relatively new package whose features allowed us to code our spatial cross-validation algorithm in an comprehensible and legible fashion. This would’ve been much harder to achieve using previously popular R packages for geospatial data, such as the sp package. This package would make neighborhood competition models accessible to a larger group of ecologists.

I am not sure you've got this detail in the work. It's certainly worth having it in and perhaps even associating the explanation more strongly with the structure and type of information that can be leveraged for all the 'clever extensions' of the package.

couple little things

  • Progress bar for create_focal_vs_comp it takes a little while
  • Rename fit_bayesain_model to fit_comp_model? Is the importance of it that it is a model of competition or that it is bayesian? To me emphasizing competition seems more important, but I am not sure.
  • Same as above for predict_bayesain_model.

Problem with little or absent competition

The problem I'm facing is due to the fact that it seems that no - or very little - competition is happening within my sample plot. The bayesian model fits the data, but it does not show a "prevailing" species or individual even though DBH values are quite different: the largest individual has an 80 mm DBH, while the smallest one has a 24 mm DBH.

Also, a point that needs to be clarified: it seems that the model describe a kind of competition "within the individual itself". For instance, first column, first row, or second column, second row, and so on. The individual has a competition effect on itself?

image

image (1)

Make small example

Make a minimal example (2 folds, 2 species) to give as an example for the whole workflow.

small lambda plot issue

The example describing how to read the columns v rows in the lambda plot is not working on the small example data set for some reason.
README-unnamed-chunk-9-1

Got rid of get_model_specs?

Hey Bert, I am back to working on taking the code from pkg_todo.R and putting it into the README.Rmd. I am looking at pkg_todo.R in the SCBI branch. I skipped over the blockCV stuff and got to lines 119-124 where you set the model formula. I thought that before we did this with the command get_model_specs so the user didn't have to get as down and dirty with all that. Just checking if you wanted to get rid of that function or maybe I am misunderstanding what you are doing in those line.

SCBI readme

Re-write SCBI section of the readme with our new package functions, in the SCBI branch.

Option for additional predictor variables

R2 said: "It also lacks functionality to accommodate multiple census periods or variability between sites or a clear way to use the results to simulate forest stand dynamics over space and time. "

The last issue is ridiculous because then the model would need to have full demography (mortality, seed dispersal, and recruitment) which is way out of the scope of the intention). But the first two issues could be addressed if we gave the option of additional predictor variables on growth. They could be categorical or continuous. For example I think SCBI has a deer exclosure, there could be a categorical predictor for is the stem in the exclosure or not. For continuous it could be the elevation the stem is at or an estimate of the soil N where the stem is. For multiple censuses each transition (census 1 to 2 and then 2 to 3) for each stem could be modeled and census interval (1 to 2 or 2 to 3) could be the categorical predictor.

HEre is how it might work. Say individual k is in category l then your model would be:
Screen Shot 2021-04-30 at 1 48 08 PM
Where c_l is the effect on growth of stems in category l

Or if the predictor was continuous and takes value c_k at individual k, then:
Screen Shot 2021-04-30 at 1 49 59 PM
Where a_c is the effect of that continuous predictor on growth.

Additional features for large, rectangular plots (i.e., ForestGEO-style plots)

I think there are a set of use cases that a ForestGEO plot researcher might like. They would play really nice with all our current spatial structure stuff, but might take tweaking for how the competition model is structured:

  • Effect of competition on stem mortality: Here the idea is that we consider focal trees as all trees that were in the first census and then instead of the response being growth the response is did the tree die or not. My understanding is this will make things tricky because the response variable is binomial rather than normal. Not sure how this plays out with our current Bayesian framework where we rely on an analytical solution to get the posteriors. But this would be really nice for a ForestGEO user. Do trees with lots of competitors die more often? Does it depend on the species of the competitor?
  • Effect of competition on seedling growth or mortality: With many ForestGEO plots there are seedling subplots. In some regular grid throughout the plot there are 1 m by 1 m plots where seedlings are tagged and them measured (either height or diameter at 10 cm). Seedling dynamics are much faster than adult stem dynamics, so just one year later you can go back and see seedlings growth or mortality. Many ForestGEO plots with only one census (so can't use the package now because they don't have stem growth) will have multiple censuses of seedlings. The issue here is there is a really clear difference between focal individuals (seedlings in their regular grid for which there are two censuses) and the competitors (>1 cm DBH stems completed censused for which there is only a single census). If there were some way to do our current competition model, but where the response is growth of seedlings, I think that would be something lots of users might be interested in.

Conspecific versus heterospecific competition

To address the reviewer's critique that the model is not flexible enough and does not include applications of existing competition theory, we could add another option for run_shuffle. In this case the shuffle would not shuffle identity of competitors which share with the focal species. The idea being there is a special kind of competition with conspecifics (because they share your exact resource needs). The result is two lambda values, one for competition between conspecifics and one for competition between heterospecifics.

Lambda plotting function problem

I really like the way you have that sentence at the top of the plot "Ex: Top row, second column = competitive effect of __ on __" but looks like it doesn't "play nice" with sp_to_plot.
README-unnamed-chunk-30-1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.