diff --git a/.Rbuildignore b/.Rbuildignore index f2dea5f..64ca8c9 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1 +1,3 @@ ^data-raw$ +^doc$ +^Meta$ diff --git a/.github/workflows/check-standard.yaml b/.github/workflows/check-os.yaml similarity index 75% rename from .github/workflows/check-standard.yaml rename to .github/workflows/check-os.yaml index 29e8860..c5078ab 100644 --- a/.github/workflows/check-standard.yaml +++ b/.github/workflows/check-os.yaml @@ -1,13 +1,13 @@ +# Check OS and R releases on: push: branches: [main, master] pull_request: branches: [main, master] -name: R-CMD-check +name: R-CMD-check-OS-R env: - R_LIBS_USER: /usr/local/lib/R/site-library NCPUS: 2 jobs: @@ -52,19 +52,19 @@ jobs: writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") shell: Rscript {0} - - name: Cache R packages - if: runner.os != 'Windows' - uses: actions/cache@v2 - with: - path: ${{ env.R_LIBS_USER }} - key: ${{ runner.os }}-rversion-${{ matrix.config.r }}-${{ hashFiles('.github/depends.Rds') }} - restore-keys: ${{ runner.os }}-r-${{ matrix.config.r }}- - - uses: r-lib/actions/setup-r-dependencies@v2 with: extra-packages: any::rcmdcheck needs: check - - - uses: r-lib/actions/check-r-package@v2 + + # rcmdcheck but do not build vignettes + - name: Build Check Across OS & R Releases + run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--no-build-vignettes"), build_args = c("--no-manual", "--no-build-vignettes"), error_on = "error") + shell: Rscript {0} + + - name: Upload check results + if: failure() + uses: actions/upload-artifact@v2 with: - upload-snapshots: true \ No newline at end of file + name: ${{ runner.os }}-r${{ matrix.config.r }}-results + path: check \ No newline at end of file diff --git a/.github/workflows/check-release.yaml b/.github/workflows/check-r-release.yaml similarity index 60% rename from .github/workflows/check-release.yaml rename to .github/workflows/check-r-release.yaml index 6c3ebfd..6162aa6 100644 --- a/.github/workflows/check-release.yaml +++ b/.github/workflows/check-r-release.yaml @@ -1,16 +1,16 @@ +# CI to test package on different versions of R, rel-1, rel, rel+1 on: push: branches: [main, master] pull_request: branches: [main, master] -name: R-CMD-check +name: R-CMD-check-R-release env: R_LIBS_USER: /usr/local/lib/R/site-library LC_ALL: en_US.UTF-8 NCPUS: 2 - CI: true jobs: R-CMD-check: @@ -41,6 +41,14 @@ jobs: extra-packages: any::rcmdcheck needs: check + # rcmdcheck but do not build vignettes - name: Run Fast Build Check Across R Releases - run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--ignore-vignettes", "--no-build-vignettes"), build_args = c("--no-manual", "--ignore-vignettes", "--no-build-vignettes"), error_on = "error") - shell: Rscript {0} \ No newline at end of file + run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--no-build-vignettes"), build_args = c("--no-manual", "--no-build-vignettes"), error_on = "error") + shell: Rscript {0} + + - name: Upload check results + if: failure() + uses: actions/upload-artifact@v2 + with: + name: ${{ runner.os }}-r${{ matrix.config.r }}-results + path: check \ No newline at end of file diff --git a/.github/workflows/ci-run_plsr_example.yaml b/.github/workflows/ci-run_plsr_example.yaml new file mode 100644 index 0000000..c66588f --- /dev/null +++ b/.github/workflows/ci-run_plsr_example.yaml @@ -0,0 +1,57 @@ +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +name: ci-run_PLSR_example + +env: + R_LIBS_USER: /usr/local/lib/R/site-library + LC_ALL: en_US.UTF-8 + NCPUS: 2 + +jobs: + run-plsr: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_KEEP_PKG_SOURCE: yes + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + + strategy: + fail-fast: false + matrix: + R: + - "3.6" + - "4.0" + - "4.1" + + steps: + #check out source code + - uses: actions/checkout@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + + - name: Query dependencies + run: | + install.packages('remotes') + saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) + writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") + shell: Rscript {0} + + - name: Install dependencies + run: | + Rscript -e 'remotes::install_github(repo="TESTgroup-BNL/spectratrait", dependencies=TRUE)' + + # Run R script + - name: Run Ely et al. (2019) PLSR Example + run: | + source("inst/scripts/spectra-trait_ely_leafN_plsr_bootstrap_example.R") + shell: Rscript {0} \ No newline at end of file diff --git a/.github/workflows/ci-weekly.yaml b/.github/workflows/ci-weekly.yaml index b013775..83e7c5e 100644 --- a/.github/workflows/ci-weekly.yaml +++ b/.github/workflows/ci-weekly.yaml @@ -1,4 +1,4 @@ -name: R-CMD-check weekly +name: R-CMD-check-Weekly on: # every Monday at 4:30 AM @@ -6,34 +6,25 @@ on: - cron: '30 4 * * 1' env: - R_LIBS_USER: /usr/local/lib/R/site-library - LC_ALL: en_US.UTF-8 NCPUS: 2 - CI: true jobs: R-CMD-check: runs-on: ${{ matrix.config.os }} - name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) strategy: fail-fast: false matrix: config: - - {os: macOS-latest, r: 'release'} - - - {os: windows-2022, r: 'release'} - # Use 3.6 to trigger usage of RTools35 - - {os: windows-2022, r: '3.6'} - - # Use older ubuntu to maximise backward compatibility - - {os: ubuntu-18.04, r: 'devel', http-user-agent: 'release'} - - {os: ubuntu-18.04, r: 'release'} - - {os: ubuntu-18.04, r: 'oldrel-1'} - - {os: ubuntu-18.04, r: 'oldrel-2'} - - {os: ubuntu-18.04, r: 'oldrel-3'} - - {os: ubuntu-18.04, r: 'oldrel-4'} + - {os: macOS-latest, r: 'oldrel-1'} + - {os: macOS-latest, r: 'release'} + - {os: windows-2022, r: 'oldrel-1'} + - {os: windows-2022, r: 'release'} + - {os: ubuntu-latest, r: 'oldrel-1'} + - {os: ubuntu-latest, r: 'release'} + - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} @@ -56,6 +47,14 @@ jobs: extra-packages: any::rcmdcheck needs: check - - uses: r-lib/actions/check-r-package@v2 + # rcmdcheck but do not build vignettes + - name: Build Check Across OS & R Releases + run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--no-build-vignettes"), build_args = c("--no-manual", "--no-build-vignettes"), error_on = "error") + shell: Rscript {0} + + - name: Upload check results + if: failure() + uses: actions/upload-artifact@v2 with: - upload-snapshots: true \ No newline at end of file + name: ${{ runner.os }}-r${{ matrix.config.r }}-results + path: check \ No newline at end of file diff --git a/.github/workflows/run_ecosis_pull_example.yaml b/.github/workflows/run_ecosis_pull_example.yaml new file mode 100644 index 0000000..3f1d862 --- /dev/null +++ b/.github/workflows/run_ecosis_pull_example.yaml @@ -0,0 +1,47 @@ +name: run_ecosis_pull_example + +on: + schedule: + - cron: '15 1 */5 * *' + +env: + R_LIBS_USER: /usr/local/lib/R/site-library + LC_ALL: en_US.UTF-8 + NCPUS: 2 + +jobs: + run-plsr: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_KEEP_PKG_SOURCE: yes + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + + steps: + #check out source code + - uses: actions/checkout@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + + - name: Query dependencies + run: | + install.packages('remotes') + saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) + writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") + shell: Rscript {0} + + - name: Install dependencies + run: | + Rscript -e 'remotes::install_github(repo="TESTgroup-BNL/spectratrait", dependencies=TRUE)' + + # Run R script + - name: Run EcoSIS API Pull Example + run: | + source("inst/scripts/pull_data_from_ecosis.R") + shell: Rscript {0} \ No newline at end of file diff --git a/.github/workflows/run_plsr_example_auto.yaml b/.github/workflows/run_plsr_example_auto.yaml new file mode 100644 index 0000000..3128c36 --- /dev/null +++ b/.github/workflows/run_plsr_example_auto.yaml @@ -0,0 +1,55 @@ +on: + schedule: + - cron: '0 0 */2 * *' + +name: run_PLSR_example-auto + +env: + R_LIBS_USER: /usr/local/lib/R/site-library + LC_ALL: en_US.UTF-8 + NCPUS: 2 + +jobs: + run-plsr: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_KEEP_PKG_SOURCE: yes + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + + strategy: + fail-fast: false + matrix: + R: + - "3.6" + - "4.0" + - "4.1" + + steps: + #check out source code + - uses: actions/checkout@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + + - name: Query dependencies + run: | + install.packages('remotes') + saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) + writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") + shell: Rscript {0} + + - name: Install dependencies + run: | + Rscript -e 'remotes::install_github(repo="TESTgroup-BNL/spectratrait", dependencies=TRUE)' + + # Run R script + - name: Run Ely et al. (2019) PLSR Example + run: | + source("inst/scripts/spectra-trait_ely_leafN_plsr_bootstrap_example.R") + shell: Rscript {0} diff --git a/.gitignore b/.gitignore index b08a346..9a033cc 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,5 @@ rsconnect/ # MacOSX *.DS* *._* +/doc/ +/Meta/ diff --git a/README.md b/README.md index d8f5bc0..9ed4b0a 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,9 @@ Finally, to complete the installation you will also need to install the spectrat # to install the master branch version devtools::install_github(repo = "TESTgroup-BNL/spectratrait", dependencies=TRUE) +# to install the master branch version - with Vignettes (though slower) +devtools::install_github(repo = "TESTgroup-BNL/spectratrait", dependencies=TRUE, build_vignettes = TRUE) + # to install a specific release, for example release 1.0.5 devtools::install_github(repo = "TESTgroup-BNL/spectratrait@v1.0.5", dependencies=TRUE) diff --git a/inst/docs/sserbin2019_plsr_ex9.pdf b/inst/docs/sserbin2019_plsr_ex9.pdf new file mode 100644 index 0000000..85a4a19 Binary files /dev/null and b/inst/docs/sserbin2019_plsr_ex9.pdf differ diff --git a/inst/scripts/pull_data_from_ecosis.R b/inst/scripts/pull_data_from_ecosis.R index e4da92b..85e8013 100644 --- a/inst/scripts/pull_data_from_ecosis.R +++ b/inst/scripts/pull_data_from_ecosis.R @@ -25,9 +25,7 @@ invisible(lapply(list.of.packages, library, character.only = TRUE)) #--------------------------------------------------------------------------------------------------# -### Setup other functions and options -# not in -`%notin%` <- Negate(`%in%`) +### Setup options # What is the source dataset from EcoSIS? ecosis_id <- "960dbb0c-144e-4563-8117-9e23d14f4aa9" @@ -107,10 +105,10 @@ trait_data <- sample_info %>% head(trait_data) # Prepare data for ggplot -trait_data <- melt(data = trait_data, id.vars = "USDA_Species_Code", measure.vars = c("LMA_g_m2", - "Cmass_g_g", - "Nmass_g_g", - "CN_Ratio")) +trait_data <- reshape2::melt(data = trait_data, id.vars = "USDA_Species_Code", measure.vars = c("LMA_g_m2", + "Cmass_g_g", + "Nmass_g_g", + "CN_Ratio")) head(trait_data) # Graph the trait data and save a file to the scratch space diff --git a/inst/scripts/sserbin2019_plsr_ex9.nb.html b/inst/scripts/sserbin2019_plsr_ex9.nb.html deleted file mode 100644 index 19ce379..0000000 --- a/inst/scripts/sserbin2019_plsr_ex9.nb.html +++ /dev/null @@ -1,731 +0,0 @@ - - - - - - - - - - - - - - - -An example showing how to apply an existing PLSR model to new data. In this case applying the LMA model from Serbin et al., (2019; DOI - 10.1111/nph.16123) to a dataset collected at CONUS NEON field sites - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - -
-

Getting Started

-
-
-

Load libraries

- - - -
list.of.packages <- c("pls","dplyr","reshape2","here","plotrix","ggplot2","gridExtra",
-                      "spectratrait")
-invisible(lapply(list.of.packages, library, character.only = TRUE))
- - -

-Attaching package: ‘pls’
-
-The following object is masked from ‘package:stats’:
-
-    loadings
-
-
-Attaching package: ‘dplyr’
-
-The following objects are masked from ‘package:stats’:
-
-    filter, lag
-
-The following objects are masked from ‘package:base’:
-
-    intersect, setdiff, setequal, union
-
-here() starts at /Users/sserbin/Data/GitHub/spectratrait
-
-Attaching package: ‘gridExtra’
-
-The following object is masked from ‘package:dplyr’:
-
-    combine
- - - -
-
-

Setup other functions and options

- - - -
### Setup options
-
-# Script options
-pls::pls.options(plsralg = "oscorespls")
-pls::pls.options("plsralg")
- - -
$plsralg
-[1] "oscorespls"
- - -
# Default par options
-opar <- par(no.readonly = T)
-
-# What is the target variable?
-inVar <- "LMA_gDW_m2"
-
-# What is the source dataset from EcoSIS?
-ecosis_id <- "5617da17-c925-49fb-b395-45a51291bd2d"
-
-# Specify output directory, output_dir 
-# Options: 
-# tempdir - use a OS-specified temporary directory 
-# user defined PATH - e.g. "~/scratch/PLSR"
-output_dir <- "tempdir"
- - - -
-
-

Set working directory (scratch space)

- - - -
The working directory was changed to /private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/RtmpvH9zex inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
- - -
[1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/RtmpvH9zex"
- - - -
-
-

Grab PLSR Coefficients from GitHub

- - - -
git_repo <- "https://raw.githubusercontent.com/serbinsh/SSerbin_etal_2019_NewPhytologist/master/"
-print("**** Downloading PLSR coefficients ****")
- - -
[1] "**** Downloading PLSR coefficients ****"
- - -
githubURL <- paste0(git_repo,"SSerbin_multibiome_lma_plsr_model/sqrt_LMA_gDW_m2_PLSR_Coefficients_10comp.csv")
-LeafLMA.plsr.coeffs <- spectratrait::source_GitHubData(githubURL)
-rm(githubURL)
-githubURL <- paste0(git_repo,"SSerbin_multibiome_lma_plsr_model/sqrt_LMA_gDW_m2_Jackkife_PLSR_Coefficients.csv")
-LeafLMA.plsr.jk.coeffs <- spectratrait::source_GitHubData(githubURL)
-rm(githubURL)
- - - -
-
-

Get source dataset from EcoSIS

- - - -
dat_raw <- spectratrait::get_ecosis_data(ecosis_id = ecosis_id)
- - -
[1] "**** Downloading Ecosis data ****"
- - -
Downloading data...
-Rows: 6312 Columns: 2162── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
-Delimiter: ","
-chr   (10): Affiliation, Common Name, Domain, Functional_type, Latin Genus, Latin Species, PI, Project, Sample_ID, USDA Symbol
-dbl (2152): LMA, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, ...
-ℹ Use `spec()` to retrieve the full column specification for this data.
-ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.Download complete!
- - -
head(dat_raw)
- - -
- -
- - -
names(dat_raw)[1:40]
- - -
 [1] "Affiliation"     "Common Name"     "Domain"          "Functional_type" "LMA"             "Latin Genus"     "Latin Species"   "PI"             
- [9] "Project"         "Sample_ID"       "USDA Symbol"     "350"             "351"             "352"             "353"             "354"            
-[17] "355"             "356"             "357"             "358"             "359"             "360"             "361"             "362"            
-[25] "363"             "364"             "365"             "366"             "367"             "368"             "369"             "370"            
-[33] "371"             "372"             "373"             "374"             "375"             "376"             "377"             "378"            
- - - -
-
-

Prepare new data for estimation

- - - -
Start.wave <- 500
-End.wave <- 2400
-wv <- seq(Start.wave,End.wave,1)
-Spectra <- as.matrix(dat_raw[,names(dat_raw) %in% wv])
-colnames(Spectra) <- c(paste0("Wave_",wv))
-head(Spectra)[1:6,1:10]
- - -
     Wave_500 Wave_501 Wave_502 Wave_503 Wave_504 Wave_505 Wave_506 Wave_507 Wave_508 Wave_509
-[1,] 0.044226 0.044605 0.044927 0.045473 0.046241 0.046878 0.047826 0.049090 0.050268 0.051525
-[2,] 0.046855 0.047601 0.047944 0.048478 0.049381 0.050235 0.051161 0.052191 0.053322 0.054357
-[3,] 0.043758 0.044171 0.044869 0.045465 0.045984 0.046933 0.047993 0.049090 0.050168 0.051441
-[4,] 0.041154 0.041603 0.042088 0.042408 0.042639 0.043260 0.044140 0.045058 0.045700 0.046476
-[5,] 0.037296 0.037944 0.038209 0.038677 0.039388 0.039948 0.040630 0.041501 0.042613 0.043731
-[6,] 0.043878 0.044257 0.044723 0.045295 0.045949 0.046575 0.047378 0.048357 0.049392 0.050387
- - -
sample_info <- dat_raw[,names(dat_raw) %notin% seq(350,2500,1)]
-head(sample_info)
- - -
- -
- - -

-sample_info2 <- sample_info %>%
-  select(Domain,Functional_type,Sample_ID,USDA_Species_Code=`USDA Symbol`,LMA_gDW_m2=LMA)
-head(sample_info2)
- - -
- -
- - -

-plsr_data <- data.frame(sample_info2,Spectra)
-rm(sample_info,sample_info2,Spectra)
- - - -
-

Example data cleaning.

- - - -
#### End user needs to do what's appropriate for their data.  This may be an iterative process.
-# Keep only complete rows of inVar and spec data before fitting
-plsr_data <- plsr_data[complete.cases(plsr_data[,names(plsr_data) %in% 
-                                                  c(inVar,paste0("Wave_",wv))]),]
- - - -
-
-

Prepare PLSR model

- - - -
print("**** Applying PLSR model to estimate LMA from spectral observations ****")
- - -
[1] "**** Applying PLSR model to estimate LMA from spectral observations ****"
- - -
# setup model
-dims <- dim(LeafLMA.plsr.coeffs)
-LeafLMA.plsr.intercept <- LeafLMA.plsr.coeffs[1,]
-LeafLMA.plsr.coeffs <- data.frame(LeafLMA.plsr.coeffs[2:dims[1],])
-names(LeafLMA.plsr.coeffs) <- c("wavelength","coefs")
-LeafLMA.plsr.coeffs.vec <- as.vector(LeafLMA.plsr.coeffs[,2])
-sub_spec <- droplevels(plsr_data[,which(names(plsr_data) %in% 
-                                                   paste0("Wave_",seq(Start.wave,End.wave,1)))])
- - - -
-
-

Apply PLSR model

- - - -
plsr_pred <- as.matrix(sub_spec) %*% LeafLMA.plsr.coeffs.vec + LeafLMA.plsr.intercept[,2]
-leafLMA <- plsr_pred[,1]^2  # convert to standard LMA units from sqrt(LMA)
-names(leafLMA) <- "PLSR_LMA_gDW_m2"
-
-# organize output
-LeafLMA.PLSR.dataset <- data.frame(plsr_data[,which(names(plsr_data) %notin% 
-                                                      paste0("Wave_",seq(Start.wave,End.wave,1)))],
-                                   PLSR_LMA_gDW_m2=leafLMA, PLSR_Residuals=leafLMA-plsr_data[,inVar])
-head(LeafLMA.PLSR.dataset)
- - -
- -
- - - -
-
-

Generate PLSR uncertainty estimates

- - - -
print("**** Generate PLSR uncertainty estimates ****")
- - -
[1] "**** Generate PLSR uncertainty estimates ****"
- - -
jk_coef <- data.frame(LeafLMA.plsr.jk.coeffs[,3:dim(LeafLMA.plsr.jk.coeffs)[2]])
-jk_coef <- t(jk_coef)
-head(jk_coef)[,1:6]
- - -
              [,1]      [,2]      [,3]      [,4]      [,5]      [,6]
-Wave_500 1.0005875 0.9952840 0.5652908 0.9793160 1.1052207 0.9370473
-Wave_501 0.9584235 0.9631434 0.5230544 0.9330803 1.0477469 0.9042780
-Wave_502 0.8960202 0.9065954 0.4597413 0.8710298 0.9658130 0.8628370
-Wave_503 0.8722135 0.8936197 0.4420696 0.8456098 0.9272967 0.8513741
-Wave_504 0.8452831 0.8644923 0.4159567 0.8110004 0.8903192 0.8320347
-Wave_505 0.8240743 0.8378399 0.3902871 0.7829891 0.8570048 0.8150339
- - -
jk_int <- t(LeafLMA.plsr.jk.coeffs[,2])
-head(jk_int)[,1:6]
- - -
[1] 7.787098 7.959443 8.015161 8.018586 7.658080 7.998432
- - -
jk_pred <- as.matrix(sub_spec) %*% jk_coef + matrix(rep(jk_int, length(plsr_data[,inVar])), 
-                                                    byrow=TRUE, ncol=length(jk_int))
-jk_pred <- jk_pred^2
-head(jk_pred)[,1:6]
- - -
      [,1]      [,2]      [,3]     [,4]      [,5]      [,6]
-1 94.28721  96.77712  96.44452 95.11992  96.72830  95.33877
-2 90.36051  90.57120  90.77562 89.77821  90.24826  89.61806
-3 75.71088  77.91861  76.42730 76.11473  77.67179  76.68756
-4 61.37001  61.30963  60.56606 60.72330  61.63712  60.69649
-5 99.24456 101.75948 101.22916 99.96305 101.70397 100.16758
-6 97.40414  97.65463  97.52687 97.00817  97.33677  96.08535
- - -
dim(jk_pred)
- - -
[1] 6312 1000
- - -
interval <- c(0.025,0.975)
-Interval_Conf <- apply(X = jk_pred, MARGIN = 1, FUN = quantile, 
-                       probs=c(interval[1], interval[2]))
-sd_mean <- apply(X = jk_pred, MARGIN = 1, FUN =sd)
-sd_res <- sd(LeafLMA.PLSR.dataset$PLSR_Residuals)
-sd_tot <- sqrt(sd_mean^2+sd_res^2)
-LeafLMA.PLSR.dataset$LCI <- Interval_Conf[1,]
-LeafLMA.PLSR.dataset$UCI <- Interval_Conf[2,]
-LeafLMA.PLSR.dataset$LPI <- LeafLMA.PLSR.dataset$PLSR_LMA_gDW_m2-1.96*sd_tot
-LeafLMA.PLSR.dataset$UPI <- LeafLMA.PLSR.dataset$PLSR_LMA_gDW_m2+1.96*sd_tot
-head(LeafLMA.PLSR.dataset)
- - -
- -
- - - -
-
-

Generate PLSR estimated LMA observed vs predicted plot

- - - -
rmsep_percrmsep <- spectratrait::percent_rmse(plsr_dataset = LeafLMA.PLSR.dataset, 
-                                              inVar = inVar, 
-                                              residuals = LeafLMA.PLSR.dataset$PLSR_Residuals, 
-                                              range="full")
-RMSEP <- rmsep_percrmsep$rmse
-perc_RMSEP <- rmsep_percrmsep$perc_rmse
-r2 <- round(summary(lm(LeafLMA.PLSR.dataset$PLSR_LMA_gDW_m2~
-                         LeafLMA.PLSR.dataset[,inVar]))$adj.r.squared,2)
-expr <- vector("expression", 3)
-expr[[1]] <- bquote(R^2==.(r2))
-expr[[2]] <- bquote(RMSEP==.(round(RMSEP,2)))
-expr[[3]] <- bquote("%RMSEP"==.(round(perc_RMSEP,2)))
-rng_vals <- c(min(LeafLMA.PLSR.dataset$LPI), max(LeafLMA.PLSR.dataset$UPI))
-par(mfrow=c(1,1), mar=c(4.2,5.3,1,0.4), oma=c(0, 0.1, 0, 0.2))
-plotrix::plotCI(LeafLMA.PLSR.dataset$PLSR_LMA_gDW_m2,LeafLMA.PLSR.dataset[,inVar], 
-                li=LeafLMA.PLSR.dataset$LPI, ui=LeafLMA.PLSR.dataset$UPI, gap=0.009,sfrac=0.000, 
-                lwd=1.6, xlim=c(rng_vals[1], rng_vals[2]), ylim=c(rng_vals[1], rng_vals[2]), 
-                err="x", pch=21, col="black", pt.bg=scales::alpha("grey70",0.7), scol="grey80",
-                cex=2, xlab=paste0("Predicted ", paste(inVar), " (units)"),
-                ylab=paste0("Observed ", paste(inVar), " (units)"),
-                cex.axis=1.5,cex.lab=1.8)
-abline(0,1,lty=2,lw=2)
- - -
plotrix::plotCI(LeafLMA.PLSR.dataset$PLSR_LMA_gDW_m2,LeafLMA.PLSR.dataset[,inVar], 
-                li=LeafLMA.PLSR.dataset$LCI, ui=LeafLMA.PLSR.dataset$UCI, gap=0.009,sfrac=0.004, 
-                lwd=1.6, xlim=c(rng_vals[1], rng_vals[2]), ylim=c(rng_vals[1], rng_vals[2]), 
-                err="x", pch=21, col="black", pt.bg=scales::alpha("grey70",0.7), scol="black",
-                cex=2, xlab=paste0("Predicted ", paste(inVar), " (units)"),
-                ylab=paste0("Observed ", paste(inVar), " (units)"),
-                cex.axis=1.5,cex.lab=1.8, add=T)
-legend("topleft", legend=expr, bty="n", cex=1.5)
- - -
legend("bottomright", legend=c("Prediction Interval","Confidence Interval"), 
-       lty=c(1,1), col = c("grey80","black"), lwd=3, bty="n", cex=1.5)
-box(lwd=2.2)
- - -
dev.copy(png,file.path(outdir,paste0(inVar,"_PLSR_Validation_Scatterplot.png")), 
-         height=2800, width=3200,  res=340)
- - -
quartz_off_screen 
-                3 
- - -
dev.off();
- - -
quartz_off_screen 
-                2 
- - -

- - - - -
print(paste("Output directory: ", outdir))
- - -
[1] "Output directory:  /var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T//RtmpvH9zex"
- - -
# Observed versus predicted
-write.csv(LeafLMA.PLSR.dataset,file=file.path(outdir,
-                                         paste0(inVar,'_PLSR_Estimates.csv')),
-          row.names=FALSE)
- - - -
-
-
-

Confirm files were written to temp space

- - - -
print("**** PLSR output files: ")
- - -
[1] "**** PLSR output files: "
- - -
print(list.files(outdir)[grep(pattern = inVar, list.files(outdir))])
- - -
[1] "LMA_gDW_m2_PLSR_Estimates.csv"              "LMA_gDW_m2_PLSR_Validation_Scatterplot.png"
- - -
- -
LS0tCnRpdGxlOiBBbiBleGFtcGxlIHNob3dpbmcgaG93IHRvIGFwcGx5IGFuIGV4aXN0aW5nIFBMU1IgbW9kZWwgdG8gbmV3IGRhdGEuIEluIHRoaXMgY2FzZSBhcHBseWluZyB0aGUgTE1BIG1vZGVsIGZyb20gU2VyYmluIGV0IGFsLiwgKDIwMTk7IERPSSAtIDEwLjExMTEvbnBoLjE2MTIzKSB0byBhIGRhdGFzZXQgY29sbGVjdGVkIGF0IENPTlVTIE5FT04gZmllbGQgc2l0ZXMgCmF1dGhvcjogIlNoYXduIFAuIFNlcmJpbiwgSnVsaWVuIExhbW91ciwgJiBKZXJlbWlhaCBBbmRlcnNvbiIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFLCBlY2hvPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyMjIEdldHRpbmcgU3RhcnRlZAojIyMgTG9hZCBsaWJyYXJpZXMKYGBge3IsIGV2YWw9VFJVRSwgZWNobz1UUlVFfQpsaXN0Lm9mLnBhY2thZ2VzIDwtIGMoInBscyIsImRwbHlyIiwicmVzaGFwZTIiLCJoZXJlIiwicGxvdHJpeCIsImdncGxvdDIiLCJncmlkRXh0cmEiLAogICAgICAgICAgICAgICAgICAgICAgInNwZWN0cmF0cmFpdCIpCmludmlzaWJsZShsYXBwbHkobGlzdC5vZi5wYWNrYWdlcywgbGlicmFyeSwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKSkKYGBgCgojIyMgU2V0dXAgb3RoZXIgZnVuY3Rpb25zIGFuZCBvcHRpb25zCmBgYHtyLCBlY2hvPVRSVUV9CiMjIyBTZXR1cCBvcHRpb25zCgojIFNjcmlwdCBvcHRpb25zCnBsczo6cGxzLm9wdGlvbnMocGxzcmFsZyA9ICJvc2NvcmVzcGxzIikKcGxzOjpwbHMub3B0aW9ucygicGxzcmFsZyIpCgojIERlZmF1bHQgcGFyIG9wdGlvbnMKb3BhciA8LSBwYXIobm8ucmVhZG9ubHkgPSBUKQoKIyBXaGF0IGlzIHRoZSB0YXJnZXQgdmFyaWFibGU/CmluVmFyIDwtICJMTUFfZ0RXX20yIgoKIyBXaGF0IGlzIHRoZSBzb3VyY2UgZGF0YXNldCBmcm9tIEVjb1NJUz8KZWNvc2lzX2lkIDwtICI1NjE3ZGExNy1jOTI1LTQ5ZmItYjM5NS00NWE1MTI5MWJkMmQiCgojIFNwZWNpZnkgb3V0cHV0IGRpcmVjdG9yeSwgb3V0cHV0X2RpciAKIyBPcHRpb25zOiAKIyB0ZW1wZGlyIC0gdXNlIGEgT1Mtc3BlY2lmaWVkIHRlbXBvcmFyeSBkaXJlY3RvcnkgCiMgdXNlciBkZWZpbmVkIFBBVEggLSBlLmcuICJ+L3NjcmF0Y2gvUExTUiIKb3V0cHV0X2RpciA8LSAidGVtcGRpciIKYGBgCgojIyMgU2V0IHdvcmtpbmcgZGlyZWN0b3J5IChzY3JhdGNoIHNwYWNlKQpgYGB7ciwgZWNobz1GQUxTRX0KaWYgKG91dHB1dF9kaXI9PSJ0ZW1wZGlyIikgewogIG91dGRpciA8LSB0ZW1wZGlyKCkKfSBlbHNlIHsKICBpZiAoISBmaWxlLmV4aXN0cyhvdXRwdXRfZGlyKSkgZGlyLmNyZWF0ZShvdXRwdXRfZGlyLHJlY3Vyc2l2ZT1UUlVFKQogIG91dGRpciA8LSBmaWxlLnBhdGgocGF0aC5leHBhbmQob3V0cHV0X2RpcikpCn0Kc2V0d2Qob3V0ZGlyKSAjIHNldCB3b3JraW5nIGRpcmVjdG9yeQpnZXR3ZCgpICAjIGNoZWNrIHdkCmBgYAoKIyMjIEdyYWIgUExTUiBDb2VmZmljaWVudHMgZnJvbSBHaXRIdWIKYGBge3IsIGVjaG89VFJVRX0KZ2l0X3JlcG8gPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9zZXJiaW5zaC9TU2VyYmluX2V0YWxfMjAxOV9OZXdQaHl0b2xvZ2lzdC9tYXN0ZXIvIgpwcmludCgiKioqKiBEb3dubG9hZGluZyBQTFNSIGNvZWZmaWNpZW50cyAqKioqIikKZ2l0aHViVVJMIDwtIHBhc3RlMChnaXRfcmVwbywiU1NlcmJpbl9tdWx0aWJpb21lX2xtYV9wbHNyX21vZGVsL3NxcnRfTE1BX2dEV19tMl9QTFNSX0NvZWZmaWNpZW50c18xMGNvbXAuY3N2IikKTGVhZkxNQS5wbHNyLmNvZWZmcyA8LSBzcGVjdHJhdHJhaXQ6OnNvdXJjZV9HaXRIdWJEYXRhKGdpdGh1YlVSTCkKcm0oZ2l0aHViVVJMKQpnaXRodWJVUkwgPC0gcGFzdGUwKGdpdF9yZXBvLCJTU2VyYmluX211bHRpYmlvbWVfbG1hX3Bsc3JfbW9kZWwvc3FydF9MTUFfZ0RXX20yX0phY2traWZlX1BMU1JfQ29lZmZpY2llbnRzLmNzdiIpCkxlYWZMTUEucGxzci5qay5jb2VmZnMgPC0gc3BlY3RyYXRyYWl0Ojpzb3VyY2VfR2l0SHViRGF0YShnaXRodWJVUkwpCnJtKGdpdGh1YlVSTCkKYGBgCgojIyMgR2V0IHNvdXJjZSBkYXRhc2V0IGZyb20gRWNvU0lTCmBgYHtyLCBlY2hvPVRSVUV9CmRhdF9yYXcgPC0gc3BlY3RyYXRyYWl0OjpnZXRfZWNvc2lzX2RhdGEoZWNvc2lzX2lkID0gZWNvc2lzX2lkKQpoZWFkKGRhdF9yYXcpCm5hbWVzKGRhdF9yYXcpWzE6NDBdCmBgYAoKIyMjIFByZXBhcmUgbmV3IGRhdGEgZm9yIGVzdGltYXRpb24KYGBge3IsIGVjaG89VFJVRX0KU3RhcnQud2F2ZSA8LSA1MDAKRW5kLndhdmUgPC0gMjQwMAp3diA8LSBzZXEoU3RhcnQud2F2ZSxFbmQud2F2ZSwxKQpTcGVjdHJhIDwtIGFzLm1hdHJpeChkYXRfcmF3WyxuYW1lcyhkYXRfcmF3KSAlaW4lIHd2XSkKY29sbmFtZXMoU3BlY3RyYSkgPC0gYyhwYXN0ZTAoIldhdmVfIix3dikpCmhlYWQoU3BlY3RyYSlbMTo2LDE6MTBdCnNhbXBsZV9pbmZvIDwtIGRhdF9yYXdbLG5hbWVzKGRhdF9yYXcpICVub3RpbiUgc2VxKDM1MCwyNTAwLDEpXQpoZWFkKHNhbXBsZV9pbmZvKQoKc2FtcGxlX2luZm8yIDwtIHNhbXBsZV9pbmZvICU+JQogIHNlbGVjdChEb21haW4sRnVuY3Rpb25hbF90eXBlLFNhbXBsZV9JRCxVU0RBX1NwZWNpZXNfQ29kZT1gVVNEQSBTeW1ib2xgLExNQV9nRFdfbTI9TE1BKQpoZWFkKHNhbXBsZV9pbmZvMikKCnBsc3JfZGF0YSA8LSBkYXRhLmZyYW1lKHNhbXBsZV9pbmZvMixTcGVjdHJhKQpybShzYW1wbGVfaW5mbyxzYW1wbGVfaW5mbzIsU3BlY3RyYSkKYGBgCgojIyMjIEV4YW1wbGUgZGF0YSBjbGVhbmluZy4gCmBgYHtyLCBlY2hvPVRSVUV9CiMjIyMgRW5kIHVzZXIgbmVlZHMgdG8gZG8gd2hhdCdzIGFwcHJvcHJpYXRlIGZvciB0aGVpciBkYXRhLiAgVGhpcyBtYXkgYmUgYW4gaXRlcmF0aXZlIHByb2Nlc3MuCiMgS2VlcCBvbmx5IGNvbXBsZXRlIHJvd3Mgb2YgaW5WYXIgYW5kIHNwZWMgZGF0YSBiZWZvcmUgZml0dGluZwpwbHNyX2RhdGEgPC0gcGxzcl9kYXRhW2NvbXBsZXRlLmNhc2VzKHBsc3JfZGF0YVssbmFtZXMocGxzcl9kYXRhKSAlaW4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoaW5WYXIscGFzdGUwKCJXYXZlXyIsd3YpKV0pLF0KYGBgCgojIyMjIFByZXBhcmUgUExTUiBtb2RlbApgYGB7ciwgZWNobz1UUlVFfQpwcmludCgiKioqKiBBcHBseWluZyBQTFNSIG1vZGVsIHRvIGVzdGltYXRlIExNQSBmcm9tIHNwZWN0cmFsIG9ic2VydmF0aW9ucyAqKioqIikKIyBzZXR1cCBtb2RlbApkaW1zIDwtIGRpbShMZWFmTE1BLnBsc3IuY29lZmZzKQpMZWFmTE1BLnBsc3IuaW50ZXJjZXB0IDwtIExlYWZMTUEucGxzci5jb2VmZnNbMSxdCkxlYWZMTUEucGxzci5jb2VmZnMgPC0gZGF0YS5mcmFtZShMZWFmTE1BLnBsc3IuY29lZmZzWzI6ZGltc1sxXSxdKQpuYW1lcyhMZWFmTE1BLnBsc3IuY29lZmZzKSA8LSBjKCJ3YXZlbGVuZ3RoIiwiY29lZnMiKQpMZWFmTE1BLnBsc3IuY29lZmZzLnZlYyA8LSBhcy52ZWN0b3IoTGVhZkxNQS5wbHNyLmNvZWZmc1ssMl0pCnN1Yl9zcGVjIDwtIGRyb3BsZXZlbHMocGxzcl9kYXRhWyx3aGljaChuYW1lcyhwbHNyX2RhdGEpICVpbiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlMCgiV2F2ZV8iLHNlcShTdGFydC53YXZlLEVuZC53YXZlLDEpKSldKQpgYGAKCiMjIyMgQXBwbHkgUExTUiBtb2RlbApgYGB7ciwgZWNobz1UUlVFfQpwbHNyX3ByZWQgPC0gYXMubWF0cml4KHN1Yl9zcGVjKSAlKiUgTGVhZkxNQS5wbHNyLmNvZWZmcy52ZWMgKyBMZWFmTE1BLnBsc3IuaW50ZXJjZXB0WywyXQpsZWFmTE1BIDwtIHBsc3JfcHJlZFssMV1eMiAgIyBjb252ZXJ0IHRvIHN0YW5kYXJkIExNQSB1bml0cyBmcm9tIHNxcnQoTE1BKQpuYW1lcyhsZWFmTE1BKSA8LSAiUExTUl9MTUFfZ0RXX20yIgoKIyBvcmdhbml6ZSBvdXRwdXQKTGVhZkxNQS5QTFNSLmRhdGFzZXQgPC0gZGF0YS5mcmFtZShwbHNyX2RhdGFbLHdoaWNoKG5hbWVzKHBsc3JfZGF0YSkgJW5vdGluJSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKCJXYXZlXyIsc2VxKFN0YXJ0LndhdmUsRW5kLndhdmUsMSkpKV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUExTUl9MTUFfZ0RXX20yPWxlYWZMTUEsIFBMU1JfUmVzaWR1YWxzPWxlYWZMTUEtcGxzcl9kYXRhWyxpblZhcl0pCmhlYWQoTGVhZkxNQS5QTFNSLmRhdGFzZXQpCmBgYAoKIyMjIyBHZW5lcmF0ZSBQTFNSIHVuY2VydGFpbnR5IGVzdGltYXRlcwpgYGB7ciwgZWNobz1UUlVFfQpwcmludCgiKioqKiBHZW5lcmF0ZSBQTFNSIHVuY2VydGFpbnR5IGVzdGltYXRlcyAqKioqIikKamtfY29lZiA8LSBkYXRhLmZyYW1lKExlYWZMTUEucGxzci5qay5jb2VmZnNbLDM6ZGltKExlYWZMTUEucGxzci5qay5jb2VmZnMpWzJdXSkKamtfY29lZiA8LSB0KGprX2NvZWYpCmhlYWQoamtfY29lZilbLDE6Nl0KamtfaW50IDwtIHQoTGVhZkxNQS5wbHNyLmprLmNvZWZmc1ssMl0pCmhlYWQoamtfaW50KVssMTo2XQoKamtfcHJlZCA8LSBhcy5tYXRyaXgoc3ViX3NwZWMpICUqJSBqa19jb2VmICsgbWF0cml4KHJlcChqa19pbnQsIGxlbmd0aChwbHNyX2RhdGFbLGluVmFyXSkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5cm93PVRSVUUsIG5jb2w9bGVuZ3RoKGprX2ludCkpCmprX3ByZWQgPC0gamtfcHJlZF4yCmhlYWQoamtfcHJlZClbLDE6Nl0KZGltKGprX3ByZWQpCmludGVydmFsIDwtIGMoMC4wMjUsMC45NzUpCkludGVydmFsX0NvbmYgPC0gYXBwbHkoWCA9IGprX3ByZWQsIE1BUkdJTiA9IDEsIEZVTiA9IHF1YW50aWxlLCAKICAgICAgICAgICAgICAgICAgICAgICBwcm9icz1jKGludGVydmFsWzFdLCBpbnRlcnZhbFsyXSkpCnNkX21lYW4gPC0gYXBwbHkoWCA9IGprX3ByZWQsIE1BUkdJTiA9IDEsIEZVTiA9c2QpCnNkX3JlcyA8LSBzZChMZWFmTE1BLlBMU1IuZGF0YXNldCRQTFNSX1Jlc2lkdWFscykKc2RfdG90IDwtIHNxcnQoc2RfbWVhbl4yK3NkX3Jlc14yKQpMZWFmTE1BLlBMU1IuZGF0YXNldCRMQ0kgPC0gSW50ZXJ2YWxfQ29uZlsxLF0KTGVhZkxNQS5QTFNSLmRhdGFzZXQkVUNJIDwtIEludGVydmFsX0NvbmZbMixdCkxlYWZMTUEuUExTUi5kYXRhc2V0JExQSSA8LSBMZWFmTE1BLlBMU1IuZGF0YXNldCRQTFNSX0xNQV9nRFdfbTItMS45NipzZF90b3QKTGVhZkxNQS5QTFNSLmRhdGFzZXQkVVBJIDwtIExlYWZMTUEuUExTUi5kYXRhc2V0JFBMU1JfTE1BX2dEV19tMisxLjk2KnNkX3RvdApoZWFkKExlYWZMTUEuUExTUi5kYXRhc2V0KQpgYGAKCiMjIyMgR2VuZXJhdGUgUExTUiBlc3RpbWF0ZWQgTE1BIG9ic2VydmVkIHZzIHByZWRpY3RlZCBwbG90CmBgYHtyLCBmaWcuaGVpZ2h0ID0gNywgZmlnLndpZHRoID0gOCwgZWNobz1UUlVFfQpybXNlcF9wZXJjcm1zZXAgPC0gc3BlY3RyYXRyYWl0OjpwZXJjZW50X3Jtc2UocGxzcl9kYXRhc2V0ID0gTGVhZkxNQS5QTFNSLmRhdGFzZXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5WYXIgPSBpblZhciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNpZHVhbHMgPSBMZWFmTE1BLlBMU1IuZGF0YXNldCRQTFNSX1Jlc2lkdWFscywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZT0iZnVsbCIpClJNU0VQIDwtIHJtc2VwX3BlcmNybXNlcCRybXNlCnBlcmNfUk1TRVAgPC0gcm1zZXBfcGVyY3Jtc2VwJHBlcmNfcm1zZQpyMiA8LSByb3VuZChzdW1tYXJ5KGxtKExlYWZMTUEuUExTUi5kYXRhc2V0JFBMU1JfTE1BX2dEV19tMn4KICAgICAgICAgICAgICAgICAgICAgICAgIExlYWZMTUEuUExTUi5kYXRhc2V0WyxpblZhcl0pKSRhZGouci5zcXVhcmVkLDIpCmV4cHIgPC0gdmVjdG9yKCJleHByZXNzaW9uIiwgMykKZXhwcltbMV1dIDwtIGJxdW90ZShSXjI9PS4ocjIpKQpleHByW1syXV0gPC0gYnF1b3RlKFJNU0VQPT0uKHJvdW5kKFJNU0VQLDIpKSkKZXhwcltbM11dIDwtIGJxdW90ZSgiJVJNU0VQIj09Lihyb3VuZChwZXJjX1JNU0VQLDIpKSkKcm5nX3ZhbHMgPC0gYyhtaW4oTGVhZkxNQS5QTFNSLmRhdGFzZXQkTFBJKSwgbWF4KExlYWZMTUEuUExTUi5kYXRhc2V0JFVQSSkpCnBhcihtZnJvdz1jKDEsMSksIG1hcj1jKDQuMiw1LjMsMSwwLjQpLCBvbWE9YygwLCAwLjEsIDAsIDAuMikpCnBsb3RyaXg6OnBsb3RDSShMZWFmTE1BLlBMU1IuZGF0YXNldCRQTFNSX0xNQV9nRFdfbTIsTGVhZkxNQS5QTFNSLmRhdGFzZXRbLGluVmFyXSwgCiAgICAgICAgICAgICAgICBsaT1MZWFmTE1BLlBMU1IuZGF0YXNldCRMUEksIHVpPUxlYWZMTUEuUExTUi5kYXRhc2V0JFVQSSwgZ2FwPTAuMDA5LHNmcmFjPTAuMDAwLCAKICAgICAgICAgICAgICAgIGx3ZD0xLjYsIHhsaW09YyhybmdfdmFsc1sxXSwgcm5nX3ZhbHNbMl0pLCB5bGltPWMocm5nX3ZhbHNbMV0sIHJuZ192YWxzWzJdKSwgCiAgICAgICAgICAgICAgICBlcnI9IngiLCBwY2g9MjEsIGNvbD0iYmxhY2siLCBwdC5iZz1zY2FsZXM6OmFscGhhKCJncmV5NzAiLDAuNyksIHNjb2w9ImdyZXk4MCIsCiAgICAgICAgICAgICAgICBjZXg9MiwgeGxhYj1wYXN0ZTAoIlByZWRpY3RlZCAiLCBwYXN0ZShpblZhciksICIgKHVuaXRzKSIpLAogICAgICAgICAgICAgICAgeWxhYj1wYXN0ZTAoIk9ic2VydmVkICIsIHBhc3RlKGluVmFyKSwgIiAodW5pdHMpIiksCiAgICAgICAgICAgICAgICBjZXguYXhpcz0xLjUsY2V4LmxhYj0xLjgpCmFibGluZSgwLDEsbHR5PTIsbHc9MikKcGxvdHJpeDo6cGxvdENJKExlYWZMTUEuUExTUi5kYXRhc2V0JFBMU1JfTE1BX2dEV19tMixMZWFmTE1BLlBMU1IuZGF0YXNldFssaW5WYXJdLCAKICAgICAgICAgICAgICAgIGxpPUxlYWZMTUEuUExTUi5kYXRhc2V0JExDSSwgdWk9TGVhZkxNQS5QTFNSLmRhdGFzZXQkVUNJLCBnYXA9MC4wMDksc2ZyYWM9MC4wMDQsIAogICAgICAgICAgICAgICAgbHdkPTEuNiwgeGxpbT1jKHJuZ192YWxzWzFdLCBybmdfdmFsc1syXSksIHlsaW09YyhybmdfdmFsc1sxXSwgcm5nX3ZhbHNbMl0pLCAKICAgICAgICAgICAgICAgIGVycj0ieCIsIHBjaD0yMSwgY29sPSJibGFjayIsIHB0LmJnPXNjYWxlczo6YWxwaGEoImdyZXk3MCIsMC43KSwgc2NvbD0iYmxhY2siLAogICAgICAgICAgICAgICAgY2V4PTIsIHhsYWI9cGFzdGUwKCJQcmVkaWN0ZWQgIiwgcGFzdGUoaW5WYXIpLCAiICh1bml0cykiKSwKICAgICAgICAgICAgICAgIHlsYWI9cGFzdGUwKCJPYnNlcnZlZCAiLCBwYXN0ZShpblZhciksICIgKHVuaXRzKSIpLAogICAgICAgICAgICAgICAgY2V4LmF4aXM9MS41LGNleC5sYWI9MS44LCBhZGQ9VCkKbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kPWV4cHIsIGJ0eT0ibiIsIGNleD0xLjUpCmxlZ2VuZCgiYm90dG9tcmlnaHQiLCBsZWdlbmQ9YygiUHJlZGljdGlvbiBJbnRlcnZhbCIsIkNvbmZpZGVuY2UgSW50ZXJ2YWwiKSwgCiAgICAgICBsdHk9YygxLDEpLCBjb2wgPSBjKCJncmV5ODAiLCJibGFjayIpLCBsd2Q9MywgYnR5PSJuIiwgY2V4PTEuNSkKYm94KGx3ZD0yLjIpCmRldi5jb3B5KHBuZyxmaWxlLnBhdGgob3V0ZGlyLHBhc3RlMChpblZhciwiX1BMU1JfVmFsaWRhdGlvbl9TY2F0dGVycGxvdC5wbmciKSksIAogICAgICAgICBoZWlnaHQ9MjgwMCwgd2lkdGg9MzIwMCwgIHJlcz0zNDApCmRldi5vZmYoKTsKYGBgCmBgYHtyLCBlY2hvPVRSVUV9CnByaW50KHBhc3RlKCJPdXRwdXQgZGlyZWN0b3J5OiAiLCBvdXRkaXIpKQoKIyBPYnNlcnZlZCB2ZXJzdXMgcHJlZGljdGVkCndyaXRlLmNzdihMZWFmTE1BLlBMU1IuZGF0YXNldCxmaWxlPWZpbGUucGF0aChvdXRkaXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKGluVmFyLCdfUExTUl9Fc3RpbWF0ZXMuY3N2JykpLAogICAgICAgICAgcm93Lm5hbWVzPUZBTFNFKQpgYGAKCiMjIyBDb25maXJtIGZpbGVzIHdlcmUgd3JpdHRlbiB0byB0ZW1wIHNwYWNlCmBgYHtyLCBlY2hvPVRSVUV9CnByaW50KCIqKioqIFBMU1Igb3V0cHV0IGZpbGVzOiAiKQpwcmludChsaXN0LmZpbGVzKG91dGRpcilbZ3JlcChwYXR0ZXJuID0gaW5WYXIsIGxpc3QuZmlsZXMob3V0ZGlyKSldKQpgYGAK
- - - -
- - - - - - - - - - - - - - - - diff --git a/vignettes/ely_etal_ex1.Rmd b/vignettes/ely_etal_ex1.Rmd index 07ae725..f9545d2 100644 --- a/vignettes/ely_etal_ex1.Rmd +++ b/vignettes/ely_etal_ex1.Rmd @@ -8,6 +8,7 @@ output: html_notebook: default html_document: df_print: paged + keep_md: true rmarkdown: html_vignette vignette: > %\VignetteIndexEntry{Spectra-trait PLSR example using leaf-level spectra and leaf nitrogen content (Narea, g/m2) data from eight different crop species growing in a glasshouse at Brookhaven National Laboratory} diff --git a/vignettes/ely_etal_ex1.md b/vignettes/ely_etal_ex1.md index 89b3068..bbf4649 100644 --- a/vignettes/ely_etal_ex1.md +++ b/vignettes/ely_etal_ex1.md @@ -3,7 +3,7 @@ content (Narea, g/m2) data from eight different crop species growing in a glasshouse at Brookhaven National Laboratory ================ Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson -2022-03-14 +2022-03-17 ### Overview @@ -28,6 +28,8 @@ invisible(lapply(list.of.packages, library, character.only = TRUE)) ## ## loadings + ## Warning: package 'dplyr' was built under R version 4.0.5 + ## ## Attaching package: 'dplyr' @@ -101,7 +103,7 @@ inVar <- "N_g_m2" ### Set working directory (scratch space) - ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/Rtmp6TSCWg" + ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/RtmpP2S4KY" ### Full PLSR dataset @@ -752,7 +754,7 @@ write.csv(out.jk.coefs,file=file.path(outdir,paste0(inVar, print(paste("Output directory: ", outdir)) ``` - ## [1] "Output directory: /var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T//Rtmp6TSCWg" + ## [1] "Output directory: /var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T//RtmpP2S4KY" ``` r # Observed versus predicted diff --git a/vignettes/ely_etal_ex2.Rmd b/vignettes/ely_etal_ex2.Rmd index f4776e2..b73ae49 100644 --- a/vignettes/ely_etal_ex2.Rmd +++ b/vignettes/ely_etal_ex2.Rmd @@ -3,11 +3,12 @@ title: Spectra-trait PLSR example using leaf-level spectra and leaf nitrogen con author: "Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson" date: "`r Sys.Date()`" output: - pdf_document: default - html_notebook: default github_document: default + html_notebook: default + pdf_document: default html_document: df_print: paged + keep_md: true rmarkdown: html_vignette vignette: > %\VignetteIndexEntry{Spectra-trait PLSR example using leaf-level spectra and leaf nitrogen content (Narea, g/m2) data from eight different crop species growing in a glasshouse at Brookhaven National Laboratory. This example illustrates running the PLSR permutation by group} diff --git a/vignettes/ely_etal_ex2.md b/vignettes/ely_etal_ex2.md index 06328aa..da603b9 100644 --- a/vignettes/ely_etal_ex2.md +++ b/vignettes/ely_etal_ex2.md @@ -4,7 +4,7 @@ a glasshouse at Brookhaven National Laboratory. This example illustrates running the PLSR permutation by group ================ Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson -2022-03-14 +2022-03-17 ### Overview @@ -29,6 +29,8 @@ invisible(lapply(list.of.packages, library, character.only = TRUE)) ## ## loadings + ## Warning: package 'dplyr' was built under R version 4.0.5 + ## ## Attaching package: 'dplyr' @@ -102,7 +104,7 @@ inVar <- "N_g_m2" ### Set working directory (scratch space) - ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/RtmplDLTQi" + ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/RtmpX6UzBl" ### Full PLSR dataset @@ -753,7 +755,7 @@ write.csv(out.jk.coefs,file=file.path(outdir,paste0(inVar, print(paste("Output directory: ", outdir)) ``` - ## [1] "Output directory: /var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T//RtmplDLTQi" + ## [1] "Output directory: /var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T//RtmpX6UzBl" ``` r # Observed versus predicted diff --git a/vignettes/kit_sla_ex3.Rmd b/vignettes/kit_sla_ex3.Rmd index e0afc41..5e5c733 100644 --- a/vignettes/kit_sla_ex3.Rmd +++ b/vignettes/kit_sla_ex3.Rmd @@ -3,11 +3,12 @@ title: Spectra-trait PLSR example using leaf-level spectra and specific leaf are author: "Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson" date: "`r Sys.Date()`" output: - pdf_document: default github_document: default + pdf_document: default html_notebook: default html_document: df_print: paged + keep_md: true rmarkdown: html_vignette vignette: > %\VignetteIndexEntry{Spectra-trait PLSR example using leaf-level spectra and specific leaf area (SLA) data from more than 40 species grassland species comprising both herbs and graminoids} diff --git a/vignettes/kit_sla_ex3.md b/vignettes/kit_sla_ex3.md index 44d6a60..7975295 100644 --- a/vignettes/kit_sla_ex3.md +++ b/vignettes/kit_sla_ex3.md @@ -3,7 +3,7 @@ area (SLA) data from more than 40 species grassland species comprising both herbs and graminoids ================ Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson -2022-03-16 +2022-03-17 ### Overview @@ -32,6 +32,8 @@ invisible(lapply(list.of.packages, library, character.only = TRUE)) ## ## loadings + ## Warning: package 'dplyr' was built under R version 4.0.5 + ## ## Attaching package: 'dplyr' @@ -84,7 +86,7 @@ output_dir <- "tempdir" ### Set working directory (scratch space) - ## [1] "Output directory: /private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/Rtmp83RkYg" + ## [1] "Output directory: /private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/Rtmp2EY9wO" ### Grab data from EcoSIS diff --git a/vignettes/neon_canopy_leafN_ex5.Rmd b/vignettes/neon_canopy_leafN_ex5.Rmd index 6521ae2..5cc8676 100644 --- a/vignettes/neon_canopy_leafN_ex5.Rmd +++ b/vignettes/neon_canopy_leafN_ex5.Rmd @@ -3,11 +3,12 @@ title: Spectra-trait PLSR example using NEON AOP pixel spectra and field-sampled author: "Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson" date: "`r Sys.Date()`" output: - pdf_document: default + github_document: default html_notebook: default html_document: df_print: paged - github_document: default + keep_md: true + pdf_document: default rmarkdown: html_vignette vignette: > %\VignetteIndexEntry{Spectra-trait PLSR example using NEON AOP pixel spectra and field-sampled leaf nitrogen content from CONUS NEON sites} diff --git a/vignettes/neon_canopy_leafN_ex5.md b/vignettes/neon_canopy_leafN_ex5.md index 1a66c71..3d9c353 100644 --- a/vignettes/neon_canopy_leafN_ex5.md +++ b/vignettes/neon_canopy_leafN_ex5.md @@ -2,7 +2,7 @@ Spectra-trait PLSR example using NEON AOP pixel spectra and field-sampled leaf nitrogen content from CONUS NEON sites ================ Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson -2022-03-15 +2022-03-17 ### Overview @@ -29,6 +29,8 @@ invisible(lapply(list.of.packages, library, character.only = TRUE)) ## ## loadings + ## Warning: package 'dplyr' was built under R version 4.0.5 + ## ## Attaching package: 'dplyr' @@ -81,7 +83,7 @@ output_dir <- "tempdir" ### Set working directory (scratch space) - ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/Rtmp5uYCrF" + ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/Rtmp4LIZez" ### Grab data from EcoSIS diff --git a/vignettes/neon_lma_ex4.Rmd b/vignettes/neon_lma_ex4.Rmd index db4a649..9ceb241 100644 --- a/vignettes/neon_lma_ex4.Rmd +++ b/vignettes/neon_lma_ex4.Rmd @@ -3,11 +3,12 @@ title: Spectra-trait PLSR example using leaf-level spectra and leaf mass per are author: "Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson" date: "`r Sys.Date()`" output: - pdf_document: default + github_document: default html_document: df_print: paged + keep_md: true html_notebook: default - github_document: default + pdf_document: default rmarkdown: html_vignette vignette: > %\VignetteIndexEntry{Spectra-trait PLSR example using leaf-level spectra and leaf mass per area (LMA) data from CONUS NEON sites} diff --git a/vignettes/neon_lma_ex4.md b/vignettes/neon_lma_ex4.md index 38b5be5..561c6a4 100644 --- a/vignettes/neon_lma_ex4.md +++ b/vignettes/neon_lma_ex4.md @@ -2,7 +2,7 @@ Spectra-trait PLSR example using leaf-level spectra and leaf mass per area (LMA) data from CONUS NEON sites ================ Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson -2022-03-15 +2022-03-17 ### Overview @@ -27,6 +27,8 @@ invisible(lapply(list.of.packages, library, character.only = TRUE)) ## ## loadings + ## Warning: package 'dplyr' was built under R version 4.0.5 + ## ## Attaching package: 'dplyr' @@ -79,7 +81,7 @@ output_dir <- "tempdir" ### Set working directory (scratch space) - ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/RtmplNNxbk" + ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/RtmpniosdI" ### Grab data from EcoSIS diff --git a/vignettes/reseco_leafN_ex6.Rmd b/vignettes/reseco_leafN_ex6.Rmd index 7057785..5ff2ed0 100644 --- a/vignettes/reseco_leafN_ex6.Rmd +++ b/vignettes/reseco_leafN_ex6.Rmd @@ -7,6 +7,7 @@ output: html_notebook: default html_document: df_print: paged + keep_md: true rmarkdown: html_vignette pdf_document: default vignette: > diff --git a/vignettes/reseco_leafN_ex6.md b/vignettes/reseco_leafN_ex6.md index e4b1aba..b549c80 100644 --- a/vignettes/reseco_leafN_ex6.md +++ b/vignettes/reseco_leafN_ex6.md @@ -3,7 +3,7 @@ content (Narea, g/m2) data from 36 species growing in Rosa rugosa invaded coastal grassland communities in Belgium ================ Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson -2022-03-15 +2022-03-17 ### Overview @@ -28,6 +28,8 @@ invisible(lapply(list.of.packages, library, character.only = TRUE)) ## ## loadings + ## Warning: package 'dplyr' was built under R version 4.0.5 + ## ## Attaching package: 'dplyr' @@ -80,7 +82,7 @@ output_dir <- "tempdir" ### Set working directory (scratch space) - ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/Rtmpu6cY9u" + ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/RtmpJx6SqV" ### Grab data from EcoSIS @@ -844,7 +846,7 @@ write.csv(out.jk.coefs,file=file.path(outdir, print(paste("Output directory: ", outdir)) ``` - ## [1] "Output directory: /var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T//Rtmpu6cY9u" + ## [1] "Output directory: /var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T//RtmpJx6SqV" ``` r # Observed versus predicted diff --git a/vignettes/reseco_leafN_ex7.Rmd b/vignettes/reseco_leafN_ex7.Rmd index 145ca55..6a5fa43 100644 --- a/vignettes/reseco_leafN_ex7.Rmd +++ b/vignettes/reseco_leafN_ex7.Rmd @@ -7,6 +7,7 @@ output: html_notebook: default html_document: df_print: paged + keep_md: true pdf_document: default rmarkdown: html_vignette vignette: > diff --git a/vignettes/reseco_leafN_ex7.md b/vignettes/reseco_leafN_ex7.md index 6e88a94..fc1ec03 100644 --- a/vignettes/reseco_leafN_ex7.md +++ b/vignettes/reseco_leafN_ex7.md @@ -4,7 +4,7 @@ invaded coastal grassland communities in Belgium. Bootstrap validation example ================ Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson -2022-03-15 +2022-03-17 ### Overview @@ -29,6 +29,8 @@ invisible(lapply(list.of.packages, library, character.only = TRUE)) ## ## loadings + ## Warning: package 'dplyr' was built under R version 4.0.5 + ## ## Attaching package: 'dplyr' @@ -81,7 +83,7 @@ output_dir <- "tempdir" ### Set working directory (scratch space) - ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/RtmpvqmQPe" + ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/Rtmp7T2QBK" ### Grab data from EcoSIS @@ -846,7 +848,7 @@ write.csv(out.jk.coefs,file=file.path(outdir,paste0(inVar, print(paste("Output directory: ", outdir)) ``` - ## [1] "Output directory: /var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T//RtmpvqmQPe" + ## [1] "Output directory: /var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T//Rtmp7T2QBK" ``` r # Observed versus predicted diff --git a/vignettes/reseco_lma_ex8.Rmd b/vignettes/reseco_lma_ex8.Rmd index c049aa5..4d7ced7 100644 --- a/vignettes/reseco_lma_ex8.Rmd +++ b/vignettes/reseco_lma_ex8.Rmd @@ -8,6 +8,7 @@ output: pdf_document: default html_document: df_print: paged + keep_md: true rmarkdown: html_vignette vignette: > %\VignetteIndexEntry{Spectra-trait PLSR example using leaf-level spectra and leaf mass per area (LMA) data from 36 species growing in Rosa rugosa invaded coastal grassland communities in Belgium} diff --git a/vignettes/reseco_lma_ex8.md b/vignettes/reseco_lma_ex8.md index 10277ae..aed792c 100644 --- a/vignettes/reseco_lma_ex8.md +++ b/vignettes/reseco_lma_ex8.md @@ -3,7 +3,7 @@ area (LMA) data from 36 species growing in Rosa rugosa invaded coastal grassland communities in Belgium ================ Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson -2022-03-15 +2022-03-17 ### Overview @@ -28,6 +28,8 @@ invisible(lapply(list.of.packages, library, character.only = TRUE)) ## ## loadings + ## Warning: package 'dplyr' was built under R version 4.0.5 + ## ## Attaching package: 'dplyr' @@ -80,7 +82,7 @@ output_dir <- "tempdir" ### Step 3. Set working directory (scratch space) - ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/RtmpBge300" + ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/Rtmp9hZZCN" ### Step 4. Pull example dataset from EcoSIS (ecosis.org) @@ -879,7 +881,7 @@ write.csv(out.jk.coefs,file=file.path(outdir, print(paste("Output directory: ", outdir)) ``` - ## [1] "Output directory: /var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T//RtmpBge300" + ## [1] "Output directory: /var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T//Rtmp9hZZCN" ``` r # Observed versus predicted diff --git a/inst/scripts/sserbin2019_plsr_ex9.Rmd b/vignettes/sserbin2019_plsr_ex9.Rmd similarity index 94% rename from inst/scripts/sserbin2019_plsr_ex9.Rmd rename to vignettes/sserbin2019_plsr_ex9.Rmd index cf2bc4c..0c9b754 100644 --- a/inst/scripts/sserbin2019_plsr_ex9.Rmd +++ b/vignettes/sserbin2019_plsr_ex9.Rmd @@ -3,7 +3,17 @@ title: An example showing how to apply an existing PLSR model to new data. In th author: "Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson" date: "`r Sys.Date()`" output: + github_document: default html_notebook: default + pdf_document: default + html_document: + df_print: paged + keep_md: true + rmarkdown: html_vignette +vignette: > + %\VignetteIndexEntry{An example showing how to apply an existing PLSR model to new data. In this case applying the LMA model from Serbin et al., (2019; DOI - 10.1111/nph.16123) to a dataset collected at CONUS NEON field sites} + %\usepackage[utf8]{inputenc} + %\VignetteEngine{knitr::knitr} --- ```{r setup, include=FALSE, echo=FALSE} @@ -168,7 +178,7 @@ expr[[1]] <- bquote(R^2==.(r2)) expr[[2]] <- bquote(RMSEP==.(round(RMSEP,2))) expr[[3]] <- bquote("%RMSEP"==.(round(perc_RMSEP,2))) rng_vals <- c(min(LeafLMA.PLSR.dataset$LPI), max(LeafLMA.PLSR.dataset$UPI)) -par(mfrow=c(1,1), mar=c(4.2,5.3,1,0.4), oma=c(0, 0.1, 0, 0.2)) +par(mfrow=c(1,1), mar=c(4,5.3,1,0.4), oma=c(0.1, 0.1, 0.1, 0.2)) plotrix::plotCI(LeafLMA.PLSR.dataset$PLSR_LMA_gDW_m2,LeafLMA.PLSR.dataset[,inVar], li=LeafLMA.PLSR.dataset$LPI, ui=LeafLMA.PLSR.dataset$UPI, gap=0.009,sfrac=0.000, lwd=1.6, xlim=c(rng_vals[1], rng_vals[2]), ylim=c(rng_vals[1], rng_vals[2]), diff --git a/vignettes/sserbin2019_plsr_ex9.md b/vignettes/sserbin2019_plsr_ex9.md new file mode 100644 index 0000000..05ed1aa --- /dev/null +++ b/vignettes/sserbin2019_plsr_ex9.md @@ -0,0 +1,436 @@ +An example showing how to apply an existing PLSR model to new data. In +this case applying the LMA model from Serbin et al., (2019; DOI - +10.1111/nph.16123) to a dataset collected at CONUS NEON field sites +================ +Shawn P. Serbin, Julien Lamour, & Jeremiah Anderson +2022-03-17 + +### Getting Started + +### Load libraries + +``` r +list.of.packages <- c("pls","dplyr","reshape2","here","plotrix","ggplot2","gridExtra", + "spectratrait") +invisible(lapply(list.of.packages, library, character.only = TRUE)) +``` + + ## + ## Attaching package: 'pls' + + ## The following object is masked from 'package:stats': + ## + ## loadings + + ## Warning: package 'dplyr' was built under R version 4.0.5 + + ## + ## Attaching package: 'dplyr' + + ## The following objects are masked from 'package:stats': + ## + ## filter, lag + + ## The following objects are masked from 'package:base': + ## + ## intersect, setdiff, setequal, union + + ## here() starts at /Users/sserbin/Data/GitHub/spectratrait + + ## + ## Attaching package: 'gridExtra' + + ## The following object is masked from 'package:dplyr': + ## + ## combine + +### Setup other functions and options + +``` r +### Setup options + +# Script options +pls::pls.options(plsralg = "oscorespls") +pls::pls.options("plsralg") +``` + + ## $plsralg + ## [1] "oscorespls" + +``` r +# Default par options +opar <- par(no.readonly = T) + +# What is the target variable? +inVar <- "LMA_gDW_m2" + +# What is the source dataset from EcoSIS? +ecosis_id <- "5617da17-c925-49fb-b395-45a51291bd2d" + +# Specify output directory, output_dir +# Options: +# tempdir - use a OS-specified temporary directory +# user defined PATH - e.g. "~/scratch/PLSR" +output_dir <- "tempdir" +``` + +### Set working directory (scratch space) + + ## [1] "/private/var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T/RtmpfDvF7M" + +### Grab PLSR Coefficients from GitHub + +``` r +git_repo <- "https://raw.githubusercontent.com/serbinsh/SSerbin_etal_2019_NewPhytologist/master/" +print("**** Downloading PLSR coefficients ****") +``` + + ## [1] "**** Downloading PLSR coefficients ****" + +``` r +githubURL <- paste0(git_repo,"SSerbin_multibiome_lma_plsr_model/sqrt_LMA_gDW_m2_PLSR_Coefficients_10comp.csv") +LeafLMA.plsr.coeffs <- spectratrait::source_GitHubData(githubURL) +rm(githubURL) +githubURL <- paste0(git_repo,"SSerbin_multibiome_lma_plsr_model/sqrt_LMA_gDW_m2_Jackkife_PLSR_Coefficients.csv") +LeafLMA.plsr.jk.coeffs <- spectratrait::source_GitHubData(githubURL) +rm(githubURL) +``` + +### Get source dataset from EcoSIS + +``` r +dat_raw <- spectratrait::get_ecosis_data(ecosis_id = ecosis_id) +``` + + ## [1] "**** Downloading Ecosis data ****" + + ## Downloading data... + + ## Rows: 6312 Columns: 2162 + ## ── Column specification ──────────────────────────────────────────────────────── + ## Delimiter: "," + ## chr (10): Affiliation, Common Name, Domain, Functional_type, Latin Genus, ... + ## dbl (2152): LMA, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361,... + ## + ## ℹ Use `spec()` to retrieve the full column specification for this data. + ## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message. + ## Download complete! + +``` r +head(dat_raw) +``` + + ## # A tibble: 6 × 2,162 + ## Affiliation `Common Name` Domain Functional_type LMA `Latin Genus` + ## + ## 1 University of Wiscon… black walnut D02 broadleaf 72.9 Juglans + ## 2 University of Wiscon… black walnut D02 broadleaf 72.9 Juglans + ## 3 University of Wiscon… black walnut D02 broadleaf 60.8 Juglans + ## 4 University of Wiscon… black walnut D02 broadleaf 60.8 Juglans + ## 5 University of Wiscon… black walnut D02 broadleaf 85.9 Juglans + ## 6 University of Wiscon… black walnut D02 broadleaf 85.9 Juglans + ## # … with 2,156 more variables: `Latin Species` , PI , Project , + ## # Sample_ID , `USDA Symbol` , `350` , `351` , + ## # `352` , `353` , `354` , `355` , `356` , + ## # `357` , `358` , `359` , `360` , `361` , + ## # `362` , `363` , `364` , `365` , `366` , + ## # `367` , `368` , `369` , `370` , `371` , + ## # `372` , `373` , `374` , `375` , `376` , … + +``` r +names(dat_raw)[1:40] +``` + + ## [1] "Affiliation" "Common Name" "Domain" "Functional_type" + ## [5] "LMA" "Latin Genus" "Latin Species" "PI" + ## [9] "Project" "Sample_ID" "USDA Symbol" "350" + ## [13] "351" "352" "353" "354" + ## [17] "355" "356" "357" "358" + ## [21] "359" "360" "361" "362" + ## [25] "363" "364" "365" "366" + ## [29] "367" "368" "369" "370" + ## [33] "371" "372" "373" "374" + ## [37] "375" "376" "377" "378" + +### Prepare new data for estimation + +``` r +Start.wave <- 500 +End.wave <- 2400 +wv <- seq(Start.wave,End.wave,1) +Spectra <- as.matrix(dat_raw[,names(dat_raw) %in% wv]) +colnames(Spectra) <- c(paste0("Wave_",wv)) +head(Spectra)[1:6,1:10] +``` + + ## Wave_500 Wave_501 Wave_502 Wave_503 Wave_504 Wave_505 Wave_506 Wave_507 + ## [1,] 0.044226 0.044605 0.044927 0.045473 0.046241 0.046878 0.047826 0.049090 + ## [2,] 0.046855 0.047601 0.047944 0.048478 0.049381 0.050235 0.051161 0.052191 + ## [3,] 0.043758 0.044171 0.044869 0.045465 0.045984 0.046933 0.047993 0.049090 + ## [4,] 0.041154 0.041603 0.042088 0.042408 0.042639 0.043260 0.044140 0.045058 + ## [5,] 0.037296 0.037944 0.038209 0.038677 0.039388 0.039948 0.040630 0.041501 + ## [6,] 0.043878 0.044257 0.044723 0.045295 0.045949 0.046575 0.047378 0.048357 + ## Wave_508 Wave_509 + ## [1,] 0.050268 0.051525 + ## [2,] 0.053322 0.054357 + ## [3,] 0.050168 0.051441 + ## [4,] 0.045700 0.046476 + ## [5,] 0.042613 0.043731 + ## [6,] 0.049392 0.050387 + +``` r +sample_info <- dat_raw[,names(dat_raw) %notin% seq(350,2500,1)] +head(sample_info) +``` + + ## # A tibble: 6 × 11 + ## Affiliation `Common Name` Domain Functional_type LMA `Latin Genus` + ## + ## 1 University of Wiscon… black walnut D02 broadleaf 72.9 Juglans + ## 2 University of Wiscon… black walnut D02 broadleaf 72.9 Juglans + ## 3 University of Wiscon… black walnut D02 broadleaf 60.8 Juglans + ## 4 University of Wiscon… black walnut D02 broadleaf 60.8 Juglans + ## 5 University of Wiscon… black walnut D02 broadleaf 85.9 Juglans + ## 6 University of Wiscon… black walnut D02 broadleaf 85.9 Juglans + ## # … with 5 more variables: `Latin Species` , PI , Project , + ## # Sample_ID , `USDA Symbol` + +``` r +sample_info2 <- sample_info %>% + select(Domain,Functional_type,Sample_ID,USDA_Species_Code=`USDA Symbol`,LMA_gDW_m2=LMA) +head(sample_info2) +``` + + ## # A tibble: 6 × 5 + ## Domain Functional_type Sample_ID USDA_Species_Code LMA_gDW_m2 + ## + ## 1 D02 broadleaf P0001 JUNI 72.9 + ## 2 D02 broadleaf L0001 JUNI 72.9 + ## 3 D02 broadleaf P0002 JUNI 60.8 + ## 4 D02 broadleaf L0002 JUNI 60.8 + ## 5 D02 broadleaf P0003 JUNI 85.9 + ## 6 D02 broadleaf L0003 JUNI 85.9 + +``` r +plsr_data <- data.frame(sample_info2,Spectra) +rm(sample_info,sample_info2,Spectra) +``` + +#### Example data cleaning. + +``` r +#### End user needs to do what's appropriate for their data. This may be an iterative process. +# Keep only complete rows of inVar and spec data before fitting +plsr_data <- plsr_data[complete.cases(plsr_data[,names(plsr_data) %in% + c(inVar,paste0("Wave_",wv))]),] +``` + +#### Prepare PLSR model + +``` r +print("**** Applying PLSR model to estimate LMA from spectral observations ****") +``` + + ## [1] "**** Applying PLSR model to estimate LMA from spectral observations ****" + +``` r +# setup model +dims <- dim(LeafLMA.plsr.coeffs) +LeafLMA.plsr.intercept <- LeafLMA.plsr.coeffs[1,] +LeafLMA.plsr.coeffs <- data.frame(LeafLMA.plsr.coeffs[2:dims[1],]) +names(LeafLMA.plsr.coeffs) <- c("wavelength","coefs") +LeafLMA.plsr.coeffs.vec <- as.vector(LeafLMA.plsr.coeffs[,2]) +sub_spec <- droplevels(plsr_data[,which(names(plsr_data) %in% + paste0("Wave_",seq(Start.wave,End.wave,1)))]) +``` + +#### Apply PLSR model + +``` r +plsr_pred <- as.matrix(sub_spec) %*% LeafLMA.plsr.coeffs.vec + LeafLMA.plsr.intercept[,2] +leafLMA <- plsr_pred[,1]^2 # convert to standard LMA units from sqrt(LMA) +names(leafLMA) <- "PLSR_LMA_gDW_m2" + +# organize output +LeafLMA.PLSR.dataset <- data.frame(plsr_data[,which(names(plsr_data) %notin% + paste0("Wave_",seq(Start.wave,End.wave,1)))], + PLSR_LMA_gDW_m2=leafLMA, PLSR_Residuals=leafLMA-plsr_data[,inVar]) +head(LeafLMA.PLSR.dataset) +``` + + ## Domain Functional_type Sample_ID USDA_Species_Code LMA_gDW_m2 PLSR_LMA_gDW_m2 + ## 1 D02 broadleaf P0001 JUNI 72.87 96.26243 + ## 2 D02 broadleaf L0001 JUNI 72.87 90.09453 + ## 3 D02 broadleaf P0002 JUNI 60.77 77.16475 + ## 4 D02 broadleaf L0002 JUNI 60.77 60.99039 + ## 5 D02 broadleaf P0003 JUNI 85.92 101.22709 + ## 6 D02 broadleaf L0003 JUNI 85.92 97.13018 + ## PLSR_Residuals + ## 1 23.3924343 + ## 2 17.2245326 + ## 3 16.3947533 + ## 4 0.2203913 + ## 5 15.3070857 + ## 6 11.2101840 + +#### Generate PLSR uncertainty estimates + +``` r +print("**** Generate PLSR uncertainty estimates ****") +``` + + ## [1] "**** Generate PLSR uncertainty estimates ****" + +``` r +jk_coef <- data.frame(LeafLMA.plsr.jk.coeffs[,3:dim(LeafLMA.plsr.jk.coeffs)[2]]) +jk_coef <- t(jk_coef) +head(jk_coef)[,1:6] +``` + + ## [,1] [,2] [,3] [,4] [,5] [,6] + ## Wave_500 1.0005875 0.9952840 0.5652908 0.9793160 1.1052207 0.9370473 + ## Wave_501 0.9584235 0.9631434 0.5230544 0.9330803 1.0477469 0.9042780 + ## Wave_502 0.8960202 0.9065954 0.4597413 0.8710298 0.9658130 0.8628370 + ## Wave_503 0.8722135 0.8936197 0.4420696 0.8456098 0.9272967 0.8513741 + ## Wave_504 0.8452831 0.8644923 0.4159567 0.8110004 0.8903192 0.8320347 + ## Wave_505 0.8240743 0.8378399 0.3902871 0.7829891 0.8570048 0.8150339 + +``` r +jk_int <- t(LeafLMA.plsr.jk.coeffs[,2]) +head(jk_int)[,1:6] +``` + + ## [1] 7.787098 7.959443 8.015161 8.018586 7.658080 7.998432 + +``` r +jk_pred <- as.matrix(sub_spec) %*% jk_coef + matrix(rep(jk_int, length(plsr_data[,inVar])), + byrow=TRUE, ncol=length(jk_int)) +jk_pred <- jk_pred^2 +head(jk_pred)[,1:6] +``` + + ## [,1] [,2] [,3] [,4] [,5] [,6] + ## 1 94.28721 96.77712 96.44452 95.11992 96.72830 95.33877 + ## 2 90.36051 90.57120 90.77562 89.77821 90.24826 89.61806 + ## 3 75.71088 77.91861 76.42730 76.11473 77.67179 76.68756 + ## 4 61.37001 61.30963 60.56606 60.72330 61.63712 60.69649 + ## 5 99.24456 101.75948 101.22916 99.96305 101.70397 100.16758 + ## 6 97.40414 97.65463 97.52687 97.00817 97.33677 96.08535 + +``` r +dim(jk_pred) +``` + + ## [1] 6312 1000 + +``` r +interval <- c(0.025,0.975) +Interval_Conf <- apply(X = jk_pred, MARGIN = 1, FUN = quantile, + probs=c(interval[1], interval[2])) +sd_mean <- apply(X = jk_pred, MARGIN = 1, FUN =sd) +sd_res <- sd(LeafLMA.PLSR.dataset$PLSR_Residuals) +sd_tot <- sqrt(sd_mean^2+sd_res^2) +LeafLMA.PLSR.dataset$LCI <- Interval_Conf[1,] +LeafLMA.PLSR.dataset$UCI <- Interval_Conf[2,] +LeafLMA.PLSR.dataset$LPI <- LeafLMA.PLSR.dataset$PLSR_LMA_gDW_m2-1.96*sd_tot +LeafLMA.PLSR.dataset$UPI <- LeafLMA.PLSR.dataset$PLSR_LMA_gDW_m2+1.96*sd_tot +head(LeafLMA.PLSR.dataset) +``` + + ## Domain Functional_type Sample_ID USDA_Species_Code LMA_gDW_m2 PLSR_LMA_gDW_m2 + ## 1 D02 broadleaf P0001 JUNI 72.87 96.26243 + ## 2 D02 broadleaf L0001 JUNI 72.87 90.09453 + ## 3 D02 broadleaf P0002 JUNI 60.77 77.16475 + ## 4 D02 broadleaf L0002 JUNI 60.77 60.99039 + ## 5 D02 broadleaf P0003 JUNI 85.92 101.22709 + ## 6 D02 broadleaf L0003 JUNI 85.92 97.13018 + ## PLSR_Residuals LCI UCI LPI UPI + ## 1 23.3924343 93.95423 99.03625 71.30476 121.2201 + ## 2 17.2245326 88.81329 92.00078 65.21071 114.9784 + ## 3 16.3947533 74.79509 79.85715 52.19722 102.1323 + ## 4 0.2203913 59.80058 62.29402 36.12678 85.8540 + ## 5 15.3070857 98.86570 103.97701 76.26586 126.1883 + ## 6 11.2101840 95.50843 99.66865 72.20971 122.0507 + +#### Generate PLSR estimated LMA observed vs predicted plot + +``` r +rmsep_percrmsep <- spectratrait::percent_rmse(plsr_dataset = LeafLMA.PLSR.dataset, + inVar = inVar, + residuals = LeafLMA.PLSR.dataset$PLSR_Residuals, + range="full") +RMSEP <- rmsep_percrmsep$rmse +perc_RMSEP <- rmsep_percrmsep$perc_rmse +r2 <- round(summary(lm(LeafLMA.PLSR.dataset$PLSR_LMA_gDW_m2~ + LeafLMA.PLSR.dataset[,inVar]))$adj.r.squared,2) +expr <- vector("expression", 3) +expr[[1]] <- bquote(R^2==.(r2)) +expr[[2]] <- bquote(RMSEP==.(round(RMSEP,2))) +expr[[3]] <- bquote("%RMSEP"==.(round(perc_RMSEP,2))) +rng_vals <- c(min(LeafLMA.PLSR.dataset$LPI), max(LeafLMA.PLSR.dataset$UPI)) +par(mfrow=c(1,1), mar=c(4,5.3,1,0.4), oma=c(0.1, 0.1, 0.1, 0.2)) +plotrix::plotCI(LeafLMA.PLSR.dataset$PLSR_LMA_gDW_m2,LeafLMA.PLSR.dataset[,inVar], + li=LeafLMA.PLSR.dataset$LPI, ui=LeafLMA.PLSR.dataset$UPI, gap=0.009,sfrac=0.000, + lwd=1.6, xlim=c(rng_vals[1], rng_vals[2]), ylim=c(rng_vals[1], rng_vals[2]), + err="x", pch=21, col="black", pt.bg=scales::alpha("grey70",0.7), scol="grey80", + cex=2, xlab=paste0("Predicted ", paste(inVar), " (units)"), + ylab=paste0("Observed ", paste(inVar), " (units)"), + cex.axis=1.5,cex.lab=1.8) +abline(0,1,lty=2,lw=2) +plotrix::plotCI(LeafLMA.PLSR.dataset$PLSR_LMA_gDW_m2,LeafLMA.PLSR.dataset[,inVar], + li=LeafLMA.PLSR.dataset$LCI, ui=LeafLMA.PLSR.dataset$UCI, gap=0.009,sfrac=0.004, + lwd=1.6, xlim=c(rng_vals[1], rng_vals[2]), ylim=c(rng_vals[1], rng_vals[2]), + err="x", pch=21, col="black", pt.bg=scales::alpha("grey70",0.7), scol="black", + cex=2, xlab=paste0("Predicted ", paste(inVar), " (units)"), + ylab=paste0("Observed ", paste(inVar), " (units)"), + cex.axis=1.5,cex.lab=1.8, add=T) +legend("topleft", legend=expr, bty="n", cex=1.5) +legend("bottomright", legend=c("Prediction Interval","Confidence Interval"), + lty=c(1,1), col = c("grey80","black"), lwd=3, bty="n", cex=1.5) +box(lwd=2.2) +``` + +![](sserbin2019_plsr_ex9_files/figure-gfm/unnamed-chunk-11-1.png) + +``` r +dev.copy(png,file.path(outdir,paste0(inVar,"_PLSR_Validation_Scatterplot.png")), + height=2800, width=3200, res=340) +``` + + ## quartz_off_screen + ## 3 + +``` r +dev.off(); +``` + + ## quartz_off_screen + ## 2 + +``` r +print(paste("Output directory: ", outdir)) +``` + + ## [1] "Output directory: /var/folders/xp/h3k9vf3n2jx181ts786_yjrn9c2gjq/T//RtmpfDvF7M" + +``` r +# Observed versus predicted +write.csv(LeafLMA.PLSR.dataset,file=file.path(outdir, + paste0(inVar,'_PLSR_Estimates.csv')), + row.names=FALSE) +``` + +### Confirm files were written to temp space + +``` r +print("**** PLSR output files: ") +``` + + ## [1] "**** PLSR output files: " + +``` r +print(list.files(outdir)[grep(pattern = inVar, list.files(outdir))]) +``` + + ## [1] "LMA_gDW_m2_PLSR_Estimates.csv" + ## [2] "LMA_gDW_m2_PLSR_Validation_Scatterplot.png" diff --git a/vignettes/sserbin2019_plsr_ex9.pdf b/vignettes/sserbin2019_plsr_ex9.pdf new file mode 100644 index 0000000..85a4a19 Binary files /dev/null and b/vignettes/sserbin2019_plsr_ex9.pdf differ diff --git a/vignettes/sserbin2019_plsr_ex9_files/figure-gfm/unnamed-chunk-11-1.png b/vignettes/sserbin2019_plsr_ex9_files/figure-gfm/unnamed-chunk-11-1.png new file mode 100644 index 0000000..4398978 Binary files /dev/null and b/vignettes/sserbin2019_plsr_ex9_files/figure-gfm/unnamed-chunk-11-1.png differ