├── .github ├── .gitignore └── workflows │ ├── pkgdown.yaml │ └── R-CMD-check.yaml ├── vignettes ├── .gitignore ├── facet_comps.Rmd ├── uspmw001.fhx ├── introduction.Rmd └── uspme001.fhx ├── data ├── pgm.rda ├── pme.rda ├── pmr.rda ├── pmw.rda ├── lgr2.rda ├── pgm_meta.rda ├── pgm_pdsi.rda └── lgr2_meta.rda ├── R ├── sysdata.rda ├── data.R ├── io.R ├── stats.R └── intervals.R ├── tests ├── testthat.R └── testthat │ ├── test-intervals.R │ ├── test-plotting.R │ ├── test-sea.R │ ├── test-stats.R │ └── test-utils.R ├── man ├── figures │ └── README-example-1.png ├── is_sea.Rd ├── is.sea.Rd ├── lgr2.Rd ├── pme.Rd ├── pmr.Rd ├── pmw.Rd ├── is_intervals.Rd ├── is.intervals.Rd ├── sample_depth.Rd ├── summary.fhx.Rd ├── first_year.Rd ├── plot.intervals.Rd ├── lgr2_meta.Rd ├── count_scar.Rd ├── count_injury.Rd ├── count_recording.Rd ├── write_fhx.Rd ├── last_year.Rd ├── is_fhx.Rd ├── print.intervals.Rd ├── yearly_recording.Rd ├── is.fhx.Rd ├── inner_type.Rd ├── outer_type.Rd ├── pgm.Rd ├── count_year_span.Rd ├── plot.sea.Rd ├── series_mean_interval.Rd ├── get_series.Rd ├── as.fhx.Rd ├── make_rec_type.Rd ├── as_fhx.Rd ├── plot_sealags.Rd ├── plus-.fhx.Rd ├── percent_scarred.Rd ├── max.intervals.Rd ├── mean.intervals.Rd ├── median.intervals.Rd ├── min.intervals.Rd ├── read_fhx.Rd ├── pgm_pdsi.Rd ├── pgm_meta.Rd ├── get_year.Rd ├── plot.fhx.Rd ├── year_range.Rd ├── print.sea.Rd ├── series_names.Rd ├── sort.fhx.Rd ├── delete.Rd ├── quantile.intervals.Rd ├── plot_intervals_dist.Rd ├── get_event_years.Rd ├── count_event_position.Rd ├── composite.Rd ├── fhx.Rd ├── intervals.Rd ├── series_stats.Rd ├── sea.Rd └── plot_demograph.Rd ├── data-raw ├── lgr2.R ├── pgm.R ├── pgm_meta.R ├── lgr2_meta.R ├── pgm_pdsi.R ├── lgr2_meta.csv ├── pajaritomountain.R ├── pgm_meta.csv ├── sysdata.R ├── uspmw001.fhx └── uspme001.fhx ├── .Rbuildignore ├── cran-comments.md ├── burnr.Rproj ├── inst └── CITATION ├── .gitignore ├── DESCRIPTION ├── NAMESPACE ├── _pkgdown.yml ├── README.md └── README.Rmd /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /data/pgm.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brews/burnr/master/data/pgm.rda -------------------------------------------------------------------------------- /data/pme.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brews/burnr/master/data/pme.rda -------------------------------------------------------------------------------- /data/pmr.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brews/burnr/master/data/pmr.rda -------------------------------------------------------------------------------- /data/pmw.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brews/burnr/master/data/pmw.rda -------------------------------------------------------------------------------- /R/sysdata.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brews/burnr/master/R/sysdata.rda -------------------------------------------------------------------------------- /data/lgr2.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brews/burnr/master/data/lgr2.rda -------------------------------------------------------------------------------- /data/pgm_meta.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brews/burnr/master/data/pgm_meta.rda -------------------------------------------------------------------------------- /data/pgm_pdsi.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brews/burnr/master/data/pgm_pdsi.rda -------------------------------------------------------------------------------- /data/lgr2_meta.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brews/burnr/master/data/lgr2_meta.rda -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(burnr) 3 | 4 | test_check("burnr") 5 | -------------------------------------------------------------------------------- /man/figures/README-example-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brews/burnr/master/man/figures/README-example-1.png -------------------------------------------------------------------------------- /data-raw/lgr2.R: -------------------------------------------------------------------------------- 1 | library(burnr) 2 | library(usethis) 3 | 4 | lgr2 <- read_fhx("data-raw/lgr2.fhx") 5 | 6 | usethis::use_data(lgr2, overwrite = TRUE) 7 | -------------------------------------------------------------------------------- /data-raw/pgm.R: -------------------------------------------------------------------------------- 1 | library(burnr) 2 | library(usethis) 3 | 4 | pgm <- read_fhx("data-raw/pgm.fhx") 5 | 6 | usethis::use_data(pgm, overwrite = TRUE) 7 | -------------------------------------------------------------------------------- /data-raw/pgm_meta.R: -------------------------------------------------------------------------------- 1 | library(usethis) 2 | 3 | pgm_meta <- read.csv("data-raw/pgm_meta.csv") 4 | 5 | usethis::use_data(pgm_meta, overwrite = TRUE) 6 | -------------------------------------------------------------------------------- /data-raw/lgr2_meta.R: -------------------------------------------------------------------------------- 1 | library(usethis) 2 | 3 | lgr2_meta <- read.csv("data-raw/lgr2_meta.csv") 4 | 5 | usethis::use_data(lgr2_meta, overwrite = TRUE) 6 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^.*\.sublime-workspace$ 4 | ^.*\.sublime-project$ 5 | ^\.vscode 6 | ^.*\.code-workspace$ 7 | ^data-raw$ 8 | ^cran-comments\.md$ 9 | ^CRAN-RELEASE$ 10 | ^README\.Rmd$ 11 | ^\.github$ 12 | ^_pkgdown\.yml$ 13 | ^docs$ 14 | ^pkgdown$ 15 | ^vignettes/articles$ 16 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | * local Ubuntu 20.04.3 install, R 4.1.2 3 | * Github Actions: ubuntu-20.04.3 (devel, release), windows-latest (release) macOS-latest (release). 4 | 5 | ## R CMD check results 6 | There were no ERRORs, WARNINGs, or NOTEs. 7 | 8 | ## Downstream dependencies 9 | This package has no downstream dependencies. 10 | -------------------------------------------------------------------------------- /data-raw/pgm_pdsi.R: -------------------------------------------------------------------------------- 1 | library(usethis) 2 | 3 | # TXT file downloaded from http://iridl.ldeo.columbia.edu/SOURCES/.LDEO/.TRL/.NADA2004/pdsiatlashtml/pdsiwebdata/1050w_350n_133.txt 4 | pdsi_raw <- read.table("data-raw/pgm_pdsi.txt", header = TRUE, row.names = 1) 5 | pgm_pdsi <- subset(pdsi_raw, select = "RECON") 6 | 7 | usethis::use_data(pgm_pdsi, overwrite = TRUE) 8 | -------------------------------------------------------------------------------- /data-raw/lgr2_meta.csv: -------------------------------------------------------------------------------- 1 | TreeID,SpeciesID 2 | LGR54,PIPO 3 | LGR44,PIPO 4 | LGR47,PIPO 5 | LGR48,PIPO 6 | LGR46,PIPO 7 | LGR41,PSME 8 | LGR52,PSME 9 | LGR51,PSME 10 | LGR45,PIST 11 | LGR49,PSME 12 | LGR53,PSME 13 | LGR43,PSME 14 | LGR55,PSME 15 | LGR56,POTR 16 | LGR36,POTR 17 | LGR33,POTR 18 | LGR32,POTR 19 | LGR31,POTR 20 | LGR27,POTR 21 | LGR29,PSME 22 | LGR25,PSME 23 | LGR35,POTR 24 | LGR30,POTR 25 | LGR26,PSME 26 | LGR42,PSME 27 | LGR34,PSME 28 | -------------------------------------------------------------------------------- /data-raw/pajaritomountain.R: -------------------------------------------------------------------------------- 1 | # Encode Pajarito mountains data 2 | 3 | library(burnr) 4 | library(usethis) 5 | 6 | # Data obtained from NOAA IMPD 7 | ## https://www1.ncdc.noaa.gov/pub/data/paleo/firehistory/firescar/northamerica/ 8 | 9 | pmr <- read_fhx('data-raw/uspmr001.fhx') 10 | pme <- read_fhx('data-raw/uspme001.fhx') 11 | pmw <- read_fhx('data-raw/uspmw001.fhx') 12 | 13 | use_data(pmr, overwrite = TRUE) 14 | use_data(pme, overwrite = TRUE) 15 | use_data(pmw, overwrite = TRUE) 16 | -------------------------------------------------------------------------------- /man/is_sea.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sea.R 3 | \name{is_sea} 4 | \alias{is_sea} 5 | \title{Check if object is \code{sea}} 6 | \usage{ 7 | is_sea(x) 8 | } 9 | \arguments{ 10 | \item{x}{An R object.} 11 | } 12 | \value{ 13 | Boolean indicating whether \code{x} is a \code{sea} object. 14 | } 15 | \description{ 16 | Check if object is \code{sea} 17 | } 18 | \seealso{ 19 | \code{\link[=sea]{sea()}} creates a \code{sea} object. 20 | } 21 | -------------------------------------------------------------------------------- /man/is.sea.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sea.R 3 | \name{is.sea} 4 | \alias{is.sea} 5 | \title{Alias to \code{\link[=is_sea]{is_sea()}}} 6 | \usage{ 7 | is.sea(x) 8 | } 9 | \arguments{ 10 | \item{x}{An R object.} 11 | } 12 | \value{ 13 | Boolean indicating whether \code{x} is a \code{sea} object. 14 | } 15 | \description{ 16 | Alias to \code{\link[=is_sea]{is_sea()}} 17 | } 18 | \seealso{ 19 | \code{\link[=sea]{sea()}} creates a \code{sea} object. 20 | } 21 | -------------------------------------------------------------------------------- /man/lgr2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{lgr2} 5 | \alias{lgr2} 6 | \title{Los Griegos Peak plot2 fire-history data} 7 | \format{ 8 | An fhx object with 26 series from 1366 to 2012 CE. 9 | } 10 | \usage{ 11 | lgr2 12 | } 13 | \description{ 14 | An \code{fhx} object with fire-history data from Los Griegos Peak, New Mexico. 15 | } 16 | \seealso{ 17 | \link{lgr2_meta} Los Griegos Peak metadata. 18 | } 19 | \keyword{datasets} 20 | -------------------------------------------------------------------------------- /burnr.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | LineEndingConversion: Posix 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageInstallArgs: --no-multiarch --with-keep.source 22 | PackageRoxygenize: rd,collate,namespace 23 | -------------------------------------------------------------------------------- /man/pme.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{pme} 5 | \alias{pme} 6 | \title{Pajarito Mountain East fire-history data} 7 | \format{ 8 | An \code{fhx} object with 17 series from 1702 to 1993 CE. 9 | } 10 | \source{ 11 | https://www1.ncdc.noaa.gov/pub/data/paleo/firehistory/firescar/northamerica/uspme001.fhx 12 | } 13 | \usage{ 14 | pme 15 | } 16 | \description{ 17 | An \code{fhx} object with fire-history data. 18 | } 19 | \keyword{datasets} 20 | -------------------------------------------------------------------------------- /man/pmr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{pmr} 5 | \alias{pmr} 6 | \title{Pajarito Mountain Ridge fire-history data} 7 | \format{ 8 | An \code{fhx} object with 23 series from 1626 to 1993 CE. 9 | } 10 | \source{ 11 | https://www1.ncdc.noaa.gov/pub/data/paleo/firehistory/firescar/northamerica/uspmr001.fhx 12 | } 13 | \usage{ 14 | pmr 15 | } 16 | \description{ 17 | An \code{fhx} object with fire-history data. 18 | } 19 | \keyword{datasets} 20 | -------------------------------------------------------------------------------- /man/pmw.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{pmw} 5 | \alias{pmw} 6 | \title{Pajarito Mountain West fire-history data} 7 | \format{ 8 | An \code{fhx} object with 11 series from 1617 to 1993 CE. 9 | } 10 | \source{ 11 | https://www1.ncdc.noaa.gov/pub/data/paleo/firehistory/firescar/northamerica/uspmw001.fhx 12 | } 13 | \usage{ 14 | pmw 15 | } 16 | \description{ 17 | An \code{fhx} object with fire-history data. 18 | } 19 | \keyword{datasets} 20 | -------------------------------------------------------------------------------- /man/is_intervals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/intervals.R 3 | \name{is_intervals} 4 | \alias{is_intervals} 5 | \title{Check if object is fire \code{intervals}} 6 | \usage{ 7 | is_intervals(x) 8 | } 9 | \arguments{ 10 | \item{x}{An R object.} 11 | } 12 | \value{ 13 | Boolean indicating whether x is an \code{intervals} object. 14 | } 15 | \description{ 16 | Check if object is fire \code{intervals} 17 | } 18 | \seealso{ 19 | \code{\link[=intervals]{intervals()}} creates an \code{intervals} object. 20 | } 21 | -------------------------------------------------------------------------------- /man/is.intervals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/intervals.R 3 | \name{is.intervals} 4 | \alias{is.intervals} 5 | \title{Alias to \code{\link[=is_intervals]{is_intervals()}}} 6 | \usage{ 7 | is.intervals(x) 8 | } 9 | \arguments{ 10 | \item{x}{An R object.} 11 | } 12 | \value{ 13 | Boolean indicating whether x is an \code{intervals} object. 14 | } 15 | \description{ 16 | Alias to \code{\link[=is_intervals]{is_intervals()}} 17 | } 18 | \seealso{ 19 | \code{\link[=intervals]{intervals()}} creates an \code{intervals} object. 20 | } 21 | -------------------------------------------------------------------------------- /man/sample_depth.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{sample_depth} 4 | \alias{sample_depth} 5 | \title{Calculate the sample depth of an \code{fhx} object} 6 | \usage{ 7 | sample_depth(x) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | } 12 | \value{ 13 | A data frame containing the years and number of observations. 14 | } 15 | \description{ 16 | Calculate the sample depth of an \code{fhx} object 17 | } 18 | \seealso{ 19 | \code{\link[=series_stats]{series_stats()}} basic statistics for series in an \code{fhx} object. 20 | } 21 | -------------------------------------------------------------------------------- /man/summary.fhx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{summary.fhx} 4 | \alias{summary.fhx} 5 | \title{Summary of \code{fhx} object} 6 | \usage{ 7 | \method{summary}{fhx}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{An \code{fhx} object.} 11 | 12 | \item{...}{Additional arguments that are tossed out.} 13 | } 14 | \value{ 15 | A \code{summary.fhx} object. 16 | } 17 | \description{ 18 | Summary of \code{fhx} object 19 | } 20 | \seealso{ 21 | \code{\link[=series_stats]{series_stats()}} basic statistics for series in an \code{fhx} object. 22 | } 23 | -------------------------------------------------------------------------------- /man/first_year.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{first_year} 4 | \alias{first_year} 5 | \title{First (earliest) year of an \code{fhx} object} 6 | \usage{ 7 | first_year(x) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | } 12 | \value{ 13 | The minimum or first year of series in \code{x}. 14 | } 15 | \description{ 16 | First (earliest) year of an \code{fhx} object 17 | } 18 | \seealso{ 19 | \itemize{ 20 | \item \code{\link[=last_year]{last_year()}} get last year of \code{fhx} object. 21 | \item \code{\link[=series_stats]{series_stats()}} basic statistics for series in an \code{fhx} object. 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /man/plot.intervals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/intervals.R 3 | \name{plot.intervals} 4 | \alias{plot.intervals} 5 | \title{Plot a fire \code{intervals} object} 6 | \usage{ 7 | \method{plot}{intervals}(...) 8 | } 9 | \arguments{ 10 | \item{...}{Arguments passed to \code{\link[=plot_intervals_dist]{plot_intervals_dist()}}.} 11 | } 12 | \description{ 13 | Plot a fire \code{intervals} object 14 | } 15 | \examples{ 16 | data(pgm) 17 | interv <- intervals(composite(pgm)) 18 | 19 | plot(interv, binwidth = 5) 20 | } 21 | \seealso{ 22 | \code{\link[=plot_intervals_dist]{plot_intervals_dist()}} plot \code{intervals} distributions. 23 | } 24 | -------------------------------------------------------------------------------- /man/lgr2_meta.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{lgr2_meta} 5 | \alias{lgr2_meta} 6 | \title{Metadata for the Los Griegos Peak fire-history dataset} 7 | \format{ 8 | A \code{data.frame} with 26 rows and 2 variables: 9 | \itemize{ 10 | \item "TreeID": Name of tree series. 11 | \item "SpeciesID": Abbreviated tree species 12 | } 13 | } 14 | \usage{ 15 | lgr2_meta 16 | } 17 | \description{ 18 | A data frame with species information for the Los Griegos Peak plot2 19 | fire-history dataset (\link{lgr2}). 20 | } 21 | \seealso{ 22 | \link{lgr2} Log Griegos Peak fire-history data. 23 | } 24 | \keyword{datasets} 25 | -------------------------------------------------------------------------------- /man/count_scar.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{count_scar} 4 | \alias{count_scar} 5 | \title{Number of scar events in an \code{fhx} object} 6 | \usage{ 7 | count_scar(x) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | } 12 | \value{ 13 | The number of fire scar events in \code{x} 14 | } 15 | \description{ 16 | Number of scar events in an \code{fhx} object 17 | } 18 | \seealso{ 19 | \itemize{ 20 | \item \code{\link[=count_injury]{count_injury()}} Count the injuries in an \code{fhx} object. 21 | \item \code{\link[=series_stats]{series_stats()}} basic statistics for series in an \code{fhx} object. 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /man/count_injury.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{count_injury} 4 | \alias{count_injury} 5 | \title{Number of injury events in an \code{fhx} object} 6 | \usage{ 7 | count_injury(x) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | } 12 | \value{ 13 | The number of injury events in \code{x} 14 | } 15 | \description{ 16 | Number of injury events in an \code{fhx} object 17 | } 18 | \seealso{ 19 | \itemize{ 20 | \item \code{\link[=count_scar]{count_scar()}} Count the injuries in an \code{fhx} object. 21 | \item \code{\link[=series_stats]{series_stats()}} basic statistics for series in an \code{fhx} object. 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /man/count_recording.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{count_recording} 4 | \alias{count_recording} 5 | \title{Number of recording years in an \code{fhx} object} 6 | \usage{ 7 | count_recording(x, injury_event = FALSE) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | 12 | \item{injury_event}{Boolean indicating whether injuries should be considered 13 | event.} 14 | } 15 | \value{ 16 | The number of recording events in \code{x}. 17 | } 18 | \description{ 19 | Number of recording years in an \code{fhx} object 20 | } 21 | \seealso{ 22 | \code{\link[=series_stats]{series_stats()}} basic statistics for series in an \code{fhx} object. 23 | } 24 | -------------------------------------------------------------------------------- /man/write_fhx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/io.R 3 | \name{write_fhx} 4 | \alias{write_fhx} 5 | \title{Write an \code{fhx} object to a new FHX2 file} 6 | \usage{ 7 | write_fhx(x, fname = "") 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | 12 | \item{fname}{Output filename.} 13 | } 14 | \description{ 15 | Write an \code{fhx} object to a new FHX2 file 16 | } 17 | \examples{ 18 | \dontrun{ 19 | data(lgr2) 20 | write_fhx(lgr2, "afile.fhx") 21 | } 22 | 23 | } 24 | \seealso{ 25 | \itemize{ 26 | \item \code{\link[=write.csv]{write.csv()}} to write a CSV file. Also works on \code{fhx} objects. 27 | \item \code{\link[=read_fhx]{read_fhx()}} to read an FHX2 file. 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /man/last_year.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{last_year} 4 | \alias{last_year} 5 | \title{Last (most recent) year of an \code{fhx} object} 6 | \usage{ 7 | last_year(x) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | } 12 | \value{ 13 | The maximum or last year of series in \code{x}. \code{NA} will be returned if 14 | \code{NA} is in \code{x$year}. 15 | } 16 | \description{ 17 | Last (most recent) year of an \code{fhx} object 18 | } 19 | \seealso{ 20 | \itemize{ 21 | \item \code{\link[=first_year]{first_year()}} get first year of \code{fhx} object. 22 | \item \code{\link[=series_stats]{series_stats()}} basic statistics for series in an \code{fhx} object. 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /man/is_fhx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{is_fhx} 4 | \alias{is_fhx} 5 | \title{Check if object is \code{fhx}.} 6 | \usage{ 7 | is_fhx(x) 8 | } 9 | \arguments{ 10 | \item{x}{An object.} 11 | } 12 | \value{ 13 | Boolean indicating whether \code{x} is an \code{fhx} object. 14 | } 15 | \description{ 16 | Check if object is \code{fhx}. 17 | } 18 | \examples{ 19 | data(lgr2) 20 | is_fhx(lgr2) 21 | 22 | } 23 | \seealso{ 24 | \itemize{ 25 | \item \code{\link[=fhx]{fhx()}} constructs an \code{fhx} object. 26 | \item \code{\link[=as_fhx]{as_fhx()}} casts data frame-like object into an \code{fhx} object. 27 | \item \code{\link[=+.fhx]{+.fhx()}} concatenate multiple \code{fhx} objects together. 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /man/print.intervals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/intervals.R 3 | \name{print.intervals} 4 | \alias{print.intervals} 5 | \title{Print a fire \code{intervals} object} 6 | \usage{ 7 | \method{print}{intervals}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{intervals} object.} 11 | 12 | \item{...}{Additional arguments that are tossed.} 13 | } 14 | \description{ 15 | Print a fire \code{intervals} object 16 | } 17 | \examples{ 18 | data(pgm) 19 | interv <- intervals(composite(pgm)) 20 | print(interv) 21 | 22 | # Note, you can also catch the printed table: 23 | summary_stats <- print(interv) 24 | 25 | } 26 | \seealso{ 27 | \code{\link[=intervals]{intervals()}} to create a fire \code{intervals} object. 28 | } 29 | -------------------------------------------------------------------------------- /man/yearly_recording.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{yearly_recording} 4 | \alias{yearly_recording} 5 | \title{Count the number of recording series for each year in an \code{fhx} object} 6 | \usage{ 7 | yearly_recording(x, injury_event = FALSE) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | 12 | \item{injury_event}{Boolean indicating whether injuries should be considered 13 | events. Default is \code{FALSE}.} 14 | } 15 | \value{ 16 | A data frame with columns giving the year and recording events count. 17 | } 18 | \description{ 19 | Count the number of recording series for each year in an \code{fhx} object 20 | } 21 | \examples{ 22 | data(lgr2) 23 | yearly_recording(lgr2) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /man/is.fhx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{is.fhx} 4 | \alias{is.fhx} 5 | \title{Alias to \code{\link[=is_fhx]{is_fhx()}}} 6 | \usage{ 7 | is.fhx(x) 8 | } 9 | \arguments{ 10 | \item{x}{An object.} 11 | } 12 | \value{ 13 | Boolean indicating whether \code{x} is an \code{fhx} object. 14 | } 15 | \description{ 16 | Alias to \code{\link[=is_fhx]{is_fhx()}} 17 | } 18 | \examples{ 19 | data(lgr2) 20 | is_fhx(lgr2) 21 | 22 | } 23 | \seealso{ 24 | \itemize{ 25 | \item \code{\link[=fhx]{fhx()}} constructs an \code{fhx} object. 26 | \item \code{\link[=as_fhx]{as_fhx()}} casts data frame-like object into an \code{fhx} object. 27 | \item \code{\link[=+.fhx]{+.fhx()}} concatenate multiple \code{fhx} objects together. 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /man/inner_type.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{inner_type} 4 | \alias{inner_type} 5 | \title{Type of observation in the first (earliest) year of an \code{fhx} object} 6 | \usage{ 7 | inner_type(x) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | } 12 | \value{ 13 | The a factor giving the type of observation in the first observation 14 | of \code{x}. 15 | } 16 | \description{ 17 | Type of observation in the first (earliest) year of an \code{fhx} object 18 | } 19 | \seealso{ 20 | \itemize{ 21 | \item \code{\link[=outer_type]{outer_type()}} get observation type in outer-most year of \code{fhx} object. 22 | \item \code{\link[=series_stats]{series_stats()}} basic statistics for series in an \code{fhx} object. 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /man/outer_type.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{outer_type} 4 | \alias{outer_type} 5 | \title{Type of observation in the last (most recent) year of an \code{fhx} object} 6 | \usage{ 7 | outer_type(x) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | } 12 | \value{ 13 | The a factor giving the type of observation in the last observation 14 | of \code{x}. 15 | } 16 | \description{ 17 | Type of observation in the last (most recent) year of an \code{fhx} object 18 | } 19 | \seealso{ 20 | \itemize{ 21 | \item \code{\link[=inner_type]{inner_type()}} get observation type in inner-most year of \code{fhx} object. 22 | \item \code{\link[=series_stats]{series_stats()}} basic statistics for series in an \code{fhx} object. 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citHeader("To cite burnr in publications use:") 2 | 3 | citEntry(entry = "Article", 4 | title = "burnr: Fire history analysis and graphics in R", 5 | volume = "49", 6 | issn = "1125-7865", 7 | doi = "10.1016/j.dendro.2018.02.005", 8 | journal = "Dendrochronologia", 9 | author = personList(as.person("Steven B. Malevich"), 10 | as.person("Christopher H. Guiterman"), 11 | as.person("Ellis Q. Margolis") 12 | ), 13 | month = "jun", 14 | year = "2018", 15 | pages = "9--15", 16 | 17 | textVersion = 18 | paste("Steven Malevich, Christopher Guiterman, Ellis Margolis (2018).", 19 | "burnr: Fire History Analysis and Graphics in R.", 20 | "Dendrochronologia 49 (June): 9–15.", 21 | "doi: 10.1016/j.dendro.2018.02.005.") 22 | ) 23 | -------------------------------------------------------------------------------- /man/pgm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{pgm} 5 | \alias{pgm} 6 | \title{Peggy Mesa fire-history data} 7 | \format{ 8 | An \code{fhx} object with 41 series from 1555 to 2013 CE. 9 | } 10 | \source{ 11 | Guiterman, Christopher H., Ellis Q. Margolis, and 12 | Thomas W. Swetnam. 2015. "Dendroecological Methods For Reconstructing 13 | High-Severity Fire In Pine-Oak Forests." Tree-Ring Research 71 (2): 67-77. 14 | doi:10.3959/1536-1098-71.2.67. 15 | } 16 | \usage{ 17 | pgm 18 | } 19 | \description{ 20 | An \code{fhx} object with fire-history data from Peggy Mesa. 21 | } 22 | \seealso{ 23 | \itemize{ 24 | \item \link{pgm_meta} Peggy Mesa metadata. 25 | \item \link{pgm_pdsi} PDSI time-series for Peggy Mesa site. 26 | } 27 | } 28 | \keyword{datasets} 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # History files 2 | .Rhistory 3 | .Rapp.history 4 | 5 | # Session Data files 6 | .RData 7 | 8 | # Example code in package build process 9 | *-Ex.R 10 | 11 | # Output files from R CMD build 12 | /*.tar.gz 13 | 14 | # Output files from R CMD check 15 | /*.Rcheck/ 16 | 17 | # RStudio files 18 | .Rproj.user/ 19 | 20 | # produced vignettes 21 | vignettes/*.html 22 | vignettes/*.pdf 23 | 24 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 25 | .httr-oauth 26 | 27 | # knitr and R markdown default cache directories 28 | /*_cache/ 29 | /cache/ 30 | 31 | # Temporary files created by R markdown 32 | *.utf8.md 33 | *.knit.md 34 | 35 | # Shiny token, see https://shiny.rstudio.com/articles/shinyapps.html 36 | rsconnect/ 37 | 38 | .Rproj.user 39 | .Rhistory 40 | *.code-workspace 41 | /.vscode/ 42 | 43 | inst/doc 44 | docs 45 | -------------------------------------------------------------------------------- /man/count_year_span.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{count_year_span} 4 | \alias{count_year_span} 5 | \title{Number of years of an \code{fhx} object} 6 | \usage{ 7 | count_year_span(x) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | } 12 | \value{ 13 | The difference between the first and last observations in the \code{fhx} 14 | object. \code{NA} will be returned if \code{NA} is in \code{x$year}. 15 | } 16 | \description{ 17 | Number of years of an \code{fhx} object 18 | } 19 | \seealso{ 20 | \itemize{ 21 | \item \code{\link[=first_year]{first_year()}} get first year of \code{fhx} object. 22 | \item \code{\link[=last_year]{last_year()}} get last year of \code{fhx} object. 23 | \item \code{\link[=series_stats]{series_stats()}} basic statistics for series in an \code{fhx} object. 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /man/plot.sea.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sea.R 3 | \name{plot.sea} 4 | \alias{plot.sea} 5 | \title{Plot a \code{sea} object} 6 | \usage{ 7 | \method{plot}{sea}(...) 8 | } 9 | \arguments{ 10 | \item{...}{Arguments passed on to \code{\link[=plot_sealags]{plot_sealags()}}.} 11 | } 12 | \description{ 13 | Plot a \code{sea} object 14 | } 15 | \examples{ 16 | \dontrun{ 17 | # Read in the Cook and Krusic (2004; The North American Drought Atlas) 18 | # reconstruction of Palmer Drought Severity Index (PDSI) for the Jemez 19 | # Mountains area (gridpoint 133). 20 | data(pgm_pdsi) 21 | 22 | # Run SEA on Peggy Mesa (pgm) data 23 | data(pgm) 24 | pgm_comp <- composite(pgm) 25 | 26 | pgm_sea <- sea(pgm_pdsi, pgm_comp) 27 | 28 | plot(pgm_sea) 29 | } 30 | } 31 | \seealso{ 32 | \code{\link[=plot_sealags]{plot_sealags()}} handles the plotting for this function. 33 | } 34 | -------------------------------------------------------------------------------- /man/series_mean_interval.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{series_mean_interval} 4 | \alias{series_mean_interval} 5 | \title{Calculate quick mean fire interval of an \code{fhx} object with single series} 6 | \usage{ 7 | series_mean_interval(x, injury_event = FALSE) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object with a single series.} 11 | 12 | \item{injury_event}{Boolean indicating whether injuries should be considered 13 | event.} 14 | } 15 | \value{ 16 | The mean fire interval observed \code{x}. 17 | } 18 | \description{ 19 | You really should be using \code{\link[=intervals]{intervals()}}. 20 | } 21 | \seealso{ 22 | \itemize{ 23 | \item \code{\link[=intervals]{intervals()}} Proper way to do fire-interval analysis of \code{fhx} object. 24 | \item \code{\link[=series_stats]{series_stats()}} basic statistics for series in an \code{fhx} object. 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /man/get_series.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{get_series} 4 | \alias{get_series} 5 | \title{Extract \code{fhx} observations for given series} 6 | \usage{ 7 | get_series(x, s) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | 12 | \item{s}{Character vector of series to extract from \code{x}.} 13 | } 14 | \value{ 15 | An \code{fhx} object. 16 | } 17 | \description{ 18 | Extract \code{fhx} observations for given series 19 | } 20 | \examples{ 21 | data(lgr2) 22 | get_series(lgr2, "LGR46") 23 | 24 | get_series(lgr2, c("LGR41", "LGR46")) 25 | 26 | } 27 | \seealso{ 28 | \itemize{ 29 | \item \code{\link[=series_names]{series_names()}} get all the series in an \code{fhx} object. 30 | \item \code{\link[=get_year]{get_year()}} subset an \code{fhx} object to select years 31 | \item \code{\link[=delete]{delete()}} remove observations from an \code{fhx} object. 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /man/as.fhx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{as.fhx} 4 | \alias{as.fhx} 5 | \title{Alias to \code{\link[=as_fhx]{as_fhx()}}} 6 | \usage{ 7 | as.fhx(x) 8 | } 9 | \arguments{ 10 | \item{x}{A data frame or list-like object to cast. Must have named elements 11 | for "year", "series", and "rec_type".} 12 | } 13 | \value{ 14 | \code{x} cast to an \code{fhx} object. 15 | } 16 | \description{ 17 | Alias to \code{\link[=as_fhx]{as_fhx()}} 18 | } 19 | \examples{ 20 | data(lgr2) 21 | example_dataframe <- as.data.frame(lgr2) 22 | back_to_fhx <- as_fhx(example_dataframe) 23 | 24 | } 25 | \seealso{ 26 | \itemize{ 27 | \item \code{\link[=fhx]{fhx()}} constructs an \code{fhx} object. 28 | \item \code{\link[=is_fhx]{is_fhx()}} test whether object is \code{fhx}. 29 | \item \code{\link[=make_rec_type]{make_rec_type()}} helpful to convert \code{rec_type}-like character vectors to 30 | full facors with proper levels. 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /man/make_rec_type.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{make_rec_type} 4 | \alias{make_rec_type} 5 | \title{Turn character vector into factor with proper \code{fhx} levels} 6 | \usage{ 7 | make_rec_type(x) 8 | } 9 | \arguments{ 10 | \item{x}{A character vector or factor containing one or more rec_type-like 11 | strings. This uses a controlled vocabulary, see \code{burnr:::rec_type_all} 12 | for list of all possible rec_type values.} 13 | } 14 | \value{ 15 | A factor with appropriate \code{fhx} levels. 16 | } 17 | \description{ 18 | Turn character vector into factor with proper \code{fhx} levels 19 | } 20 | \examples{ 21 | make_rec_type("null_year") 22 | 23 | make_rec_type(c("null_year", "late_fs")) 24 | 25 | } 26 | \seealso{ 27 | \itemize{ 28 | \item \code{\link[=fhx]{fhx()}} constructs an \code{fhx} object. 29 | \item \code{\link[=as_fhx]{as_fhx()}} casts data frame-like objects into \code{fhx} objects. 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /man/as_fhx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{as_fhx} 4 | \alias{as_fhx} 5 | \title{Cast data frame or list-like to \code{fhx} object} 6 | \usage{ 7 | as_fhx(x) 8 | } 9 | \arguments{ 10 | \item{x}{A data frame or list-like object to cast. Must have named elements 11 | for "year", "series", and "rec_type".} 12 | } 13 | \value{ 14 | \code{x} cast to an \code{fhx} object. 15 | } 16 | \description{ 17 | Cast data frame or list-like to \code{fhx} object 18 | } 19 | \examples{ 20 | data(lgr2) 21 | example_dataframe <- as.data.frame(lgr2) 22 | back_to_fhx <- as_fhx(example_dataframe) 23 | 24 | } 25 | \seealso{ 26 | \itemize{ 27 | \item \code{\link[=fhx]{fhx()}} constructs an \code{fhx} object. 28 | \item \code{\link[=is_fhx]{is_fhx()}} test whether object is \code{fhx}. 29 | \item \code{\link[=make_rec_type]{make_rec_type()}} helpful to convert \code{rec_type}-like character vectors to 30 | full facors with proper levels. 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /man/plot_sealags.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sea.R 3 | \name{plot_sealags} 4 | \alias{plot_sealags} 5 | \title{Basic SEA lag plot of \code{sea} object} 6 | \usage{ 7 | plot_sealags(x) 8 | } 9 | \arguments{ 10 | \item{x}{A \code{sea} object.} 11 | } 12 | \value{ 13 | A \code{ggplot} object. 14 | } 15 | \description{ 16 | Basic SEA lag plot of \code{sea} object 17 | } 18 | \examples{ 19 | \dontrun{ 20 | # Read in the Cook and Krusic (2004; The North American Drought Atlas) 21 | # reconstruction of Palmer Drought Severity Index (PDSI) for the Jemez 22 | # Mountains area (gridpoint 133). 23 | data(pgm_pdsi) 24 | 25 | # Run SEA on Peggy Mesa (pgm) data 26 | data(pgm) 27 | pgm_comp <- composite(pgm) 28 | 29 | pgm_sea <- sea(pgm_pdsi, pgm_comp) 30 | 31 | plot(pgm_sea) 32 | } 33 | } 34 | \seealso{ 35 | \itemize{ 36 | \item \code{\link[=sea]{sea()}} creates a \code{sea} object. 37 | \item \code{\link[=print.sea]{print.sea()}} prints a pretty summary of a \code{sea} object. 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /man/plus-.fhx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{+.fhx} 4 | \alias{+.fhx} 5 | \title{Concatenate or combine two fhx objects} 6 | \usage{ 7 | \method{+}{fhx}(a, b) 8 | } 9 | \arguments{ 10 | \item{a}{An \code{fhx} object.} 11 | 12 | \item{b}{The \code{fhx} object to be append.} 13 | } 14 | \value{ 15 | An \code{fhx} object with the observations from \code{a} and \code{b}. 16 | } 17 | \description{ 18 | Concatenate or combine two fhx objects 19 | } 20 | \note{ 21 | Throws \code{stop()} if there are duplicate series names in \code{a} and \code{b}. 22 | } 23 | \examples{ 24 | data(lgr2) 25 | data(pgm) 26 | plot(lgr2 + pgm) 27 | 28 | } 29 | \seealso{ 30 | \itemize{ 31 | \item \code{\link[=series_names]{series_names()}} get all the series in an \code{fhx} object. 32 | \item \code{\link[=get_series]{get_series()}} subset an \code{fhx} object to select series. 33 | \item \code{\link[=delete]{delete()}} remove observations from an \code{fhx} object. 34 | \item \code{\link[=sort.fhx]{sort.fhx()}} sort an \code{fhx} object. 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /man/percent_scarred.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{percent_scarred} 4 | \alias{percent_scarred} 5 | \title{Percent scarred time series for \code{fhx} object} 6 | \usage{ 7 | percent_scarred(x, injury_event = FALSE) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | 12 | \item{injury_event}{Boolean indicating whether years with injury events 13 | should be considered as scars. Default is \code{FALSE}.} 14 | } 15 | \value{ 16 | \code{data.frame} with four columns: 17 | \itemize{ 18 | \item "Year": The year. 19 | \item "NumRec": The number of recording trees. 20 | \item "NumScars": Number of fire scars and possibly fire injuries. 21 | \item "PercScarred": The proportion of scars (and possibly injuries) to 22 | non-scar/injury series in the year. 23 | } 24 | } 25 | \description{ 26 | Percent scarred time series for \code{fhx} object 27 | } 28 | \examples{ 29 | data("pgm") 30 | percent_scarred(pgm) 31 | } 32 | \seealso{ 33 | \code{\link[=series_stats]{series_stats()}} basic statistics for series in an \code{fhx} object. 34 | } 35 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | release: 7 | types: [published] 8 | workflow_dispatch: 9 | 10 | name: pkgdown 11 | 12 | jobs: 13 | pkgdown: 14 | runs-on: ubuntu-latest 15 | env: 16 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - uses: r-lib/actions/setup-pandoc@v1 21 | 22 | - uses: r-lib/actions/setup-r@v1 23 | with: 24 | use-public-rspm: true 25 | 26 | - uses: r-lib/actions/setup-r-dependencies@v1 27 | with: 28 | extra-packages: pkgdown 29 | needs: website 30 | 31 | - name: Deploy package 32 | run: | 33 | git config --local user.name "$GITHUB_ACTOR" 34 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 35 | Rscript -e 'pkgdown::deploy_to_branch(new_process = FALSE)' 36 | -------------------------------------------------------------------------------- /man/max.intervals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/intervals.R 3 | \name{max.intervals} 4 | \alias{max.intervals} 5 | \title{Maximum interval in fire \code{intervals}} 6 | \usage{ 7 | \method{max}{intervals}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{intervals} object.} 11 | 12 | \item{...}{Additional arguments passed to \code{\link[=max]{max()}}.} 13 | } 14 | \value{ 15 | Numeric or NA. 16 | } 17 | \description{ 18 | Maximum interval in fire \code{intervals} 19 | } 20 | \seealso{ 21 | \itemize{ 22 | \item \code{\link[=intervals]{intervals()}} to create a fire \code{intervals} object. 23 | \item \code{\link[=mean.intervals]{mean.intervals()}} gets median fire interval. 24 | \item \code{\link[=median.intervals]{median.intervals()}} gets median fire interval. 25 | \item \code{\link[=quantile.intervals]{quantile.intervals()}} get fit distribution quantiles. 26 | \item \code{\link[=min.intervals]{min.intervals()}} gives the minimum fire interval. 27 | \item \code{\link[=print.intervals]{print.intervals()}} prints common fire-interval summary statistics. 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /man/mean.intervals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/intervals.R 3 | \name{mean.intervals} 4 | \alias{mean.intervals} 5 | \title{Fire \code{intervals} arithmetic mean} 6 | \usage{ 7 | \method{mean}{intervals}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{intervals} object.} 11 | 12 | \item{...}{Additional arguments passed to \code{\link[=mean]{mean()}}.} 13 | } 14 | \value{ 15 | Numeric or NA. 16 | } 17 | \description{ 18 | Fire \code{intervals} arithmetic mean 19 | } 20 | \seealso{ 21 | \itemize{ 22 | \item \code{\link[=intervals]{intervals()}} to create a fire \code{intervals} object. 23 | \item \code{\link[=median.intervals]{median.intervals()}} gets median fire interval. 24 | \item \code{\link[=quantile.intervals]{quantile.intervals()}} get fit distribution quantiles. 25 | \item \code{\link[=min.intervals]{min.intervals()}} gives the minimum fire interval. 26 | \item \code{\link[=max.intervals]{max.intervals()}} gives the maximum fire interval. 27 | \item \code{\link[=print.intervals]{print.intervals()}} prints common fire-interval summary statistics. 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /man/median.intervals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/intervals.R 3 | \name{median.intervals} 4 | \alias{median.intervals} 5 | \title{Fire \code{intervals} median} 6 | \usage{ 7 | \method{median}{intervals}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{intervals} object.} 11 | 12 | \item{...}{Additional arguments passed to \code{\link[stats:median]{stats::median()}}.} 13 | } 14 | \value{ 15 | Numeric or NA. 16 | } 17 | \description{ 18 | Fire \code{intervals} median 19 | } 20 | \seealso{ 21 | \itemize{ 22 | \item \code{\link[=intervals]{intervals()}} to create a fire \code{intervals} object. 23 | \item \code{\link[=mean.intervals]{mean.intervals()}} gets mean fire interval. 24 | \item \code{\link[=quantile.intervals]{quantile.intervals()}} get fit distribution quantiles. 25 | \item \code{\link[=min.intervals]{min.intervals()}} gives the minimum fire interval. 26 | \item \code{\link[=max.intervals]{max.intervals()}} gives the maximum fire interval. 27 | \item \code{\link[=print.intervals]{print.intervals()}} prints common fire-interval summary statistics. 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /man/min.intervals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/intervals.R 3 | \name{min.intervals} 4 | \alias{min.intervals} 5 | \title{Minimum interval in fire \code{intervals}} 6 | \usage{ 7 | \method{min}{intervals}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{intervals} object.} 11 | 12 | \item{...}{Additional arguments passed to \code{\link[=min]{min()}}.} 13 | } 14 | \value{ 15 | Numeric or NA. 16 | } 17 | \description{ 18 | Minimum interval in fire \code{intervals} 19 | } 20 | \seealso{ 21 | \itemize{ 22 | \item \code{\link[=intervals]{intervals()}} to create a fire \code{intervals} object. 23 | \item \code{\link[=mean.intervals]{mean.intervals()}} gets median fire interval. 24 | \item \code{\link[=median.intervals]{median.intervals()}} gets median fire interval. 25 | \item \code{\link[=quantile.intervals]{quantile.intervals()}} get fit distribution quantiles. 26 | \item \code{\link[=max.intervals]{max.intervals()}} gives the maximum fire interval. 27 | \item \code{\link[=print.intervals]{print.intervals()}} prints common fire-interval summary statistics. 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: burnr 2 | Title: Forest Fire History Analysis 3 | Version: 0.6.1.9000 4 | Authors@R: c( 5 | person("Steven", "Malevich", email = "sbmalev@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-4752-8190")), 6 | person("Christopher", "Guiterman", role = c("aut", "ctb"), comment = c(ORCID = "0000-0002-9706-9332")), 7 | person("Ellis", "Margolis", role = c("aut"), comment = c(ORCID = "0000-0002-0595-9005"))) 8 | Description: Tools to read, write, parse, and analyze forest fire history data (e.g. FHX). Described in Malevich et al. (2018) . 9 | URL: https://github.com/ltrr-arizona-edu/burnr/ 10 | BugReports: https://github.com/ltrr-arizona-edu/burnr/issues 11 | Depends: 12 | R (>= 3.2) 13 | License: GPL (>= 3) 14 | Encoding: UTF-8 15 | LazyData: true 16 | Suggests: 17 | testthat, 18 | knitr, 19 | rmarkdown 20 | Imports: 21 | forcats, 22 | ggplot2, 23 | MASS, 24 | plyr, 25 | reshape2, 26 | rlang, 27 | stats, 28 | stringr, 29 | tidyr 30 | RoxygenNote: 7.1.2 31 | Roxygen: list(markdown = TRUE) 32 | VignetteBuilder: knitr 33 | -------------------------------------------------------------------------------- /man/read_fhx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/io.R 3 | \name{read_fhx} 4 | \alias{read_fhx} 5 | \title{Read FHX2 file and return an `fhx`` object} 6 | \usage{ 7 | read_fhx(fname, encoding, text) 8 | } 9 | \arguments{ 10 | \item{fname}{Name of target FHX file. Needs to be in format version 2.} 11 | 12 | \item{encoding}{Encoding to use when reading the FHX file. The default is to 13 | use the system default in R.} 14 | 15 | \item{text}{Character string. If \code{fname} is not provided and text is, then 16 | data is read from text using a text connection.} 17 | } 18 | \value{ 19 | An \code{fhx} object, as returned by \code{\link[=fhx]{fhx()}}. 20 | } 21 | \description{ 22 | Read FHX2 file and return an `fhx`` object 23 | } 24 | \examples{ 25 | \dontrun{ 26 | d <- read_fhx("afile.fhx") 27 | } 28 | 29 | } 30 | \seealso{ 31 | \itemize{ 32 | \item \code{\link[=write_fhx]{write_fhx()}} write an \code{fhx} object to a file. 33 | \item \code{\link[=fhx]{fhx()}} create an \code{fhx} object. 34 | \item \code{\link[=as_fhx]{as_fhx()}} cast data frame or similar object to an \code{fhx} object. 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /man/pgm_pdsi.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{pgm_pdsi} 5 | \alias{pgm_pdsi} 6 | \title{Reconstructed PDSI time series for the Peggy Mesa fire-history dataset} 7 | \format{ 8 | A \code{data.frame} with 2004 rows and 1 variables. Row names give the 9 | year for the reconstructed value: 10 | \itemize{ 11 | \item "RECON": The reconstructed PDSI series. 12 | } 13 | } 14 | \source{ 15 | Cook, E. R., and Krusic, P. J. (2004). The North American Drought 16 | Atlas. Retrieved September 13, 2017, from 17 | http://iridl.ldeo.columbia.edu/SOURCES/.LDEO/.TRL/.NADA2004/.pdsi-atlas.html 18 | } 19 | \usage{ 20 | pgm_pdsi 21 | } 22 | \description{ 23 | A tree-ring reconstructed Palmer Drought-Severity Index time series 24 | corresponding to the Peggy Mesa fire-history dataset (\link{pgm}) -- specifically, 25 | the Jemez Mountains area (gridpoint 133). The reconstruction is from The 26 | North American Drought Atlas (Cook and Krusic 2004). 27 | } 28 | \seealso{ 29 | \itemize{ 30 | \item \link{pgm} Peggy Mesa fire-history data. 31 | \item \link{pgm_meta} Peggy Mesa metadata. 32 | } 33 | } 34 | \keyword{datasets} 35 | -------------------------------------------------------------------------------- /man/pgm_meta.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{pgm_meta} 5 | \alias{pgm_meta} 6 | \title{Metadata for the Peggy Mesa fire-history dataset} 7 | \format{ 8 | A \code{data.frame} with 41 rows and 5 variables: 9 | \itemize{ 10 | \item "TreeID": Name of tree series. 11 | \item "SpeciesID": Abbreviated tree species. 12 | \item "Latitude": latitude of tree in decimal degrees. 13 | \item "Longitude": longitude of tree in decimal degrees. 14 | \item "Elevation": tree elevation in meters. 15 | } 16 | } 17 | \source{ 18 | Guiterman, Christopher H., Ellis Q. Margolis, and 19 | Thomas W. Swetnam. 2015. "Dendroecological Methods For Reconstructing 20 | High-Severity Fire In Pine-Oak Forests." Tree-Ring Research 71 (2): 67-77. 21 | doi:10.3959/1536-1098-71.2.67. 22 | } 23 | \usage{ 24 | pgm_meta 25 | } 26 | \description{ 27 | A data frame with species and location information for the Peggy Mesa 28 | fire-history dataset (\link{pgm}). 29 | } 30 | \seealso{ 31 | \itemize{ 32 | \item \link{pgm} Peggy Mesa fire-history data. 33 | \item \link{pgm_pdsi} PDSI time-series for Peggy Mesa site. 34 | } 35 | } 36 | \keyword{datasets} 37 | -------------------------------------------------------------------------------- /tests/testthat/test-intervals.R: -------------------------------------------------------------------------------- 1 | library(burnr) 2 | context("Interval statistics") 3 | 4 | data(pgm) 5 | REF <- composite(pgm) 6 | TEST_INTER <- intervals(REF) 7 | 8 | test_that("Check observed interval mean", { 9 | expect_equal(mean(TEST_INTER), 11.75) 10 | }) 11 | 12 | test_that("Check observed interval median", { 13 | expect_equal(median(TEST_INTER), 10) 14 | }) 15 | 16 | test_that("Check minimum interval", { 17 | expect_equal(min(TEST_INTER), 2) 18 | }) 19 | 20 | test_that("Check maximum interval", { 21 | expect_equal(max(TEST_INTER), 30) 22 | }) 23 | 24 | test_that("quantile.intervals() basic cases", { 25 | expect_equal(quantile(TEST_INTER), 26 | c(3.918526, 10.590013, 20.555245), 27 | tolerance = 1e-3 28 | ) 29 | expect_equal(quantile(TEST_INTER, q = c(0.25)), 30 | c(6.227954), 31 | tolerance = 1e-3 32 | ) 33 | }) 34 | 35 | test_that("The intervals object prints", { 36 | prnt_int <- capture_output(print(TEST_INTER)) 37 | # or 793 chars to support change in ks.test output in R>=6.0.0: 38 | expect_true((nchar(prnt_int) == 793) || (nchar(prnt_int) == 771)) 39 | }) 40 | 41 | test_that("Plotting intervals works", { 42 | p <- plot(TEST_INTER) 43 | expect_is(p, "ggplot") 44 | }) 45 | 46 | -------------------------------------------------------------------------------- /man/get_year.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{get_year} 4 | \alias{get_year} 5 | \title{Extract \code{fhx} observations for given years} 6 | \usage{ 7 | get_year(x, yr) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | 12 | \item{yr}{Numeric vector of year(s) to extract from \code{x}.} 13 | } 14 | \value{ 15 | An \code{fhx} object. 16 | } 17 | \description{ 18 | Extract \code{fhx} observations for given years 19 | } 20 | \examples{ 21 | data(lgr2) 22 | get_year(lgr2, 1806) 23 | 24 | get_year(lgr2, 1805:1807) 25 | 26 | \dontrun{ 27 | # Subsetting before/after a specific year requires a 28 | # call to year_range(). For example, to extract all observations 29 | # prior to 1900, use 30 | get_year(lgr2, year_range(lgr2)[1]:1900) 31 | } 32 | 33 | } 34 | \seealso{ 35 | \itemize{ 36 | \item \code{\link[=year_range]{year_range()}} get earliest and latest year in an \code{fhx} object. 37 | \item \code{\link[=get_series]{get_series()}} subset an \code{fhx} object to select series. 38 | \item \code{\link[=delete]{delete()}} remove observations from an \code{fhx} object. 39 | \item \code{\link[=get_event_years]{get_event_years()}} gets years for various events in an \code{fhx} object. 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /man/plot.fhx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotting.R 3 | \name{plot.fhx} 4 | \alias{plot.fhx} 5 | \title{Plot an \code{fhx} object} 6 | \usage{ 7 | \method{plot}{fhx}(...) 8 | } 9 | \arguments{ 10 | \item{...}{Arguments passed on to \code{\link[=plot_demograph]{plot_demograph()}}.} 11 | } 12 | \description{ 13 | Plot an \code{fhx} object 14 | } 15 | \examples{ 16 | data(lgr2) 17 | plot(lgr2) 18 | 19 | plot(lgr2, ylabels = FALSE, plot_legend = TRUE) 20 | 21 | data(lgr2_meta) 22 | # With color showing species. 23 | plot(lgr2, 24 | color_group = lgr2_meta$SpeciesID, 25 | color_id = lgr2_meta$TreeID, 26 | plot_legend = TRUE 27 | ) 28 | # With facets for each species. 29 | plot(lgr2, 30 | facet_group = lgr2_meta$SpeciesID, 31 | facet_id = lgr2_meta$TreeID, 32 | plot_legend = TRUE 33 | ) 34 | 35 | # Append annotation onto a ggplot object. 36 | require(ggplot2) 37 | p <- plot_demograph(lgr2, 38 | color_group = lgr2_meta$SpeciesID, 39 | color_id = lgr2_meta$TreeID 40 | ) 41 | # Add transparent box as annotation to plot. 42 | p + annotate("rect", 43 | xmin = 1750, xmax = 1805, 44 | ymin = 3.5, ymax = 13.5, alpha = 0.2 45 | ) 46 | } 47 | \seealso{ 48 | \code{\link[=plot_demograph]{plot_demograph()}} is what does the actual plotting. 49 | } 50 | -------------------------------------------------------------------------------- /man/year_range.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{year_range} 4 | \alias{year_range} 5 | \title{Range of years in an \code{fhx} object} 6 | \usage{ 7 | year_range(x) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | } 12 | \value{ 13 | A numeric vector or \code{NULL}. 14 | } 15 | \description{ 16 | Range of years in an \code{fhx} object 17 | } 18 | \examples{ 19 | data(lgr2) 20 | year_range(lgr2) 21 | 22 | } 23 | \seealso{ 24 | \itemize{ 25 | \item \code{\link[=series_names]{series_names()}} get all the series in an \code{fhx} object. 26 | \item \code{\link[=get_year]{get_year()}} subset an \code{fhx} object to select years. 27 | \item \code{\link[=get_series]{get_series()}} subset an \code{fhx} object to select series. 28 | \item \code{\link[=get_event_years]{get_event_years()}} gets years for various events in an \code{fhx} object. 29 | \item \code{\link[=count_event_position]{count_event_position()}} count the number of different events in an \code{fhx} 30 | object. 31 | \item \code{\link[=yearly_recording]{yearly_recording()}} count the number of "recording" events in each year 32 | of an \code{fhx} object. 33 | \item \code{\link[=series_stats]{series_stats()}} basic summary stats for an \code{fhx} object. 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /man/print.sea.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sea.R 3 | \name{print.sea} 4 | \alias{print.sea} 5 | \title{Print a \code{sea} object.} 6 | \usage{ 7 | \method{print}{sea}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{A \code{sea} object.} 11 | 12 | \item{...}{Additional arguments that are tossed.} 13 | } 14 | \description{ 15 | Print a \code{sea} object. 16 | } 17 | \examples{ 18 | \dontrun{ 19 | # Read in the Cook and Krusic (2004; The North American Drought Atlas) 20 | # reconstruction of Palmer Drought Severity Index (PDSI) for the Jemez 21 | # Mountains area (gridpoint 133). 22 | target_url <- paste0( 23 | "http://iridl.ldeo.columbia.edu", 24 | "/SOURCES/.LDEO/.TRL/.NADA2004", 25 | "/pdsiatlashtml/pdsiwebdata/1050w_350n_133.txt" 26 | ) 27 | pdsi <- read.table(target_url, header = TRUE, row.names = 1) 28 | pdsi <- subset(pdsi, select = "RECON") 29 | 30 | # Run SEA on Peggy Mesa (pgm) data 31 | data(pgm) 32 | pgm_comp <- composite(pgm) 33 | 34 | pgm_sea <- sea(pdsi, pgm_comp) 35 | 36 | # See basic results: 37 | print(pgm_sea) 38 | 39 | # Basic plot: 40 | plot(pgm_sea) 41 | } 42 | 43 | } 44 | \seealso{ 45 | \itemize{ 46 | \item \code{\link[=sea]{sea()}} creates a \code{sea} object. 47 | \item \code{\link[=plot_sealags]{plot_sealags()}} basic plot of \code{sea} object lags. 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /man/series_names.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{series_names} 4 | \alias{series_names} 5 | \title{Get \code{fhx} series names} 6 | \usage{ 7 | series_names(x) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | } 12 | \value{ 13 | A character vector or \code{NULL}. 14 | } 15 | \description{ 16 | Get \code{fhx} series names 17 | } 18 | \examples{ 19 | data(lgr2) 20 | series_names(lgr2) 21 | 22 | } 23 | \seealso{ 24 | \itemize{ 25 | \item \code{\link[=series_names]{series_names()}} get all the series in an \code{fhx} object. 26 | \item \code{\link[=get_year]{get_year()}} subset an \code{fhx} object to select years. 27 | \item \code{\link[=year_range]{year_range()}} get earliest and latest year in an \code{fhx} object. 28 | \item \code{\link[=get_series]{get_series()}} subset an \code{fhx} object to select series. 29 | \item \code{\link[=get_event_years]{get_event_years()}} gets years for various events in an \code{fhx} object. 30 | \item \code{\link[=count_event_position]{count_event_position()}} count the number of different events in an \code{fhx} 31 | object. 32 | \item \code{\link[=yearly_recording]{yearly_recording()}} count the number of "recording" events in each year 33 | of an \code{fhx} object. 34 | \item \code{\link[=series_stats]{series_stats()}} basic summary stats for an \code{fhx} object. 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method("+",fhx) 4 | S3method(max,intervals) 5 | S3method(mean,intervals) 6 | S3method(median,intervals) 7 | S3method(min,intervals) 8 | S3method(plot,fhx) 9 | S3method(plot,intervals) 10 | S3method(plot,sea) 11 | S3method(print,intervals) 12 | S3method(print,sea) 13 | S3method(quantile,intervals) 14 | S3method(sort,fhx) 15 | S3method(summary,fhx) 16 | export(as.fhx) 17 | export(as_fhx) 18 | export(composite) 19 | export(count_event_position) 20 | export(count_injury) 21 | export(count_recording) 22 | export(count_scar) 23 | export(count_year_span) 24 | export(delete) 25 | export(fhx) 26 | export(first_year) 27 | export(get_event_years) 28 | export(get_series) 29 | export(get_year) 30 | export(inner_type) 31 | export(intervals) 32 | export(is.fhx) 33 | export(is.intervals) 34 | export(is.sea) 35 | export(is_fhx) 36 | export(is_intervals) 37 | export(is_sea) 38 | export(last_year) 39 | export(make_rec_type) 40 | export(outer_type) 41 | export(percent_scarred) 42 | export(plot_demograph) 43 | export(plot_intervals_dist) 44 | export(plot_sealags) 45 | export(read_fhx) 46 | export(sample_depth) 47 | export(sea) 48 | export(series_mean_interval) 49 | export(series_names) 50 | export(series_stats) 51 | export(write_fhx) 52 | export(year_range) 53 | export(yearly_recording) 54 | importFrom(rlang,.data) 55 | importFrom(stats,median) 56 | importFrom(stats,quantile) 57 | importFrom(tidyr,pivot_wider) 58 | -------------------------------------------------------------------------------- /man/sort.fhx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{sort.fhx} 4 | \alias{sort.fhx} 5 | \title{Sort the series names of \code{fhx} object by the earliest or latest year} 6 | \usage{ 7 | \method{sort}{fhx}(x, decreasing = FALSE, sort_by = "first_year", ...) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object to sort.} 11 | 12 | \item{decreasing}{Logical. Decreasing sorting? Defaults to \code{FALSE}.} 13 | 14 | \item{sort_by}{Either "first_year" or "last_year". Designates the inner or 15 | outer year for sorting. Defaults to "first_year"} 16 | 17 | \item{...}{Additional arguments that fall off the face of the universe.} 18 | } 19 | \value{ 20 | A copy of \code{x} with reordered series. 21 | } 22 | \description{ 23 | Sort the series names of \code{fhx} object by the earliest or latest year 24 | } 25 | \examples{ 26 | data(lgr2) 27 | plot(sort(lgr2, decreasing = TRUE)) 28 | plot(sort(lgr2, sort_by = "last_year")) 29 | 30 | } 31 | \seealso{ 32 | \itemize{ 33 | \item \code{\link[=fhx]{fhx()}} constructs an \code{fhx} object. 34 | \item \code{\link[=as_fhx]{as_fhx()}} casts data frame-like object into an \code{fhx} object. 35 | \item \code{\link[=series_names]{series_names()}} get all the series in an \code{fhx} object. 36 | \item \code{\link[=delete]{delete()}} remove observations from an \code{fhx} object. 37 | \item \code{\link[=+.fhx]{+.fhx()}} concatenate multiple \code{fhx} objects together. 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/master/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: macOS-latest, r: 'release'} 22 | - {os: windows-latest, r: 'release'} 23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 24 | - {os: ubuntu-latest, r: 'release'} 25 | - {os: ubuntu-latest, r: 'oldrel-1'} 26 | 27 | env: 28 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 29 | R_KEEP_PKG_SOURCE: yes 30 | 31 | steps: 32 | - uses: actions/checkout@v2 33 | 34 | - uses: r-lib/actions/setup-pandoc@v1 35 | 36 | - uses: r-lib/actions/setup-r@v1 37 | with: 38 | r-version: ${{ matrix.config.r }} 39 | http-user-agent: ${{ matrix.config.http-user-agent }} 40 | use-public-rspm: true 41 | 42 | - uses: r-lib/actions/setup-r-dependencies@v1 43 | with: 44 | extra-packages: rcmdcheck 45 | 46 | - uses: r-lib/actions/check-r-package@v1 47 | -------------------------------------------------------------------------------- /man/delete.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{delete} 4 | \alias{delete} 5 | \title{Remove series or years from an \code{fhx} object} 6 | \usage{ 7 | delete(x, s, yr) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{fhx} object.} 11 | 12 | \item{s}{Character vector of series to remove from \code{x}.} 13 | 14 | \item{yr}{Integer vector of years to remove from \code{x}.} 15 | } 16 | \value{ 17 | An fhx \code{object} with observations removed. 18 | } 19 | \description{ 20 | Remove series or years from an \code{fhx} object 21 | } 22 | \details{ 23 | You can combine \code{s} and \code{yr} to specify years within select series to remove. 24 | } 25 | \examples{ 26 | data(lgr2) 27 | plot(delete(lgr2, s = "LGR46")) 28 | 29 | plot(delete(lgr2, yr = 1300:1550)) 30 | 31 | } 32 | \seealso{ 33 | \itemize{ 34 | \item \code{\link[=fhx]{fhx()}} constructs an \code{fhx} object. 35 | \item \code{\link[=as_fhx]{as_fhx()}} casts data frame-like object into an \code{fhx} object. 36 | \item \code{\link[=series_names]{series_names()}} get all the series in an \code{fhx} object. 37 | \item \code{\link[=year_range]{year_range()}} get earliest and latest year in an \code{fhx} object. 38 | \item \code{\link[=get_year]{get_year()}} subset an \code{fhx} object to select years. 39 | \item \code{\link[=get_series]{get_series()}} subset an \code{fhx} object to select series. 40 | \item \code{\link[=get_event_years]{get_event_years()}} gets years for various events in an \code{fhx} object. 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /man/quantile.intervals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/intervals.R 3 | \name{quantile.intervals} 4 | \alias{quantile.intervals} 5 | \title{Fit distribution quantiles to fire \code{intervals}} 6 | \usage{ 7 | \method{quantile}{intervals}(x, q = c(0.125, 0.5, 0.875), ...) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{intervals} object.} 11 | 12 | \item{q}{Vector giving the desired quantiles.} 13 | 14 | \item{...}{Additional arguments passed to the \code{\link[=quantile]{quantile()}} method for the 15 | fit distribution.} 16 | } 17 | \description{ 18 | Fit distribution quantiles to fire \code{intervals} 19 | } 20 | \examples{ 21 | data(pgm) 22 | intervs <- intervals(composite(pgm)) 23 | quantile(intervs) 24 | 25 | # Or you can pass in your own quantiles: 26 | quantile(intervs, q = c(0.25, 0.5, 0.75)) 27 | } 28 | \seealso{ 29 | \itemize{ 30 | \item \code{\link[=intervals]{intervals()}} to create a fire \code{intervals} object. 31 | \item \code{\link[=mean.intervals]{mean.intervals()}} gets median fire interval. 32 | \item \code{\link[=median.intervals]{median.intervals()}} gets median fire interval. 33 | \item \code{\link[=quantile.intervals]{quantile.intervals()}} get fit distribution quantiles. 34 | \item \code{\link[=min.intervals]{min.intervals()}} gives the minimum fire interval. 35 | \item \code{\link[=max.intervals]{max.intervals()}} gives the maximum fire interval. 36 | \item \code{\link[=print.intervals]{print.intervals()}} prints common fire-interval summary statistics. 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /man/plot_intervals_dist.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/intervals.R 3 | \name{plot_intervals_dist} 4 | \alias{plot_intervals_dist} 5 | \title{Basic fire \code{intervals} distribution plot} 6 | \usage{ 7 | plot_intervals_dist(x, binwidth = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{An \code{intervals} object, from \code{\link[=intervals]{intervals()}}.} 11 | 12 | \item{binwidth}{The width of the bins. Can be specified as a numeric value 13 | or as a function that calculates width from unscaled x. Here, "unscaled x" 14 | refers to the original x values in the data, before application of any 15 | scale transformation. When specifying a function along with a grouping 16 | structure, the function will be called once per group. 17 | The default is to use the number of bins in \code{bins}, 18 | covering the range of the data. You should always override 19 | this value, exploring multiple widths to find the best to illustrate the 20 | stories in your data. 21 | 22 | The bin width of a date variable is the number of days in each time; the 23 | bin width of a time variable is the number of seconds.} 24 | } 25 | \value{ 26 | A ggplot object. 27 | } 28 | \description{ 29 | Basic fire \code{intervals} distribution plot 30 | } 31 | \seealso{ 32 | \itemize{ 33 | \item \code{\link[=intervals]{intervals()}} to create a fire \code{intervals} object. 34 | \item \code{\link[=mean.intervals]{mean.intervals()}} gets mean fire interval. 35 | \item \code{\link[=median.intervals]{median.intervals()}} gets median fire interval. 36 | \item \code{\link[=quantile.intervals]{quantile.intervals()}} get fit distribution quantiles. 37 | \item \code{\link[=min.intervals]{min.intervals()}} gives the minimum fire interval. 38 | \item \code{\link[=max.intervals]{max.intervals()}} gives the maximum fire interval. 39 | \item \code{\link[=print.intervals]{print.intervals()}} prints common fire-interval summary statistics. 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/testthat/test-plotting.R: -------------------------------------------------------------------------------- 1 | library(burnr) 2 | data(lgr2) 3 | data(lgr2_meta) 4 | context("FHX plotting") 5 | 6 | TEST_FHX <- lgr2 7 | TEST_META <- lgr2_meta 8 | 9 | test_that("plot_demograph() gets ggplot on fhx object", { 10 | p <- plot_demograph(TEST_FHX) 11 | expect_is(p, "ggplot") 12 | }) 13 | 14 | test_that("plot_demograph() gets ggplot on 50yr fhx object", { 15 | p <- plot_demograph(get_year(TEST_FHX, seq(1800, 1850))) 16 | expect_is(p, "ggplot") 17 | }) 18 | 19 | test_that("plot_demograph() gets ggplot with composite_rug", { 20 | p <- plot_demograph(TEST_FHX, composite_rug = TRUE) 21 | expect_is(p, "ggplot") 22 | }) 23 | 24 | test_that("plot_demograph() gets ggplot with facet", { 25 | p <- plot_demograph(TEST_FHX, 26 | facet_group = TEST_META$SpeciesID, # nolint 27 | facet_id = TEST_META$TreeID # nolint 28 | ) 29 | expect_is(p, "ggplot") 30 | }) 31 | 32 | test_that("plot_demograph() gets ggplot with grid facet", { 33 | p <- plot_demograph(TEST_FHX, 34 | facet_group = TEST_META$SpeciesID, # nolint 35 | facet_id = TEST_META$TreeID, # nolint 36 | facet_type = "grid" 37 | ) 38 | expect_is(p, "ggplot") 39 | }) 40 | 41 | test_that("plot_demograph() gets ggplot with wrap facet", { 42 | p <- plot_demograph(TEST_FHX, 43 | facet_group = TEST_META$SpeciesID, # nolint 44 | facet_id = TEST_META$TreeID, # nolint 45 | facet_type = "wrap" 46 | ) 47 | expect_is(p, "ggplot") 48 | }) 49 | 50 | test_that("plot_demograph() gets ggplot with color", { 51 | p <- plot_demograph(TEST_FHX, 52 | color_group = TEST_META$SpeciesID, # nolint 53 | color_id = TEST_META$TreeID # nolint 54 | ) 55 | expect_is(p, "ggplot") 56 | }) 57 | 58 | test_that("plot() method gets ggplot on fhx object", { 59 | # Note we're directing output to a temp jpg file. 60 | tmpfile <- tempfile() 61 | 62 | jpeg(tmpfile) 63 | p <- plot(TEST_FHX) 64 | dev.off() 65 | 66 | expect_is(p, "ggplot") 67 | unlink(tmpfile) 68 | }) 69 | -------------------------------------------------------------------------------- /data-raw/pgm_meta.csv: -------------------------------------------------------------------------------- 1 | TreeID,SpeciesID,Latitude,Longitude,Elevation 2 | PGM1,PIPO,35.723976,-106.79524,2282.11499 3 | PGM10,PIPO,35.725781,-106.798958,2298.150635 4 | PGM11,JUSC,35.725815,-106.799201,2300.069824 5 | PGM12,PIPO,35.726528,-106.79993,2300.006348 6 | PGM13,QUGA,35.725956,-106.800621,2318.192871 7 | PGM14,QUGA,35.725956,-106.800621,2318.192871 8 | PGM15,PIPO,35.725025,-106.800798,2332.320312 9 | PGM16,QUGA,35.724777,-106.80155,2342.432129 10 | PGM17,QUGA,35.724777,-106.80155,2342.432129 11 | PGM18,QUGA,35.724777,-106.80155,2342.432129 12 | PGM19,QUGA,35.723732,-106.800657,2343.048096 13 | PGM2,PSME,35.72395,-106.795352,2288.078125 14 | PGM20,QUGA,35.723732,-106.800657,2343.048096 15 | PGM21,QUGA,35.72445,-106.799085,2316.615967 16 | PGM22,QUGA,35.72445,-106.799085,2316.615967 17 | PGM23,PIPO,35.721682,-106.798423,2334.536377 18 | PGM25,PIPO,35.721733,-106.797788,2328.45459 19 | PGM26,QUGA,35.721606,-106.798017,2332.539307 20 | PGM27,QUGA,35.723119,-106.797994,2327.680908 21 | PGM28,QUGA,35.723119,-106.797994,2327.680908 22 | PGM29,QUGA,35.723601,-106.796104,2302.263184 23 | PGM3,QUGA,35.723944,-106.79534,2288.312744 24 | PGM30,QUGA,35.723601,-106.796104,2302.263184 25 | PGM31,JUSC,35.721515,-106.79214,2248.833252 26 | PGM32,PIPO,35.721412,-106.792163,2262.830322 27 | PGM33,QUGA,35.72158,-106.794063,2279.464111 28 | PGM34,QUGA,35.72158,-106.794063,2279.464111 29 | PGM35,PSME,35.721225,-106.794511,2289.895752 30 | PGM36,PIED,35.72117,-106.794529,2290.043945 31 | PGM37,QUGA,35.72102,-106.794829,2296.327148 32 | PGM38,QUGA,35.72102,-106.794829,2296.327148 33 | PGM39,PIPO,35.721229,-106.796412,2311.219482 34 | PGM40,PIPO,35.722477,-106.796107,2298.864746 35 | PGM42,QUGA,35.722677,-106.796033,2297.010498 36 | PGM43,QUGA,35.722677,-106.796033,2297.010498 37 | PGM44,QUGA,35.722831,-106.794998,2280.291016 38 | PGM45,QUGA,35.722831,-106.794998,2280.291016 39 | PGM5,PIPO,35.723982,-106.795458,2288.864746 40 | PGM6,PIPO,35.72417,-106.795475,2286.700439 41 | PGM7,PIPO,35.723762,-106.795148,2289.906982 42 | PGM9,QUGA,35.724234,-106.795521,2286.273682 43 | -------------------------------------------------------------------------------- /man/get_event_years.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{get_event_years} 4 | \alias{get_event_years} 5 | \title{Get years with events for an \code{fhx} object} 6 | \usage{ 7 | get_event_years( 8 | x, 9 | scar_event = TRUE, 10 | injury_event = FALSE, 11 | custom_grep_str = NULL 12 | ) 13 | } 14 | \arguments{ 15 | \item{x}{An \code{fhx} object.} 16 | 17 | \item{scar_event}{Boolean indicating whether years with scar events should be 18 | returned. Default is \code{TRUE}.} 19 | 20 | \item{injury_event}{Boolean indicating whether years with injury events 21 | should be returned. Default is \code{FALSE}.} 22 | 23 | \item{custom_grep_str}{Character string to pass a custom grep search pattern 24 | to search \code{x} "rec_type" column for. \code{NULL} by default.} 25 | } 26 | \value{ 27 | A list. Elements of the list are numeric vectors giving the years 28 | with events for each \code{fhx} series. Each element's name reflects the series' 29 | name. 30 | } 31 | \description{ 32 | Get years with events for an \code{fhx} object 33 | } 34 | \examples{ 35 | data(pgm) 36 | get_event_years(pgm, scar_event = TRUE, injury_event = TRUE) 37 | 38 | # Passing a custom string to grep. This one identified recorder years: 39 | get_event_years(pgm, custom_grep_str = "recorder_") 40 | 41 | # Use with composite to get composite years: 42 | comp <- composite(pgm, comp_name = "pgm") 43 | event_yrs <- get_event_years(comp)[["pgm"]] 44 | print(event_yrs) 45 | 46 | } 47 | \seealso{ 48 | \itemize{ 49 | \item \code{\link[=series_names]{series_names()}} get all the series in an \code{fhx} object. 50 | \item \code{\link[=year_range]{year_range()}} get earliest and latest year in an \code{fhx} object. 51 | \item \code{\link[=get_year]{get_year()}} subset an \code{fhx} object to select years. 52 | \item \code{\link[=get_series]{get_series()}} subset an \code{fhx} object to select series. 53 | \item \code{\link[=get_event_years]{get_event_years()}} gets years for various events in an \code{fhx} object. 54 | \item \code{\link[=count_event_position]{count_event_position()}} count the number of different events in an \code{fhx} 55 | object. 56 | \item \code{\link[=yearly_recording]{yearly_recording()}} count the number of "recording" events in each 57 | year of an \code{fhx} object. 58 | \item \code{\link[=series_stats]{series_stats()}} basic summary stats for an \code{fhx} object. 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /man/count_event_position.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{count_event_position} 4 | \alias{count_event_position} 5 | \title{Count different events in an \code{fhx} object} 6 | \usage{ 7 | count_event_position( 8 | x, 9 | injury_event = FALSE, 10 | position, 11 | drop_unknown = FALSE, 12 | groupby 13 | ) 14 | } 15 | \arguments{ 16 | \item{x}{An \code{fhx} object.} 17 | 18 | \item{injury_event}{Optional boolean indicating whether injuries should be 19 | considered an "event". Default is \code{FALSE}.} 20 | 21 | \item{position}{Depreciated. This allowed users to specify which intra-ring 22 | positions to include in the summary output table. The default counts all 23 | types of event positions.} 24 | 25 | \item{drop_unknown}{Boolean. Defaults to FALSE. If TRUE will remove the 26 | "unknown_fs" and/or "unknown_fi" from rec_type.} 27 | 28 | \item{groupby}{Optional named list containing character vectors that are used 29 | to count the total number of different event types. The names given to each 30 | character vector give the group's name in the output data frame.} 31 | } 32 | \value{ 33 | A data frame with a columns giving the event or event group and 34 | values giving the corresponding count for each event type or group. 35 | } 36 | \description{ 37 | Count different events in an \code{fhx} object 38 | } 39 | \examples{ 40 | data(pgm) 41 | count_event_position(pgm) 42 | 43 | # As above, but considering injuries to be a type of event. 44 | count_event_position(pgm, injury_event = TRUE) 45 | 46 | # Often we only quantify known intra-ring positions. 47 | # Remove the "unknown_fs" and/or "unknown_fi" with 48 | count_event_position(pgm, drop_unknown = TRUE) 49 | 50 | # Using custom "groupby" args in a named list, as 51 | grplist <- list( 52 | foo = c("dormant_fs", "early_fs"), 53 | bar = c("middle_fs", "late_fs") 54 | ) 55 | count_event_position(pgm, groupby = grplist) 56 | # Note that if a position in the groupby list is 57 | # not included in rec_type, forcats::fct_count() 58 | # will throw a flag for an "Unknown levels in 'f':" 59 | 60 | } 61 | \seealso{ 62 | \itemize{ 63 | \item \code{\link[=get_event_years]{get_event_years()}} gets years for various events in an \code{fhx} 64 | object. * \code{\link[=yearly_recording]{yearly_recording()}} count the number of "recording" events in 65 | each year of an \code{fhx} object. * \code{\link[=series_stats]{series_stats()}} basic summary stats for an 66 | \code{fhx} object. 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tests/testthat/test-sea.R: -------------------------------------------------------------------------------- 1 | library(burnr) 2 | context("SEA") 3 | 4 | data(pgm) 5 | data(pgm_pdsi) 6 | COMP_TEST <- composite(pgm) 7 | suppressWarnings(RNGversion("3.5.0")) 8 | set.seed(123) 9 | SEA_TEST <- sea(pgm_pdsi, COMP_TEST) 10 | 11 | test_that("Check sea warning on bad rownames", { 12 | expect_warning(sea(data.frame(1:2000), COMP_TEST), regexpr = "rownames") 13 | }) 14 | 15 | test_that("Check sea stop on no matching years", { 16 | expect_error(sea(data.frame(1:20), COMP_TEST), regexpr = "shared") 17 | }) 18 | 19 | test_that("Check sea departure data.frame", { 20 | goal_mean <- c( 21 | -0.283, 0.608, -0.148, 0.997, 1.234, 0.204, 22 | -2.156, -0.090, -0.505, 0.299, 0.283 23 | ) 24 | goal_lower95 <- c( 25 | -1.006, -1.014, -1.054, -1.049, -1.061, 26 | -1.040, -0.957, -0.995, -1.025, -1.020, -1.045 27 | ) 28 | goal_upper95 <- c( 29 | 1.032, 1.014, 0.966, 0.996, 0.972, 30 | 0.977, 0.965, 1.015, 1.015, 0.932, 1.013 31 | ) 32 | goal_lower99 <- c( 33 | -1.267, -1.333, -1.337, -1.407, -1.311, 34 | -1.329, -1.333, -1.332, -1.310, -1.342, -1.364 35 | ) 36 | goal_upper99 <- c( 37 | 1.333, 1.415, 1.179, 1.331, 1.174, 38 | 1.169, 1.341, 1.427, 1.508, 1.232, 1.386 39 | ) 40 | expect_equal(SEA_TEST$departure$lag, seq(-6, 4)) 41 | expect_equal(SEA_TEST$departure$mean, goal_mean) 42 | expect_equal(SEA_TEST$departure$upper_95_perc, goal_upper95) 43 | expect_equal(SEA_TEST$departure$lower_95_perc, goal_lower95) 44 | expect_equal(SEA_TEST$departure$upper_99_perc, goal_upper99) 45 | expect_equal(SEA_TEST$departure$lower_99_perc, goal_lower99) 46 | }) 47 | 48 | test_that("Plotting sea output works", { 49 | p <- plot(SEA_TEST) 50 | expect_is(p, "ggplot") 51 | }) 52 | 53 | test_that("The sea object prints", { 54 | prnt_sea <- capture_output(print(SEA_TEST)) 55 | expect_equal(prnt_sea, "\tSuperposed Epoch Analysis\n\t=========================\n lag upper95 lower95 upper99 lower99 departure sig\n -6 1.032 -1.006 1.333 -1.267 -0.283 \n -5 1.014 -1.014 1.415 -1.333 0.608 \n -4 0.966 -1.054 1.179 -1.337 -0.148 \n -3 0.996 -1.049 1.331 -1.407 0.997 .\n -2 0.972 -1.061 1.174 -1.311 1.234 *\n -1 0.977 -1.040 1.169 -1.329 0.204 \n 0 0.965 -0.957 1.341 -1.333 -2.156 *\n 1 1.015 -0.995 1.427 -1.332 -0.090 \n 2 1.015 -1.025 1.508 -1.310 -0.505 \n 3 0.932 -1.020 1.232 -1.342 0.299 \n 4 1.013 -1.045 1.386 -1.364 0.283 \n---\nSignif. codes: 0.01 '*' 0.05 '.'") 56 | }) 57 | -------------------------------------------------------------------------------- /man/composite.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{composite} 4 | \alias{composite} 5 | \title{Composite fire events in fhx object} 6 | \usage{ 7 | composite( 8 | x, 9 | filter_prop = 0.25, 10 | filter_min_rec = 2, 11 | filter_min_events = 1, 12 | injury_event = FALSE, 13 | comp_name = "COMP" 14 | ) 15 | } 16 | \arguments{ 17 | \item{x}{An \code{fhx} object.} 18 | 19 | \item{filter_prop}{The minimum proportion of fire events in recording series 20 | needed for fire event to be considered for composite. Default is 0.25.} 21 | 22 | \item{filter_min_rec}{The minimum number of recording series needed for a 23 | fire event to be considered for the composite. Default is 2 recording 24 | series.} 25 | 26 | \item{filter_min_events}{The minimum number of fire scars needed for a fire 27 | event to be considered for the composite. Default is 1. Fire injuries are 28 | included in this count if \code{injury_event} is \code{TRUE}.} 29 | 30 | \item{injury_event}{Boolean indicating whether injuries should be considered 31 | events. Default is \code{FALSE}.} 32 | 33 | \item{comp_name}{Character vector of the series name for the returned \code{fhx} 34 | object composite series. Default is 'COMP'.} 35 | } 36 | \value{ 37 | An \code{fhx} object representing the composited series. The object will 38 | be empty if there are nocomposite-worthy events. 39 | } 40 | \description{ 41 | Composite fire events in fhx object 42 | } 43 | \examples{ 44 | data(lgr2) 45 | plot(composite(lgr2)) 46 | 47 | # Use with composite to get composite years: 48 | comp <- composite(pgm, comp_name = "pgm") 49 | event_yrs <- get_event_years(comp)[["pgm"]] 50 | print(event_yrs) 51 | 52 | } 53 | \seealso{ 54 | \itemize{ 55 | \item \code{\link[=intervals]{intervals()}} fire interval analysis from an \code{fhx} composite. 56 | \item \code{\link[=sea]{sea()}} superposed epoch analysis. 57 | \item \code{\link[=series_stats]{series_stats()}} basic summary stats for an \code{fhx} object. 58 | \item \code{\link[=get_event_years]{get_event_years()}} gets years for various events in an \code{fhx} object. 59 | \item \code{\link[=count_event_position]{count_event_position()}} count the number of different events in an \code{fhx} 60 | object. 61 | \item \code{\link[=yearly_recording]{yearly_recording()}} count the number of "recording" events in each year 62 | of an \code{fhx} object. 63 | \item \code{\link[=fhx]{fhx()}} constructs an \code{fhx} object. 64 | \item \code{\link[=as_fhx]{as_fhx()}} casts data frame-like object into an \code{fhx} object. 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | navbar: 2 | type: default 3 | left: 4 | - text: Introduction 5 | href: articles/Introduction.html 6 | - text: Function help 7 | href: reference/index.html 8 | - text: Articles 9 | menu: 10 | - text: Add composites to facet plots 11 | href: articles/facet_comps.html 12 | right: 13 | - icon: fa-github fa-lg 14 | href: https://github.com/ltrr-arizona-edu/burnr 15 | reference: 16 | - title: Import and export data 17 | desc: > 18 | Read/write FHX file formats. These are specialized text files for 19 | storing tree-ring fire history data. FHX files can be created 20 | in [FHAES](https://www.frames.gov/fhaes/download), or by our 21 | [specialized MS Access Database](https://github.com/chguiterman/Fire_History_Database). 22 | contents: 23 | - read_fhx 24 | - write_fhx 25 | - title: Included data 26 | contents: 27 | - starts_with("pgm") 28 | - starts_with("lgr2") 29 | - pme 30 | - pmw 31 | - pmr 32 | - title: Data manipulation 33 | contents: 34 | - "`+.fhx`" 35 | - sort.fhx 36 | - composite 37 | - delete 38 | - get_series 39 | - get_year 40 | - is_fhx 41 | - make_rec_type 42 | - outer_type 43 | - last_year 44 | - title: Graphics 45 | contents: 46 | - plot_demograph 47 | - plot.fhx 48 | - plot.intervals 49 | - plot.sea 50 | - plot_intervals_dist 51 | - title: Statistical summaries 52 | contents: 53 | - series_stats 54 | - intervals 55 | - count_event_position 56 | - count_scar 57 | - count_injury 58 | - count_recording 59 | - count_year_span 60 | - get_event_years 61 | - title: Derrived time series 62 | contents: 63 | - percent_scarred 64 | - sample_depth 65 | - title: Fire-climate relationship 66 | contents: 67 | - sea 68 | - title: MISC 69 | contents: 70 | - as.fhx 71 | - as_fhx 72 | - fhx 73 | - first_year 74 | - inner_type 75 | - is.fhx 76 | - is.intervals 77 | - is.sea 78 | - is_fhx 79 | - is_intervals 80 | - is_sea 81 | - max.intervals 82 | - mean.intervals 83 | - median.intervals 84 | - min.intervals 85 | - plot_sealags 86 | - print.intervals 87 | - print.sea 88 | - quantile.intervals 89 | - series_mean_interval 90 | - series_names 91 | - summary.fhx 92 | - yearly_recording 93 | - year_range 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /man/fhx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{fhx} 4 | \alias{fhx} 5 | \title{Constructor for \code{fhx} objects} 6 | \usage{ 7 | fhx(year, series, rec_type) 8 | } 9 | \arguments{ 10 | \item{year}{An n-length numeric vector of observation years.} 11 | 12 | \item{series}{An n-length factor or character vector of observation series 13 | names.} 14 | 15 | \item{rec_type}{An n-length factor or character vector denoting the record 16 | type for each observations. Note that this needs to use a controlled 17 | vocabulary, see \code{burnr:::rec_type_all} for all possible values.} 18 | } 19 | \value{ 20 | An \code{fhx} object. \code{fhx} are S3 objects; specialized data frames with 3 21 | columns: 22 | \itemize{ 23 | \item "year": An n-length numeric vector. The year of an observation. 24 | \item "series": An n-length factor. Giving the series name for each 25 | observation. 26 | \item "rec_type": An n-length factor with controlled vocabulary and levels. 27 | This records the type of ring or record of each observation. 28 | } 29 | } 30 | \description{ 31 | Constructor for \code{fhx} objects 32 | } 33 | \details{ 34 | Note that 'year', 'series', and 'rec_type' are pass through \code{\link[=as.numeric]{as.numeric()}}, 35 | \code{\link[=as.factor]{as.factor()}}, and \code{\link[=make_rec_type]{make_rec_type()}} the \code{fhx} object is created. 36 | } 37 | \examples{ 38 | x <- fhx( 39 | year = c(1900, 1954, 1996), 40 | series = rep("tree1", 3), 41 | rec_type = c("pith_year", "unknown_fs", "bark_year") 42 | ) 43 | print(x) 44 | 45 | } 46 | \seealso{ 47 | \itemize{ 48 | \item \code{\link[=as_fhx]{as_fhx()}} casts data frame-like object into \code{fhx} object. 49 | \item \code{\link[=sort.fhx]{sort.fhx()}} sort an \code{fhx} object. 50 | \item \code{\link[=is_fhx]{is_fhx()}} test whether object is \code{fhx}. 51 | \item \code{\link[=+.fhx]{+.fhx()}} concatenate multiple \code{fhx} objects together. 52 | \item \code{\link[=make_rec_type]{make_rec_type()}} helpful to convert \code{rec_type}-like character vectors to 53 | full facors with proper levels. 54 | \item \code{\link[=read_fhx]{read_fhx()}} Read FHX2 files. 55 | \item \code{\link[=write_fhx]{write_fhx()}} Write FHX2 files. 56 | \item \code{\link[=plot_demograph]{plot_demograph()}} makes demography plots of \code{fhx} objects. 57 | \item \code{\link[=series_stats]{series_stats()}} basic common statistical summaries of \code{fhx} objects. 58 | \item \code{\link[=composite]{composite()}} create fire composites from \code{fhx} objects. 59 | \item \code{\link[=intervals]{intervals()}} fire interval analysis. 60 | \item \code{\link[=sea]{sea()}} superposed epoch analysis. 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /man/intervals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/intervals.R 3 | \name{intervals} 4 | \alias{intervals} 5 | \title{Calculate fire intervals from a \code{composite}} 6 | \usage{ 7 | intervals(comp, densfun = "weibull") 8 | } 9 | \arguments{ 10 | \item{comp}{A \code{composite} instance, usually output from \code{\link[=composite]{composite()}}. 11 | Should contain only one series.} 12 | 13 | \item{densfun}{String giving desired distribution to fit. Either "weibull" 14 | or "lognormal". Default is "weibull".} 15 | } 16 | \value{ 17 | An \code{intervals} object. \code{intervals} have components: 18 | \itemize{ 19 | \item "intervals" an integer vector giving the actual fire intervals. 20 | \item "fitdistr" a \code{fitdistr} object from \code{\link[MASS:fitdistr]{MASS::fitdistr()}} representing the 21 | density function fit. 22 | \item "densfun" a string giving the name of the density function used. 23 | \item "kstest" an \code{htest} object from \code{\link[stats:ks.test]{stats::ks.test()}} giving the result of a 24 | one-sample Kolmogorov-Smirnov test. 25 | \item "shapirotest" an \code{htest} object from \code{\link[stats:shapiro.test]{stats::shapiro.test()}} giving the 26 | result of a Shapiro-Wilk normality test. 27 | \item "comp_name" a string giving the name of the interval's input composite. 28 | \item "event_range" an integer vector giving the year range (min, max) of 29 | events used to create this intervals. 30 | } 31 | } 32 | \description{ 33 | Calculate fire intervals from a \code{composite} 34 | } 35 | \examples{ 36 | data(pgm) 37 | interv <- intervals(composite(pgm)) 38 | print(interv) 39 | 40 | mean(interv) # Mean interval 41 | 42 | # Now fit log-normal distribution instead of Weibull. 43 | intervals(composite(pgm), densfun = "lognormal") 44 | \dontrun{ 45 | # Boxplot of fire interval distribution. 46 | boxplot(intervals(composite(pgm))$intervals) 47 | } 48 | 49 | } 50 | \seealso{ 51 | \itemize{ 52 | \item \code{\link[=composite]{composite()}} to create a \code{composite} object. 53 | \item \code{\link[=mean.intervals]{mean.intervals()}} gets mean fire interval. 54 | \item \code{\link[=median.intervals]{median.intervals()}} gets median fire interval. 55 | \item \code{\link[=quantile.intervals]{quantile.intervals()}} get fit distribution quantiles. 56 | \item \code{\link[=plot_intervals_dist]{plot_intervals_dist()}} plots \code{intervals}. 57 | \item \code{\link[=min.intervals]{min.intervals()}} gives the minimum fire interval. 58 | \item \code{\link[=max.intervals]{max.intervals()}} gives the maximum fire interval. 59 | \item \code{\link[=print.intervals]{print.intervals()}} prints common fire-interval summary statistics. 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /man/series_stats.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stats.R 3 | \name{series_stats} 4 | \alias{series_stats} 5 | \title{Generate series-level descriptive statistics for \code{fhx} object} 6 | \usage{ 7 | series_stats( 8 | x, 9 | func_list = list(first = first_year, last = last_year, years = count_year_span, 10 | inner_type = inner_type, outer_type = outer_type, number_scars = count_scar, 11 | number_injuries = count_injury, recording_years = count_recording, mean_interval = 12 | series_mean_interval) 13 | ) 14 | } 15 | \arguments{ 16 | \item{x}{An \code{fhx} object.} 17 | 18 | \item{func_list}{A list of named functions that will be run on each series 19 | in the \code{fhx} object. The list name for each function is the corresponding 20 | column name in the output data frame.} 21 | } 22 | \value{ 23 | A \code{data.frame} containing series-level statistics. 24 | } 25 | \description{ 26 | Generate series-level descriptive statistics for \code{fhx} object 27 | } 28 | \examples{ 29 | data(lgr2) 30 | series_stats(lgr2) 31 | 32 | # You can create your own list of statistics to output. You can also create 33 | # your own functions: 34 | flist <- list( 35 | n = count_year_span, 36 | xbar_interval = function(x) mean_interval(x, injury_event = TRUE) 37 | ) 38 | sstats <- series_stats(lgr2) 39 | head(sstats) 40 | } 41 | \seealso{ 42 | \itemize{ 43 | \item \code{\link[=fhx]{fhx()}} creates an \code{fhx} object. 44 | \item \code{\link[=as_fhx]{as_fhx()}} casts data frame into an \code{fhx} object. 45 | \item \code{\link[=first_year]{first_year()}} gets earliest year in an \code{fhx} object. 46 | \item \code{\link[=last_year]{last_year()}} gets latest year in an \code{fhx} object. 47 | \item \code{\link[=count_year_span]{count_year_span()}} counts the year span of an \code{fhx} object. 48 | \item \code{\link[=inner_type]{inner_type()}} gets "rec_type" for inner event of an \code{fhx} object. 49 | \item \code{\link[=outer_type]{outer_type()}} get "rec_type" for outside event of an \code{fhx} object. 50 | \item \code{\link[=count_scar]{count_scar()}} counts scars in an \code{fhx} object. 51 | \item \code{\link[=count_injury]{count_injury()}} counts injuries in an \code{fhx} object. 52 | \item \code{\link[=count_recording]{count_recording()}} counts recording years in \code{fhx} object. 53 | \item \code{\link[=series_mean_interval]{series_mean_interval()}} quickly estimates mean fire-interval of \code{fhx} 54 | object. 55 | \item \code{\link[=sample_depth]{sample_depth()}} gets sample depth of an \code{fhx} object. 56 | \item \code{\link[=summary.fhx]{summary.fhx()}} brief summary of an \code{fhx} object. 57 | \item \code{\link[=composite]{composite()}} create a fire \code{composite} from an \code{fhx} object. 58 | \item \code{\link[=intervals]{intervals()}} get fire \code{intervals} analysis from \code{composite}. 59 | \item \code{\link[=sea]{sea()}} superposed epoch analysis. 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /data-raw/sysdata.R: -------------------------------------------------------------------------------- 1 | library(usethis) 2 | library(burnr) 3 | 4 | 5 | type_key <- list( 6 | "." = "null_year", 7 | "|" = "recorder_year", 8 | "U" = "unknown_fs", 9 | "u" = "unknown_fi", 10 | "D" = "dormant_fs", 11 | "d" = "dormant_fi", 12 | "E" = "early_fs", 13 | "e" = "early_fi", 14 | "M" = "middle_fs", 15 | "m" = "middle_fi", 16 | "L" = "late_fs", 17 | "l" = "late_fi", 18 | "A" = "latewd_fs", 19 | "a" = "latewd_fi", 20 | "[" = "pith_year", 21 | "]" = "bark_year", 22 | "{" = "inner_year", 23 | "}" = "outer_year", 24 | "?" = "estimate", # non-canon for estimated years to pith. 25 | "T" = "transition_fs", # noncanon 26 | "t" = "transition_fi", # noncanon 27 | "F" = "falldormant_fs", # noncanon 28 | "f" = "falldormant_fi", # noncanon 29 | "S" = "springdormant_fs", # noncanon 30 | "s" = "springdormant_fi", # noncanon 31 | "B" = "earlylw_fs", # noncanon 32 | "b" = "earlylw_fi", # noncanon 33 | "C" = "latelw_fs", # noncanon 34 | "c" = "latelw_fi" # noncanon 35 | ) 36 | 37 | rec_type_all <- unlist(type_key) 38 | # Has names() of the original, abbreviated FHX file event codes. 39 | 40 | rec_type_abrv <- names(rec_type_all) 41 | # Has names() of the rec_type levels we use for this package. 42 | names(rec_type_abrv) <- rec_type_all 43 | 44 | rec_type_recorder <- c( 45 | "recorder_year", 46 | "unknown_fs", 47 | "dormant_fs", 48 | "early_fs", 49 | "middle_fs", 50 | "late_fs", 51 | "latewd_fs", 52 | "transition_fs", # noncanon 53 | "falldormant_fs", # noncanon 54 | "springdormant_fs", #noncanon 55 | "earlylw_fs", # noncanon 56 | "latelw_fs" # noncanon 57 | ) 58 | rec_type_injury <- c( 59 | "unknown_fi", 60 | "dormant_fi", 61 | "early_fi", 62 | "middle_fi", 63 | "late_fi", 64 | "latewd_fi", 65 | "transition_fi", # noncanon 66 | "falldormant_fi", # noncanon 67 | "springdormant_fi", # noncanon 68 | "earlylw_fi", # noncanon 69 | "latelw_fi" # noncanon 70 | ) 71 | rec_type_scar <- c( 72 | "unknown_fs", 73 | "dormant_fs", 74 | "early_fs", 75 | "middle_fs", 76 | "late_fs", 77 | "latewd_fs", 78 | "transition_fs", # noncanon 79 | "falldormant_fs", # noncanon 80 | "springdormant_fs", # noncanon 81 | "earlylw_fs", # noncanon 82 | "latelw_fs" # noncanon 83 | ) 84 | rec_type_ends <- c( 85 | "pith_year", 86 | "bark_year", 87 | "inner_year", 88 | "outer_year" 89 | ) 90 | 91 | # Only "official" canon rec_types go here: 92 | rec_type_canon <- c( 93 | "null_year", 94 | "recorder_year", 95 | "unknown_fs", 96 | "unknown_fi", 97 | "dormant_fs", 98 | "dormant_fi", 99 | "early_fs", 100 | "early_fi", 101 | "middle_fs", 102 | "middle_fi", 103 | "late_fs", 104 | "late_fi", 105 | "latewd_fs", 106 | "latewd_fi", 107 | "pith_year", 108 | "bark_year", 109 | "inner_year", 110 | "outer_year" 111 | ) 112 | 113 | usethis::use_data(rec_type_all, rec_type_abrv, 114 | rec_type_recorder, rec_type_injury, rec_type_scar, rec_type_ends, 115 | rec_type_canon, 116 | internal = TRUE, overwrite = TRUE 117 | ) 118 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # burnr 5 | 6 | 7 | 8 | [![CRAN\_Status\_Badge](https://www.r-pkg.org/badges/version/burnr)](https://cran.r-project.org/package=burnr) 9 | [![Coverage 10 | Status](https://coveralls.io/repos/github/ltrr-arizona-edu/burnr/badge.svg?branch=master)](https://coveralls.io/github/ltrr-arizona-edu/burnr?branch=master) 11 | [![R-CMD-check](https://github.com/ltrr-arizona-edu/burnr/workflows/R-CMD-check/badge.svg)](https://github.com/ltrr-arizona-edu/burnr/actions) 12 | [![downloads](https://cranlogs.r-pkg.org/badges/burnr)](https://cran.r-project.org/package=burnr) 13 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.594459.svg)](https://doi.org/10.5281/zenodo.594459) 14 | 15 | 16 | 17 | Basic tools to analyze forest fire history data (e.g. FHX) in R. This is 18 | designed for power users and projects with special needs. 19 | 20 | ## Installation 21 | 22 | You can install the released version of burnr from 23 | [CRAN](https://CRAN.R-project.org) with: 24 | 25 | ``` r 26 | install.packages("burnr") 27 | ``` 28 | 29 | And the development version from [GitHub](https://github.com/) with: 30 | 31 | ``` r 32 | # install.packages("devtools") 33 | devtools::install_github("ltrr-arizona-edu/burnr") 34 | ``` 35 | 36 | ## Example 37 | 38 | This is a basic example which shows you how to solve a common problem: 39 | 40 | ``` r 41 | library(burnr) 42 | 43 | # This gives you a basic plot. There are more advanced options. For example, we can color our plot by sample species. 44 | 45 | data(lgr2_meta) 46 | 47 | plot(lgr2, 48 | color_group = lgr2_meta$SpeciesID, 49 | color_id = lgr2_meta$TreeID, 50 | plot_legend = TRUE 51 | ) 52 | ``` 53 | 54 | 55 | 56 | ## Support 57 | 58 | Documentation is included in the code. If you’re new to `burnr`, our 59 | [2018 paper in 60 | Dendrochronologia](https://doi.org/10.1016/j.dendro.2018.02.005) is a 61 | nice survey of the package with many examples. We also have 62 | instructional vignettes on the project website, 63 | . And you can work through 64 | examples, with included data, in an R project hosted by @chguiterman on 65 | GitHub: . We’re working to 66 | enhance our instruction and add to these demos on the burnr website, so 67 | please send us requests for new tips and tricks, or create your own and 68 | share with us\! 69 | 70 | ## Citation 71 | 72 | Please cite the original `burnr` paper if you use it in your research: 73 | 74 | > Malevich, Steven B., Christopher H. Guiterman, and Ellis Q. Margolis 75 | > (2018) [Burnr: Fire History Analysis and Graphics in 76 | > R](https://www.sciencedirect.com/science/article/abs/pii/S1125786517301418?via%3Dihub). 77 | > *Dendrochronologia* 49: 9–15. DOI: 10.1016/j.dendro.2018.02.005. 78 | 79 | Citations help us to identify user needs and justify additional time 80 | developing and maintaining `burnr`. 81 | 82 | ## Development 83 | 84 | Please file bugs in the [bug 85 | tracker](https://github.com/ltrr-arizona-edu/burnr/issues). 86 | 87 | Want to contribute? Great\! We’re following [Hadley’s packaging 88 | workflow](https://r-pkgs.org/) and [style 89 | guide](https://style.tidyverse.org/). Fork away. 90 | 91 | If you’re not a developer, don’t worry\! We also welcome help with 92 | documentation and tutorials. 93 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, include = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "man/figures/README-", 12 | out.width = "100%" 13 | ) 14 | ``` 15 | 16 | # burnr 17 | 18 | 19 | [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/burnr)](https://cran.r-project.org/package=burnr) 20 | [![Coverage Status](https://coveralls.io/repos/github/ltrr-arizona-edu/burnr/badge.svg?branch=master)](https://coveralls.io/github/ltrr-arizona-edu/burnr?branch=master) 21 | [![R-CMD-check](https://github.com/ltrr-arizona-edu/burnr/workflows/R-CMD-check/badge.svg)](https://github.com/ltrr-arizona-edu/burnr/actions) 22 | [![downloads](https://cranlogs.r-pkg.org/badges/burnr)](https://cran.r-project.org/package=burnr) 23 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.594459.svg)](https://doi.org/10.5281/zenodo.594459) 24 | 25 | 26 | 27 | 28 | 29 | Basic tools to analyze forest fire history data (e.g. FHX) in R. This is designed for power users and projects with special needs. 30 | 31 | ## Installation 32 | 33 | You can install the released version of burnr from [CRAN](https://CRAN.R-project.org) with: 34 | 35 | ``` r 36 | install.packages("burnr") 37 | ``` 38 | 39 | And the development version from [GitHub](https://github.com/) with: 40 | 41 | ``` r 42 | # install.packages("devtools") 43 | devtools::install_github("ltrr-arizona-edu/burnr") 44 | ``` 45 | ## Example 46 | 47 | This is a basic example which shows you how to solve a common problem: 48 | 49 | ```{r example} 50 | library(burnr) 51 | 52 | # This gives you a basic plot. There are more advanced options. For example, we can color our plot by sample species. 53 | 54 | data(lgr2_meta) 55 | 56 | plot(lgr2, 57 | color_group = lgr2_meta$SpeciesID, 58 | color_id = lgr2_meta$TreeID, 59 | plot_legend = TRUE 60 | ) 61 | ``` 62 | 63 | ## Support 64 | 65 | Documentation is included in the code. If you're new to `burnr`, our [2018 paper in Dendrochronologia](https://doi.org/10.1016/j.dendro.2018.02.005) is a nice survey of the package with many examples. We also have instructional vignettes on the project website, . And you can work through examples, with included data, in an R project hosted by @chguiterman on GitHub: . We're working to enhance our instruction and add to these demos on the burnr website, so please send us requests for new tips and tricks, or create your own and share with us! 66 | 67 | 68 | ## Citation 69 | 70 | Please cite the original `burnr` paper if you use it in your research: 71 | 72 | > Malevich, Steven B., Christopher H. Guiterman, and Ellis Q. Margolis (2018) [Burnr: Fire History Analysis and Graphics in R](https://www.sciencedirect.com/science/article/abs/pii/S1125786517301418?via%3Dihub). _Dendrochronologia_ 49: 9–15. DOI: 10.1016/j.dendro.2018.02.005. 73 | 74 | 75 | Citations help us to identify user needs and justify additional time developing and maintaining `burnr`. 76 | 77 | 78 | ## Development 79 | 80 | Please file bugs in the [bug tracker](https://github.com/ltrr-arizona-edu/burnr/issues). 81 | 82 | Want to contribute? Great! We're following [Hadley's packaging workflow](https://r-pkgs.org/) and [style guide](https://style.tidyverse.org/). Fork away. 83 | 84 | If you're not a developer, don't worry! We also welcome help with documentation and tutorials. 85 | -------------------------------------------------------------------------------- /R/data.R: -------------------------------------------------------------------------------- 1 | #' Los Griegos Peak plot2 fire-history data 2 | #' 3 | #' An `fhx` object with fire-history data from Los Griegos Peak, New Mexico. 4 | #' 5 | #' @format An fhx object with 26 series from 1366 to 2012 CE. 6 | #' 7 | #' @seealso [lgr2_meta] Los Griegos Peak metadata. 8 | "lgr2" 9 | 10 | 11 | #' Metadata for the Los Griegos Peak fire-history dataset 12 | #' 13 | #' @description 14 | #' A data frame with species information for the Los Griegos Peak plot2 15 | #' fire-history dataset ([lgr2]). 16 | #' 17 | #' @format A `data.frame` with 26 rows and 2 variables: 18 | #' * "TreeID": Name of tree series. 19 | #' * "SpeciesID": Abbreviated tree species 20 | #' 21 | #' @seealso [lgr2] Log Griegos Peak fire-history data. 22 | "lgr2_meta" 23 | 24 | 25 | #' Peggy Mesa fire-history data 26 | #' 27 | #' @description 28 | #' An `fhx` object with fire-history data from Peggy Mesa. 29 | #' 30 | #' @format An `fhx` object with 41 series from 1555 to 2013 CE. 31 | #' 32 | #' @source Guiterman, Christopher H., Ellis Q. Margolis, and 33 | #' Thomas W. Swetnam. 2015. "Dendroecological Methods For Reconstructing 34 | #' High-Severity Fire In Pine-Oak Forests." Tree-Ring Research 71 (2): 67-77. 35 | #' doi:10.3959/1536-1098-71.2.67. 36 | #' 37 | #' @seealso 38 | #' * [pgm_meta] Peggy Mesa metadata. 39 | #' * [pgm_pdsi] PDSI time-series for Peggy Mesa site. 40 | "pgm" 41 | 42 | 43 | #' Metadata for the Peggy Mesa fire-history dataset 44 | #' 45 | #' @description 46 | #' A data frame with species and location information for the Peggy Mesa 47 | #' fire-history dataset ([pgm]). 48 | #' 49 | #' @format A `data.frame` with 41 rows and 5 variables: 50 | #' * "TreeID": Name of tree series. 51 | #' * "SpeciesID": Abbreviated tree species. 52 | #' * "Latitude": latitude of tree in decimal degrees. 53 | #' * "Longitude": longitude of tree in decimal degrees. 54 | #' * "Elevation": tree elevation in meters. 55 | #' 56 | #' @source Guiterman, Christopher H., Ellis Q. Margolis, and 57 | #' Thomas W. Swetnam. 2015. "Dendroecological Methods For Reconstructing 58 | #' High-Severity Fire In Pine-Oak Forests." Tree-Ring Research 71 (2): 67-77. 59 | #' doi:10.3959/1536-1098-71.2.67. 60 | #' 61 | #' @seealso 62 | #' * [pgm] Peggy Mesa fire-history data. 63 | #' * [pgm_pdsi] PDSI time-series for Peggy Mesa site. 64 | "pgm_meta" 65 | 66 | 67 | #' Reconstructed PDSI time series for the Peggy Mesa fire-history dataset 68 | #' 69 | #' @description 70 | #' A tree-ring reconstructed Palmer Drought-Severity Index time series 71 | #' corresponding to the Peggy Mesa fire-history dataset ([pgm]) -- specifically, 72 | #' the Jemez Mountains area (gridpoint 133). The reconstruction is from The 73 | #' North American Drought Atlas (Cook and Krusic 2004). 74 | #' 75 | #' @format A `data.frame` with 2004 rows and 1 variables. Row names give the 76 | #' year for the reconstructed value: 77 | #' * "RECON": The reconstructed PDSI series. 78 | #' 79 | #' @source Cook, E. R., and Krusic, P. J. (2004). The North American Drought 80 | #' Atlas. Retrieved September 13, 2017, from 81 | #' http://iridl.ldeo.columbia.edu/SOURCES/.LDEO/.TRL/.NADA2004/.pdsi-atlas.html 82 | #' 83 | #' @seealso 84 | #' * [pgm] Peggy Mesa fire-history data. 85 | #' * [pgm_meta] Peggy Mesa metadata. 86 | "pgm_pdsi" 87 | 88 | #' Pajarito Mountain East fire-history data 89 | #' 90 | #' @description 91 | #' An `fhx` object with fire-history data. 92 | #' 93 | #' @format An `fhx` object with 17 series from 1702 to 1993 CE. 94 | #' 95 | #' @source https://www1.ncdc.noaa.gov/pub/data/paleo/firehistory/firescar/northamerica/uspme001.fhx 96 | #' 97 | "pme" 98 | 99 | #' Pajarito Mountain West fire-history data 100 | #' 101 | #' @description 102 | #' An `fhx` object with fire-history data. 103 | #' 104 | #' @format An `fhx` object with 11 series from 1617 to 1993 CE. 105 | #' 106 | #' @source https://www1.ncdc.noaa.gov/pub/data/paleo/firehistory/firescar/northamerica/uspmw001.fhx 107 | #' 108 | "pmw" 109 | 110 | #' Pajarito Mountain Ridge fire-history data 111 | #' 112 | #' @description 113 | #' An `fhx` object with fire-history data. 114 | #' 115 | #' @format An `fhx` object with 23 series from 1626 to 1993 CE. 116 | #' 117 | #' @source https://www1.ncdc.noaa.gov/pub/data/paleo/firehistory/firescar/northamerica/uspmr001.fhx 118 | #' 119 | "pmr" 120 | -------------------------------------------------------------------------------- /tests/testthat/test-stats.R: -------------------------------------------------------------------------------- 1 | library(burnr) 2 | context("Statistics") 3 | 4 | data(lgr2) 5 | REF_MULTI <- lgr2 6 | REF_SINGLE <- get_series(REF_MULTI, "LGR53") 7 | 8 | test_that("first_year on single series", { 9 | expect_equal(first_year(REF_SINGLE), 1772) 10 | }) 11 | 12 | test_that("first_year on multi-series fhx object", { 13 | expect_equal(first_year(REF_MULTI), 1366) 14 | }) 15 | 16 | test_that("last_year on single series", { 17 | expect_equal(last_year(REF_SINGLE), 1843) 18 | }) 19 | 20 | test_that("last_year on multi-series fhx object", { 21 | expect_equal(last_year(REF_MULTI), 2012) 22 | }) 23 | 24 | test_that("count_year_span on single series", { 25 | expect_equal(count_year_span(REF_SINGLE), 72) 26 | }) 27 | 28 | test_that("count_year_span on multi-series fhx object", { 29 | expect_equal(count_year_span(REF_MULTI), 647) 30 | }) 31 | 32 | test_that("outer_type on single series", { 33 | expect_match(as.character(outer_type(REF_SINGLE)), "outer_year") 34 | }) 35 | 36 | test_that("outer_type on multi-series fhx object", { 37 | expect_match(as.character(outer_type(REF_MULTI)), "bark_year") 38 | }) 39 | 40 | test_that("inner_type on single series", { 41 | expect_match(as.character(inner_type(REF_SINGLE)), "pith_year") 42 | }) 43 | 44 | test_that("inner_type on multi-series fhx object", { 45 | expect_match(as.character(inner_type(REF_MULTI)), "inner_year") 46 | }) 47 | 48 | test_that("count_scar on single series", { 49 | expect_equal(count_scar(REF_SINGLE), 1) 50 | }) 51 | 52 | test_that("count_scar on multi-series fhx object", { 53 | expect_equal(count_scar(REF_MULTI), 9) 54 | }) 55 | 56 | test_that("count_injury on single series", { 57 | expect_equal(count_injury(REF_SINGLE), 0) 58 | }) 59 | 60 | test_that("count_injury on multi-series fhx object", { 61 | expect_equal(count_injury(REF_MULTI), 6) 62 | }) 63 | 64 | test_that("count_recording on single series", { 65 | expect_equal(count_recording(REF_SINGLE), 38) 66 | }) 67 | 68 | test_that("count_recording on multi-series fhx object", { 69 | expect_equal(count_recording(REF_MULTI), 514) 70 | }) 71 | 72 | test_that("count_recording on single series with injury as events", { 73 | expect_equal(count_recording(REF_SINGLE, injury_event = TRUE), 38) 74 | }) 75 | 76 | test_that("count_recording on multi-series fhx object with injury as events", { 77 | expect_equal(count_recording(REF_MULTI, injury_event = TRUE), 514) 78 | }) 79 | 80 | test_that("series_mean_interval on single series without enough events", { 81 | expect_equal(series_mean_interval(REF_SINGLE), NA) 82 | }) 83 | 84 | test_that("series_mean_interval on single series", { 85 | expect_equal(series_mean_interval(get_series(REF_MULTI, "LGR46")), 16.5) 86 | }) 87 | 88 | test_that("series_mean_interval on multi-series object", { 89 | expect_warning(series_mean_interval(REF_MULTI)) 90 | }) 91 | 92 | test_that("series_mean_interval on multi-series fhx object", { 93 | expect_equal(series_mean_interval(REF_MULTI), 47.9) 94 | }) 95 | 96 | test_that("sample_depth on multi-series fhx object", { 97 | sdepth <- subset( 98 | sample_depth(REF_MULTI), 99 | year %in% c(1366, 1436, 2011, 2012) 100 | )[["samp_depth"]] 101 | expect_equal(sdepth, c(1, 2, 13, 2)) 102 | }) 103 | 104 | test_that("sample_depth on single-series fhx object", { 105 | sdepth <- subset( 106 | sample_depth(REF_SINGLE), 107 | year %in% 1800 108 | )[["samp_depth"]] 109 | expect_equal(sdepth, 1) 110 | }) 111 | 112 | test_that("percent scarred works without injury", { 113 | goal_1773_percent_scarred <- 50 114 | victim <- percent_scarred(REF_MULTI) 115 | expect_equal( 116 | victim[victim$year == 1773, ]$percent_scarred, 117 | goal_1773_percent_scarred 118 | ) 119 | expect_equal( 120 | victim[victim$year == 1774, ]$percent_scarred, 121 | 0 122 | ) 123 | }) 124 | 125 | test_that("percent scarred works with injuries", { 126 | goal_1806_percent_scarred <- 88 127 | victim <- percent_scarred(REF_MULTI, injury_event = TRUE) 128 | expect_equal( 129 | victim[victim$year == 1806, ]$percent_scarred, 130 | goal_1806_percent_scarred 131 | ) 132 | }) 133 | 134 | test_that("Summary output is consistent", { 135 | lgr_summ <- unlist(summary(lgr2)) 136 | target <- c("number_series" = 26, 137 | "first_year" = 1366, 138 | "last_year" = 2012, 139 | "number_scars" = 9, 140 | "number_injuries" = 6) 141 | expect_equal(lgr_summ, target) 142 | }) 143 | -------------------------------------------------------------------------------- /vignettes/facet_comps.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Add composites to facet plots" 3 | author: "Chris Guiterman" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Add composites to facet plots} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | \usepackage[utf8]{inputenc} 10 | --- 11 | 12 | ```{r, include = FALSE} 13 | knitr::opts_chunk$set( 14 | collapse = TRUE, 15 | comment = "#>" 16 | ) 17 | ``` 18 | 19 | A limitation of ggplot graphics is an inability to use the `composite_rug` parameter within a facet generated by `plot_demograph()`. In this instance, one can make composites and add them to demograph plots within the facets, or stack the composites in a separate facet. We can use the color options of `plot_demograph()` to help distinguish between trees and site-level composites. This section will demonstrate how. 20 | 21 | First, read in three related sites from the Jemez Mountains, New Mexico. These are available on the International Multiproxy Paleofire Database (IMPD). 22 | 23 | ```{r} 24 | library(burnr) 25 | library(ggplot2) 26 | 27 | ## Files were obtained from the IMPD 28 | # url <- "https://www1.ncdc.noaa.gov/pub/data/paleo/firehistory/firescar/northamerica/" 29 | 30 | pmr <- read_fhx("uspmr001.fhx") 31 | pme <- read_fhx("uspme001.fhx") 32 | pmw <- read_fhx("uspmw001.fhx") 33 | ``` 34 | 35 | To designate the different sites and data type (tree vs. composite in this case) we create metadata tables for each site from the fhx objects. If we had species information we color by species as well, and would add "composite" as a sort of species. 36 | 37 | ```{r} 38 | pmr.meta <- data.frame(series = series_names(pmr), site = 'PMR', type = 'Tree') 39 | pme.meta <- data.frame(series = series_names(pme), site = 'PME', type = 'Tree') 40 | pmw.meta <- data.frame(series = series_names(pmw), site = 'PMW', type = 'Tree') 41 | ``` 42 | 43 | Make the composite fire histories for each site. 44 | 45 | ```{r} 46 | pmr.comp <- composite(pmr, comp_name = 'PMR.comp') 47 | pme.comp <- composite(pme, comp_name = 'PME.comp') 48 | pmw.comp <- composite(pmw, comp_name = 'PMW.comp') 49 | ``` 50 | Make a dataframe for the composites, and combine it with the tree-level data. 51 | 52 | ```{r} 53 | comp.meta <- data.frame(series = c('PMR.comp', 'PME.comp', 'PMW.comp'), 54 | site = c('PMR', 'PME', 'PMW'), 55 | type = 'Composite') 56 | ``` 57 | 58 | Combine all of the fhx objects and the metadata tables. We add here the sort function to order the series in the fhx object. In this case, the preferred final look of the plot will be trees sorted by their inner-ring date. In the next step we'll flip the series order to place the composites on the bottom of each facet, so here we sort the series in the opposite manner. 59 | 60 | ```{r} 61 | all.fhx <- sort(pmr, sort_by = "first_year", decreasing = TRUE) + 62 | sort(pme, sort_by = "first_year", decreasing = TRUE) + 63 | sort(pmw, sort_by = "first_year", decreasing = TRUE) + 64 | pmr.comp + pme.comp + pmw.comp 65 | 66 | all.meta <- rbind(pmr.meta, pme.meta, pmw.meta, comp.meta) 67 | ``` 68 | 69 | To ensure the composite stays at the bottom of the facet, the factor order needs to be reversed. 70 | 71 | ```{r} 72 | all.fhx$series <- factor(all.fhx$series, levels = rev(levels(all.fhx$series))) 73 | ``` 74 | Make the fire-demography plot. 75 | 76 | ```{r} 77 | plot_demograph(all.fhx, facet_group = all.meta$site, 78 | facet_id = all.meta$series, 79 | color_group = all.meta$type, 80 | color_id = all.meta$series, 81 | ylabels = FALSE, event_size = c(2.5, 1, 1), 82 | plot_legend = TRUE, yearlims = c(1600, 1995)) + 83 | scale_color_manual(values=c('red', 'black')) + 84 | theme(legend.position = 'top', 85 | legend.direction="horizontal", 86 | legend.background=element_rect(fill='white'), 87 | legend.box="horizontal") 88 | ``` 89 | 90 | To place the composites in their own facet, change the site ID to "composite". Make sure the order in which the composites are added to the full fhx object matches the order of the tree-level site facets. 91 | ```{r} 92 | comp.meta <- data.frame(series = c('PMR.comp', 'PME.comp', 'PMW.comp'), 93 | site = 'Composite', 94 | type = 'Composite') 95 | 96 | all.meta <- rbind(pmr.meta, pme.meta, pmw.meta, comp.meta) 97 | all.meta$site <- factor(all.meta$site, 98 | levels = c("PMR", "PME", "PMW", "Composite")) 99 | # use factor() to resort the facets, placing Composite on bottom 100 | 101 | plot_demograph(all.fhx, 102 | facet_group = all.meta$site, 103 | facet_id = all.meta$series, 104 | ylabels = FALSE, 105 | event_size = c(2.5, 1, 1), 106 | plot_legend = TRUE, 107 | yearlims = c(1600, 1995)) + 108 | theme(legend.position = 'top', 109 | legend.direction="horizontal", 110 | legend.background=element_rect(fill='white'), 111 | legend.box="horizontal") 112 | 113 | ``` 114 | -------------------------------------------------------------------------------- /man/sea.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sea.R 3 | \name{sea} 4 | \alias{sea} 5 | \title{Perform superposed epoch analysis} 6 | \usage{ 7 | sea(x, event, nbefore = 6, nafter = 4, event_range = TRUE, n_iter = 1000) 8 | } 9 | \arguments{ 10 | \item{x}{A data frame climate reconstruction or tree-ring series with row 11 | names as years, and one numeric variable.} 12 | 13 | \item{event}{An numeric vector of event years for superposed epoch, such as 14 | fire years, or an \code{fhx} object with a single series as produced by 15 | \code{\link[=composite]{composite()}}.} 16 | 17 | \item{nbefore}{The number of lag years prior to the event year.} 18 | 19 | \item{nafter}{The number of lag years following the event year.} 20 | 21 | \item{event_range}{Logical. Constrain the time series to the time period of 22 | key events within the range of the \code{x} series. \code{FALSE} uses the entire 23 | series, ignoring the period of key events.} 24 | 25 | \item{n_iter}{The number of iterations for bootstrap resampling.} 26 | } 27 | \value{ 28 | A \code{sea} object containing. This contains: 29 | \itemize{ 30 | \item "event_years": a numeric vector of event years. 31 | \item "actual": a \code{data.frame} summary of the actual events. 32 | \item "random": a \code{data.frame} summary of the bootstrapped events. 33 | \item "departure": a \code{data.frame} summary of the departures of actual from 34 | bootstrapped events. 35 | \item "simulated": a full 2D \code{matrix} of the bootstrapped-values across lags. 36 | \item "observed": a ful 2D \code{matrix} of "actual" events across lags. 37 | } 38 | } 39 | \description{ 40 | Perform superposed epoch analysis 41 | } 42 | \details{ 43 | Superposed epoch analysis (SEA) helps to evaluate fire-climate 44 | relationships in studies of tree-ring fire history. It works by compositing 45 | the values of an annual time series or climate reconstruction for the fire 46 | years provided (\code{event}) and both positive and negative lag years. 47 | Bootstrap resampling of the time series is performed to evaluate the 48 | statistical significance of each year's mean value. Users interpret the 49 | departure of the actual event year means from the simulated event year means. 50 | Note that there is no rescaling of the climate time series \code{x}. 51 | 52 | The significance of lag-year departures from the average climate condition 53 | was first noted by Baisan and Swetnam (1990) and used in an organized SEA by 54 | Swetnam (1993). Since then, the procedure has been commonly applied in fire 55 | history studies. The FORTRAN program EVENT.exe was written by Richard Holmes 56 | and Thomas Swetnam (Holmes and Swetnam 1994) to perform SEA for fire history 57 | specifically. EVENT was incorporated in the FHX2 software by Henri 58 | Grissino-Mayer. Further information about SEA can be found in the FHAES 59 | user's manual, http://help.fhaes.org/. 60 | 61 | \code{\link[=sea]{sea()}} was originally designed to replicate EVENT as closely as possible. We 62 | have tried to stay true to their implementation of SEA, although multiple 63 | versions of the analysis exist in the climate literature and for fire 64 | history. The outcome of EVENT and sea should only differ slightly in the 65 | values of the simulated events and the departures, because random draws are 66 | used. The event year and lag significance levels should match, at least in 67 | the general pattern. 68 | 69 | Our SEA implementation borrowed from \code{dplR::sea()} function in how it 70 | performs the bootstrap procedure, but differs in the kind of output provided 71 | for the user. 72 | } 73 | \examples{ 74 | \dontrun{ 75 | # Read in the Cook and Krusic (2004; The North American Drought Atlas) 76 | # reconstruction of Palmer Drought Severity Index (PDSI) for the Jemez 77 | # Mountains area (gridpoint 133). 78 | target_url <- paste0( 79 | "http://iridl.ldeo.columbia.edu", 80 | "/SOURCES/.LDEO/.TRL/.NADA2004", 81 | "/pdsiatlashtml/pdsiwebdata/1050w_350n_133.txt" 82 | ) 83 | pdsi <- read.table(target_url, header = TRUE, row.names = 1) 84 | pdsi <- subset(pdsi, select = "RECON") 85 | 86 | # Run SEA on Peggy Mesa (pgm) data 87 | data(pgm) 88 | pgm_comp <- composite(pgm) 89 | 90 | pgm_sea <- sea(pdsi, pgm_comp) 91 | 92 | # See basic results: 93 | print(pgm_sea) 94 | 95 | # Basic plot: 96 | plot(pgm_sea) 97 | } 98 | 99 | } 100 | \references{ 101 | Baisan and Swetnam 1990, Fire history on desert mountain range: 102 | Rincon Mountain Wilderness, Arizona, U.S.A. Canadian Journal of Forest 103 | Research 20:1559-1569. 104 | 105 | Bunn 2008, A dendrochronology program library in R (dplR), 106 | Dendrochronologia 26:115-124 107 | 108 | Holmes and Swetnam 1994, EVENT program description 109 | 110 | Swetnam 1993, Fire history and climate change in giant sequoia 111 | groves, Science 262:885-889. 112 | } 113 | \seealso{ 114 | \itemize{ 115 | \item \code{\link[=plot_sealags]{plot_sealags()}} plots \code{sea} lags and their statistical significance. 116 | \item \code{\link[=print.sea]{print.sea()}} prints a pretty summary of \code{sea} objects. 117 | \item \code{\link[=composite]{composite()}} creates fire composites, a common input to \code{\link[=sea]{sea()}}. 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /man/plot_demograph.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotting.R 3 | \name{plot_demograph} 4 | \alias{plot_demograph} 5 | \title{Create an ggplot2 object for plotting fhx demographics} 6 | \usage{ 7 | plot_demograph( 8 | x, 9 | color_group, 10 | color_id, 11 | facet_group, 12 | facet_id, 13 | facet_type = "grid", 14 | ylabels = TRUE, 15 | yearlims = FALSE, 16 | composite_rug = FALSE, 17 | filter_prop = 0.25, 18 | filter_min_rec = 2, 19 | filter_min_events = 1, 20 | injury_event = FALSE, 21 | plot_legend = FALSE, 22 | event_size = c(Scar = 4, Injury = 2, `Pith/Bark` = 1.5), 23 | rugbuffer_size = 2, 24 | rugdivide_pos = 2 25 | ) 26 | } 27 | \arguments{ 28 | \item{x}{An \code{fhx} object, as from \code{\link[=fhx]{fhx()}}} 29 | 30 | \item{color_group}{Option to plot series with colors. This is a character 31 | vector or factor which corresponds to the series names given in 32 | \code{color_id}. Both \code{color_group} and \code{color_id} need to be 33 | specified. Default plot gives no color.} 34 | 35 | \item{color_id}{Option to plot series with colors. A character vector of 36 | series names corresponding to groups given in \code{color_group.} Every 37 | unique value in \code{x} series.names needs to have a corresponding 38 | color_group value. Both \code{color_group} and \code{color_id} need to be 39 | specified. Default plot gives no species colors.} 40 | 41 | \item{facet_group}{Option to plot series with faceted by a factor. A vector 42 | of factors or character vector which corresponds to the series names given 43 | in \code{facet_id.} Both \code{facet_group} and \code{facet_id} need to be 44 | specified. Default plot is not faceted.} 45 | 46 | \item{facet_id}{Option to plot series with faceted by a factor. A vector of 47 | series names corresponding to species names given in \code{facet_group.} 48 | Every unique values in \code{x} series.names needs to have a corresponding 49 | facet_group value. Both \code{facet_group} and \code{facet_id} need to be 50 | specified. Default plot is not faceted. Note that \code{composite_rug}, 51 | \code{facet_group}, and \code{facet_id} cannot be used in the same plot. You must 52 | choose facets or a composite rug.} 53 | 54 | \item{facet_type}{Type of ggplot2 facet to use, if faceting. Must be 55 | either "grid" or "wrap". Default is "grid". Note that \code{composite_rug}, 56 | \code{facet_group}, and \code{facet_id} cannot be used in the same plot. You must 57 | choose facets or a composite rug.} 58 | 59 | \item{ylabels}{Optional boolean to remove y-axis (series name) labels and 60 | tick marks. Default is TRUE.} 61 | 62 | \item{yearlims}{Option to limit the plot to a range of years. This is a 63 | vector with two integers. The first integer gives the lower year for the 64 | range while the second integer gives the upper year. The default is to 65 | plot the full range of data given by \code{x}.} 66 | 67 | \item{composite_rug}{A boolean option to plot a rug on the bottom of the 68 | plot. Default is FALSE. Note that \code{composite_rug} and \code{facet_group}, 69 | \code{facet_id} cannot be used in the same plot. You must choose facets or a 70 | composite rug.} 71 | 72 | \item{filter_prop}{The minimum proportion of fire events in recording series 73 | needed for fire event to be considered for composite. Default is 0.25.} 74 | 75 | \item{filter_min_rec}{The minimum number of recording series needed for a 76 | fire event to be considered for the composite. Default is 2 recording 77 | series.} 78 | 79 | \item{filter_min_events}{The minimum number of fire scars needed for a fire 80 | event to be considered for the composite. Default is 1. Fire injuries are 81 | included in this count if \code{injury_event} is \code{TRUE}.} 82 | 83 | \item{injury_event}{Boolean indicating whether injuries should be considered 84 | events. Default is \code{FALSE}.} 85 | 86 | \item{plot_legend}{A boolean option allowing the user to choose whether a 87 | legend is included in the plot or not. Default is \code{FALSE}.} 88 | 89 | \item{event_size}{An optional numeric vector that adjusts the size of fire 90 | event symbols on the plot. Default is 91 | \code{c("Scar" = 4, "Injury" = 2, "Pith/Bark" = 1.5)}.} 92 | 93 | \item{rugbuffer_size}{An optional integer. If the user plots a rug, this 94 | controls the amount of buffer whitespace along the y-axis between the rug 95 | and the main plot. Must be >= 2.} 96 | 97 | \item{rugdivide_pos}{Optional integer if plotting a rug. Adjust the 98 | placement of the rug divider along the y-axis. Default is 2.} 99 | } 100 | \value{ 101 | A \code{ggplot} object for plotting or manipulation. 102 | } 103 | \description{ 104 | Create an ggplot2 object for plotting fhx demographics 105 | } 106 | \examples{ 107 | data(lgr2) 108 | plot(lgr2) 109 | 110 | plot(lgr2, ylabels = FALSE, plot_legend = TRUE) 111 | 112 | data(lgr2_meta) 113 | # With color showing species. 114 | plot(lgr2, 115 | color_group = lgr2_meta$SpeciesID, 116 | color_id = lgr2_meta$TreeID, 117 | plot_legend = TRUE 118 | ) 119 | # With facets for each species. 120 | plot(lgr2, 121 | facet_group = lgr2_meta$SpeciesID, 122 | facet_id = lgr2_meta$TreeID, 123 | plot_legend = TRUE 124 | ) 125 | 126 | # Append annotation onto a ggplot object. 127 | require(ggplot2) 128 | p <- plot_demograph(lgr2, 129 | color_group = lgr2_meta$SpeciesID, 130 | color_id = lgr2_meta$TreeID 131 | ) 132 | # Add transparent box as annotation to plot. 133 | p + annotate("rect", 134 | xmin = 1750, xmax = 1805, 135 | ymin = 3.5, ymax = 13.5, alpha = 0.2 136 | ) 137 | 138 | } 139 | -------------------------------------------------------------------------------- /R/io.R: -------------------------------------------------------------------------------- 1 | #' Read FHX2 file and return an `fhx`` object 2 | #' 3 | #' @param fname Name of target FHX file. Needs to be in format version 2. 4 | #' @param encoding Encoding to use when reading the FHX file. The default is to 5 | #' use the system default in R. 6 | #' @param text Character string. If `fname` is not provided and text is, then 7 | #' data is read from text using a text connection. 8 | #' 9 | #' @return An `fhx` object, as returned by [fhx()]. 10 | #' 11 | #' @seealso 12 | #' * [write_fhx()] write an `fhx` object to a file. 13 | #' * [fhx()] create an `fhx` object. 14 | #' * [as_fhx()] cast data frame or similar object to an `fhx` object. 15 | #' 16 | #' @examples 17 | #' \dontrun{ 18 | #' d <- read_fhx("afile.fhx") 19 | #' } 20 | #' 21 | #' @export 22 | read_fhx <- function(fname, encoding, text) { 23 | if (missing(encoding)) { 24 | encoding <- getOption("encoding") 25 | } 26 | if (missing(fname) && !missing(text)) { 27 | con <- textConnection(text) 28 | on.exit(close(con)) 29 | } 30 | if (!missing(fname)) { 31 | con <- file(fname, encoding = encoding) 32 | on.exit(close(con)) 33 | } 34 | # Error checking and basic variables. 35 | if (length(readLines(con, n = 1)) == 0) { 36 | stop("file appears to be empty") 37 | } 38 | fl <- readLines(con, warn = FALSE) 39 | 40 | no_head_line <- !any(suppressWarnings(grepl( 41 | "^FHX2 FORMAT|^FIRE2 FORMAT", fl, 42 | ignore.case = TRUE 43 | ))) 44 | 45 | if (no_head_line) { 46 | stop("Cannot find line 'FHX2 FORMAT' or 'FIRE2 FORMAT'.") 47 | } 48 | 49 | first <- suppressWarnings(grep( 50 | "^FHX2 FORMAT|^FIRE2 FORMAT", fl, 51 | ignore.case = TRUE 52 | )) 53 | 54 | describe <- as.numeric(strsplit(fl[[first + 1]], "[ ]+")[[1]]) 55 | # First year; no. sites; length of site id. 56 | if (length(describe) != 3) { 57 | stop(paste( 58 | "Three-digit descriptive information that should be on line ", 59 | first + 1, 60 | " needs to have 3 elements separated by spaces." 61 | )) 62 | } 63 | # TODO: Need error check that row length = describe[2] + year. 64 | # TODO: Need error check that first year in body is first year in meta. 65 | # Parse series names. 66 | ## use lapply function to eliminate extra speces at end of id blocks 67 | id_block <- fl[(first + 2):(first + 1 + describe[3])] 68 | uncleaned <- as.matrix(unlist(lapply(seq_along(id_block), function(x) { 69 | splt <- unlist(strsplit(id_block[x], "")) 70 | splt <- splt[1:describe[2]] 71 | return(splt) 72 | }))) 73 | 74 | if ( (describe[2] * describe[3]) != dim(uncleaned)[1] ) { 75 | stop( 76 | "The file's three-digit descriptive information on line ", first + 1, 77 | " does not match the series titles in the file. Please correct this ", 78 | "discrepancy." 79 | ) 80 | } 81 | dim(uncleaned) <- c(describe[2], describe[3]) 82 | series_names <- apply( 83 | uncleaned, 1, 84 | function(x) gsub("^\\s+|\\s+$", "", paste(x, collapse = "")) 85 | ) 86 | 87 | databuff <- 2 88 | while (TRUE) { 89 | if (gsub("^\\s+|\\s+$", "", fl[first + databuff + describe[3]]) == "") { 90 | databuff <- databuff + 1 91 | } else { 92 | break 93 | } 94 | } 95 | 96 | no_blank_line <- !any( 97 | fl[first + databuff - 1 + describe[3]] == 98 | c("", " ", strrep(" ", describe[2])) 99 | ) 100 | if (no_blank_line) { 101 | stop("The line before the annual FHX data should be blank.") 102 | } 103 | 104 | # Filling with info from the fhx file body. 105 | fl_body <- strsplit( 106 | fl[(first + databuff + describe[3]):length(fl)], 107 | split = "" 108 | ) 109 | first_year <- describe[1] 110 | if (length(series_names) == 1) { 111 | # For whatever reason R wants to flip our dims when we have a single series. 112 | fl_body <- as.data.frame(sapply(fl_body, function(x) x[1:describe[2]]), 113 | stringsAsFactors = FALSE 114 | ) 115 | } else { 116 | fl_body <- as.data.frame(t(sapply(fl_body, function(x) x[1:describe[2]])), 117 | stringsAsFactors = FALSE 118 | ) 119 | } 120 | names(fl_body) <- series_names 121 | fl_body$year <- seq(first_year, first_year + dim(fl_body)[1] - 1) 122 | fl_body_melt <- reshape2::melt(fl_body, 123 | id.vars = "year", value.name = "rec_type", 124 | variable.name = "series", na.rm = TRUE 125 | ) 126 | fl_body_melt <- fl_body_melt[! fl_body_melt$rec_type %in% c(".", "\032"), ] 127 | fl_body_melt$rec_type <- vapply(fl_body_melt$rec_type, abrv2rec_type, "") # nolint 128 | fl_body_melt$rec_type <- make_rec_type(fl_body_melt$rec_type) 129 | f <- fhx( 130 | year = fl_body_melt$year, series = fl_body_melt$series, 131 | rec_type = fl_body_melt$rec_type 132 | ) 133 | f 134 | } 135 | 136 | 137 | #' List of character strings to write to FHX file 138 | #' 139 | #' @param x An `fhx` object. 140 | #' 141 | #' @return A list with four members containing vectors: 142 | #' * "head_line" 143 | #' * "subhead_line" 144 | #' * "series_heading" 145 | #' * "body". 146 | #' Each referring to a portion of an FHX file that the strings are dumped into. 147 | #' 148 | #' @importFrom tidyr pivot_wider 149 | #' @importFrom rlang .data 150 | #' 151 | #' @noRd 152 | list_filestrings <- function(x) { 153 | stopifnot(is_fhx(x)) 154 | out <- x 155 | out$rec_type <- vapply(out$rec_type, rec_type2abrv, "") # nolint 156 | year_range <- seq(min(out$year), max(out$year)) 157 | filler <- data.frame( 158 | year = year_range, 159 | series = rep("hackishsolution", length(year_range)), 160 | rec_type = rep(".", length(year_range)) 161 | ) 162 | out <- rbind(out, filler) 163 | out <- pivot_wider(out, 164 | names_from = .data$series, 165 | values_from = .data$rec_type, 166 | values_fill = list(rec_type = ".")) 167 | out <- out[order(out$year), ] 168 | out$hackishsolution <- NULL 169 | # Weird thing to move year to the last column of the data.frame: 170 | out$yr <- paste0(" ", out$year) 171 | out$year <- NULL 172 | series_names <- as.character(unique(x$series)) 173 | no_series <- length(series_names) 174 | max_series_name_length <- max(sapply(series_names, nchar)) 175 | head_line <- "FHX2 FORMAT" 176 | subhead_line <- paste(min(x$year), no_series, max_series_name_length) 177 | # Vertical series name heading. 178 | series_heading <- matrix(" ", nrow = max_series_name_length, ncol = no_series) 179 | for (i in seq(1, no_series)) { 180 | ingoing <- strsplit(series_names[i], split = "")[[1]] 181 | n <- length(ingoing) 182 | series_heading[1:n, i] <- ingoing 183 | } 184 | list( 185 | "head_line" = head_line, 186 | "subhead_line" = subhead_line, 187 | "series_heading" = series_heading, 188 | "body" = out 189 | ) 190 | } 191 | 192 | 193 | #' Write an `fhx` object to a new FHX2 file 194 | #' 195 | #' @param x An `fhx` object. 196 | #' @param fname Output filename. 197 | #' 198 | #' @seealso 199 | #' * [write.csv()] to write a CSV file. Also works on `fhx` objects. 200 | #' * [read_fhx()] to read an FHX2 file. 201 | #' 202 | #' @examples 203 | #' \dontrun{ 204 | #' data(lgr2) 205 | #' write_fhx(lgr2, "afile.fhx") 206 | #' } 207 | #' 208 | #' @export 209 | write_fhx <- function(x, fname = "") { 210 | if (fname == "") { 211 | stop("Please specify a character string naming a file or connection open 212 | for writing.") 213 | } 214 | if (violates_canon(x)) { 215 | warning( 216 | "`write_fhx()` run on `fhx` object with rec_types that violate FHX2", 217 | " canon - other software may not be able to read the output FHX file" 218 | ) 219 | } 220 | d <- list_filestrings(x) 221 | fl <- file(fname, open = "wt") 222 | cat(paste(d[["head_line"]], "\n", d[["subhead_line"]], "\n", sep = ""), 223 | file = fl, sep = "" 224 | ) 225 | utils::write.table(d[["series_heading"]], fl, 226 | append = TRUE, quote = FALSE, 227 | sep = "", na = "!", 228 | row.names = FALSE, col.names = FALSE 229 | ) 230 | cat("\n", file = fl, sep = "", append = TRUE) 231 | utils::write.table(d[["body"]], fl, 232 | append = TRUE, quote = FALSE, 233 | sep = "", na = "!", 234 | row.names = FALSE, col.names = FALSE 235 | ) 236 | close(fl) 237 | } 238 | 239 | 240 | #' Convert abreviated `fhx` file event char to rec_type char 241 | #' 242 | #' @param x A character string. 243 | #' 244 | #' @return A character string. 245 | #' 246 | #' @seealso [rec_type2abrc] inverse function, converting an `fhx` rec_type 247 | #' string to abbreviated character used in FHX files. 248 | #' 249 | #' @noRd 250 | abrv2rec_type <- function(x) { 251 | rec_type_all[[as.character(x)]] # nolint 252 | } 253 | 254 | 255 | #' Convert rec_type char to abreviated FHX file event char 256 | #' 257 | #' @param x A character string. 258 | #' 259 | #' @return A character string. 260 | #' 261 | #' @seealso [abrv2rec_type] inverse function, convert abbreviated character used 262 | #' in FHX files to an `fhx` rec_type string. 263 | #' 264 | #' @noRd 265 | rec_type2abrv <- function(x) { 266 | rec_type_abrv[[as.character(x)]] # nolint 267 | } 268 | -------------------------------------------------------------------------------- /data-raw/uspmw001.fhx: -------------------------------------------------------------------------------- 1 | Name of site : Pajarito Mountains North West 2 | Site code : PMW 3 | Collection date: 4 | Collectors : Craig Allen, Ramzi Touchan, Tom Swetnam 5 | Crossdaters : 6 | Number samples : 7 | Species name : Pinus ponderosa (PIPO) 8 | Common name : Ponderosa pine 9 | Habitat type : 10 | Country : USA 11 | State : NM 12 | County : 13 | Park/Monument : 14 | National Forest: Sante Fe 15 | Ranger district: 16 | Township : 17 | Range : 18 | Section : 19 | Quarter section: 20 | UTM easting : 21 | UTM northing : 22 | Latitude : 35.8967133 N 23 | Longitude : -106.4044647 E 24 | Topographic map: 25 | Lowest elev : 2860 m 26 | Highest elev : 2970 m 27 | Slope : 28 | Aspect : 29 | Area sampled : 30 | Substrate type : 31 | Begin comments BELOW this line: 32 | Principal Investigator(s) Ramzi Touchan, Thomas W. Swetnam, Craig Allen; 33 | End comments ABOVE this line: 34 | 35 | 36 | FHX2 FORMAT 37 | 1617 11 5 38 | PPPPPPPPPPP 39 | MMMMMMMMMMM 40 | WWWWWWWWWWW 41 | 00000001111 42 | 24567890124 43 | 44 | .....[..... 1617 45 | ........... 1618 46 | ........... 1619 47 | ........... 1620 48 | ........... 1621 49 | ........... 1622 50 | ........... 1623 51 | ........... 1624 52 | ........... 1625 53 | ........... 1626 54 | ........... 1627 55 | ........... 1628 56 | ........... 1629 57 | ........... 1630 58 | ........... 1631 59 | ........... 1632 60 | ........... 1633 61 | ........... 1634 62 | ........... 1635 63 | ........... 1636 64 | ........... 1637 65 | ........... 1638 66 | ........... 1639 67 | ........... 1640 68 | ........... 1641 69 | ........... 1642 70 | ........... 1643 71 | ........... 1644 72 | ........... 1645 73 | ........... 1646 74 | ........... 1647 75 | ........... 1648 76 | ........... 1649 77 | ........... 1650 78 | ........... 1651 79 | .......[... 1652 80 | ........... 1653 81 | ........... 1654 82 | ........... 1655 83 | ........... 1656 84 | ........... 1657 85 | ........... 1658 86 | ........... 1659 87 | ........... 1660 88 | ........... 1661 89 | ........... 1662 90 | ........... 1663 91 | ........... 1664 92 | ........... 1665 93 | ........... 1666 94 | ........... 1667 95 | ........... 1668 96 | .....E..... 1669 97 | .....|..... 1670 98 | .....|..... 1671 99 | .....|..... 1672 100 | .....|..... 1673 101 | .....|..... 1674 102 | .....|..... 1675 103 | .....|..... 1676 104 | .....|..... 1677 105 | .....|..... 1678 106 | .....|..... 1679 107 | .....|..... 1680 108 | .....|..... 1681 109 | .....|..... 1682 110 | .....|..... 1683 111 | .....|..... 1684 112 | .....|..... 1685 113 | .....|..... 1686 114 | .....|..... 1687 115 | .....|..... 1688 116 | .....|..... 1689 117 | .....|..... 1690 118 | .....|..... 1691 119 | .....|..... 1692 120 | .....|..... 1693 121 | .....|..... 1694 122 | .....|..... 1695 123 | .....|..... 1696 124 | .....|..... 1697 125 | .....|..... 1698 126 | .....|..... 1699 127 | .....|..... 1700 128 | .....|..... 1701 129 | .....|..... 1702 130 | .....|..... 1703 131 | .....|..... 1704 132 | .....|..... 1705 133 | .....|..... 1706 134 | .....|..... 1707 135 | .....|..... 1708 136 | .....|..... 1709 137 | .....|..... 1710 138 | .....|..... 1711 139 | .....|..... 1712 140 | .....|..... 1713 141 | .....|..... 1714 142 | .....|..... 1715 143 | .....|..... 1716 144 | .....|..... 1717 145 | .....|..... 1718 146 | .....|..... 1719 147 | .....|..... 1720 148 | .....|..... 1721 149 | .....|..... 1722 150 | .....|..... 1723 151 | .....|..... 1724 152 | .....|..... 1725 153 | .....|..... 1726 154 | .....|..... 1727 155 | .....|..... 1728 156 | .....|..... 1729 157 | .....|..... 1730 158 | .....|..... 1731 159 | .....|..... 1732 160 | .....|..... 1733 161 | .....|..... 1734 162 | .....|..... 1735 163 | .....|..... 1736 164 | .....|..... 1737 165 | .....|..... 1738 166 | .....|..... 1739 167 | .....|..... 1740 168 | .....U..... 1741 169 | .....|..... 1742 170 | .....|..... 1743 171 | .....|..... 1744 172 | .....|..... 1745 173 | .....|..... 1746 174 | .....|..... 1747 175 | .....|..... 1748 176 | .....|..... 1749 177 | .....|..... 1750 178 | .....|..... 1751 179 | .....u..... 1752 180 | .....|..... 1753 181 | .....|..... 1754 182 | .....|..... 1755 183 | .....|..... 1756 184 | .....|..... 1757 185 | .....|..... 1758 186 | .....|..... 1759 187 | .....|..... 1760 188 | .....|..... 1761 189 | .....|..... 1762 190 | .....|..... 1763 191 | .....|..... 1764 192 | .....|..... 1765 193 | .....|..... 1766 194 | .....|..... 1767 195 | .....|..... 1768 196 | .....|..... 1769 197 | .....|..... 1770 198 | .....|..... 1771 199 | .....|..... 1772 200 | .....|..... 1773 201 | .....|..... 1774 202 | .....|..... 1775 203 | .....|..... 1776 204 | .....|..... 1777 205 | .....|..... 1778 206 | .....|..... 1779 207 | .....|..... 1780 208 | .....|..... 1781 209 | .....|..... 1782 210 | .....|..... 1783 211 | .....|..... 1784 212 | .....|..... 1785 213 | .....|..... 1786 214 | .....|..... 1787 215 | .....|..... 1788 216 | .....|..... 1789 217 | .....|..... 1790 218 | .....|..... 1791 219 | .....|..... 1792 220 | .....|..... 1793 221 | .....|..... 1794 222 | .....|..... 1795 223 | .....|..... 1796 224 | .....|..... 1797 225 | .....|..... 1798 226 | .....|..... 1799 227 | .....|..... 1800 228 | .....U..... 1801 229 | .....|..... 1802 230 | .....|..... 1803 231 | .....|..... 1804 232 | .....|..... 1805 233 | .....|..... 1806 234 | .....|..... 1807 235 | .....|..... 1808 236 | .....|..... 1809 237 | .....|..... 1810 238 | .....|..... 1811 239 | .....|..... 1812 240 | .....|..... 1813 241 | .....|..[.. 1814 242 | .....|..... 1815 243 | .....|[.... 1816 244 | .....|..... 1817 245 | .....|.U... 1818 246 | .....|.|... 1819 247 | .....|.|... 1820 248 | .....|.|... 1821 249 | .....|.|... 1822 250 | .....|.|... 1823 251 | .....|.|... 1824 252 | .....|.|... 1825 253 | .....|.|... 1826 254 | .....|.|... 1827 255 | ..{..|.|... 1828 256 | .....|.|... 1829 257 | .....|.|... 1830 258 | .....|.|..[ 1831 259 | .....|.|... 1832 260 | .....|.|... 1833 261 | .....|.|... 1834 262 | .....|.|... 1835 263 | .....|.|... 1836 264 | .....|.|... 1837 265 | .....|.|... 1838 266 | .....|.|... 1839 267 | .....|.|... 1840 268 | .....|U|... 1841 269 | ....{|||... 1842 270 | .....|||... 1843 271 | .....|||... 1844 272 | .....|||... 1845 273 | .....|||... 1846 274 | U....E|UU.. 1847 275 | |....||||.. 1848 276 | |....||||.. 1849 277 | |....||||.. 1850 278 | |....||||.. 1851 279 | |....||||.. 1852 280 | |....||||.. 1853 281 | |....}|||.. 1854 282 | |.....|||.. 1855 283 | |.....|||.. 1856 284 | |.....|||.. 1857 285 | |.....|||.. 1858 286 | |.....|||.. 1859 287 | |.....|||.. 1860 288 | |{..M.|||.M 1861 289 | |...|.|||.| 1862 290 | |...|.|||.| 1863 291 | |...|.|||.| 1864 292 | |...|.|||.| 1865 293 | |...|.|||.| 1866 294 | |...|.|||.| 1867 295 | |...|.|||.| 1868 296 | |...|.|||.| 1869 297 | |...|.|||.| 1870 298 | |...|.|||.| 1871 299 | |...|.|||.| 1872 300 | |...|.|||.| 1873 301 | |...|.|||.| 1874 302 | |...|.|||.| 1875 303 | |...|.u||.| 1876 304 | |...|.|||.| 1877 305 | |...|.|||.| 1878 306 | |U..|.|||.| 1879 307 | ||..|.|||.| 1880 308 | ||..|.|||.| 1881 309 | ||..|.|||.| 1882 310 | ||..|.|||.| 1883 311 | ||..|.|||.| 1884 312 | ||..|.|||.| 1885 313 | ||..|.|||{| 1886 314 | ||..|.|||.| 1887 315 | ||..|.|||.| 1888 316 | ||..|.|||.| 1889 317 | ||..|.|d|.| 1890 318 | ||..|.|||.| 1891 319 | ||..|.|||.| 1892 320 | ||..|.|||.| 1893 321 | ||..|.|||.| 1894 322 | ||..|.|||.| 1895 323 | ||..|.|||.| 1896 324 | ||..|.|||.| 1897 325 | ||..|.|||.| 1898 326 | ||..|.|||.| 1899 327 | ||..|.|||.| 1900 328 | ||..|.|||.| 1901 329 | ||..|.|||.| 1902 330 | ||..|.|||.| 1903 331 | ||U.|.|||.| 1904 332 | |||.|.|||.| 1905 333 | |||.|.|||.| 1906 334 | |||.|.|||.| 1907 335 | |||.|.|||.| 1908 336 | |||.|.|||.| 1909 337 | |||.|.|||.| 1910 338 | |||.|.|||.| 1911 339 | |||.|.|||.| 1912 340 | |||{|.|||.| 1913 341 | |||.|.|||.| 1914 342 | |||.|.|||.| 1915 343 | |||.|.|||.| 1916 344 | |||.|.|||.| 1917 345 | |||.|.|||.| 1918 346 | |||.|.|||.| 1919 347 | |||.|.|||.| 1920 348 | |||.|.|||.| 1921 349 | |||.|.|||.| 1922 350 | |||.|.|||.| 1923 351 | |||.|.|||.| 1924 352 | |||U|.|||.| 1925 353 | |||||.|||.| 1926 354 | |||||.|||.| 1927 355 | |||||.|||.| 1928 356 | |||||.|||.| 1929 357 | |||||.|||.| 1930 358 | |||||.|||.| 1931 359 | |||||.|||.| 1932 360 | |||||.|||.| 1933 361 | |||||.|||.| 1934 362 | |||||.|||.| 1935 363 | |||||.|||u| 1936 364 | |||||.|||.| 1937 365 | |||||.|||.| 1938 366 | |||||.|||.| 1939 367 | |||||.|||.| 1940 368 | |||||.|||.| 1941 369 | ]||||.|||.| 1942 370 | .||||.|||.| 1943 371 | .||||.|||.| 1944 372 | .||||.|||.| 1945 373 | .||||.|||.| 1946 374 | .||||.|||.| 1947 375 | .||||.|||.| 1948 376 | .||||.|||.| 1949 377 | .||||.|||.| 1950 378 | .||||.|||.| 1951 379 | .||||.|||.| 1952 380 | .||||.|||.| 1953 381 | .||||.|||.| 1954 382 | .||||.|||.| 1955 383 | .||||.|||.| 1956 384 | .||||.u||.| 1957 385 | .||||.|||.| 1958 386 | .||||.|||.| 1959 387 | .||||.|||.| 1960 388 | .||||.|||.| 1961 389 | .||||.|||.| 1962 390 | .||||.|||.| 1963 391 | .||||.|||.| 1964 392 | .||||.|||u| 1965 393 | .||||.|||.| 1966 394 | .||||.|||.| 1967 395 | .||||.|||.| 1968 396 | .||||.|||.| 1969 397 | .||||.|||.| 1970 398 | .||||.|||.| 1971 399 | .||||.|||.| 1972 400 | .||||.|||.| 1973 401 | .||||.|||.| 1974 402 | .||||.|||.| 1975 403 | .||||.|||.| 1976 404 | .||||.|||.| 1977 405 | .||||.|||.| 1978 406 | .||||.|||.| 1979 407 | .||||.|||.| 1980 408 | .||||.|||.| 1981 409 | .||||.|||.| 1982 410 | .||||.|||.| 1983 411 | .||||.|||.| 1984 412 | .||||.|||.| 1985 413 | .||||.|||.| 1986 414 | .||||.|||.| 1987 415 | .||||.|||.| 1988 416 | .||||.|||.| 1989 417 | .||||.|||]| 1990 418 | .||||.|||.| 1991 419 | .||||.|||.| 1992 420 | .]}]].]]].] 1993 421 | -------------------------------------------------------------------------------- /vignettes/uspmw001.fhx: -------------------------------------------------------------------------------- 1 | Name of site : Pajarito Mountains North West 2 | Site code : PMW 3 | Collection date: 4 | Collectors : Craig Allen, Ramzi Touchan, Tom Swetnam 5 | Crossdaters : 6 | Number samples : 7 | Species name : Pinus ponderosa (PIPO) 8 | Common name : Ponderosa pine 9 | Habitat type : 10 | Country : USA 11 | State : NM 12 | County : 13 | Park/Monument : 14 | National Forest: Sante Fe 15 | Ranger district: 16 | Township : 17 | Range : 18 | Section : 19 | Quarter section: 20 | UTM easting : 21 | UTM northing : 22 | Latitude : 35.8967133 N 23 | Longitude : -106.4044647 E 24 | Topographic map: 25 | Lowest elev : 2860 m 26 | Highest elev : 2970 m 27 | Slope : 28 | Aspect : 29 | Area sampled : 30 | Substrate type : 31 | Begin comments BELOW this line: 32 | Principal Investigator(s) Ramzi Touchan, Thomas W. Swetnam, Craig Allen; 33 | End comments ABOVE this line: 34 | 35 | 36 | FHX2 FORMAT 37 | 1617 11 5 38 | PPPPPPPPPPP 39 | MMMMMMMMMMM 40 | WWWWWWWWWWW 41 | 00000001111 42 | 24567890124 43 | 44 | .....[..... 1617 45 | ........... 1618 46 | ........... 1619 47 | ........... 1620 48 | ........... 1621 49 | ........... 1622 50 | ........... 1623 51 | ........... 1624 52 | ........... 1625 53 | ........... 1626 54 | ........... 1627 55 | ........... 1628 56 | ........... 1629 57 | ........... 1630 58 | ........... 1631 59 | ........... 1632 60 | ........... 1633 61 | ........... 1634 62 | ........... 1635 63 | ........... 1636 64 | ........... 1637 65 | ........... 1638 66 | ........... 1639 67 | ........... 1640 68 | ........... 1641 69 | ........... 1642 70 | ........... 1643 71 | ........... 1644 72 | ........... 1645 73 | ........... 1646 74 | ........... 1647 75 | ........... 1648 76 | ........... 1649 77 | ........... 1650 78 | ........... 1651 79 | .......[... 1652 80 | ........... 1653 81 | ........... 1654 82 | ........... 1655 83 | ........... 1656 84 | ........... 1657 85 | ........... 1658 86 | ........... 1659 87 | ........... 1660 88 | ........... 1661 89 | ........... 1662 90 | ........... 1663 91 | ........... 1664 92 | ........... 1665 93 | ........... 1666 94 | ........... 1667 95 | ........... 1668 96 | .....E..... 1669 97 | .....|..... 1670 98 | .....|..... 1671 99 | .....|..... 1672 100 | .....|..... 1673 101 | .....|..... 1674 102 | .....|..... 1675 103 | .....|..... 1676 104 | .....|..... 1677 105 | .....|..... 1678 106 | .....|..... 1679 107 | .....|..... 1680 108 | .....|..... 1681 109 | .....|..... 1682 110 | .....|..... 1683 111 | .....|..... 1684 112 | .....|..... 1685 113 | .....|..... 1686 114 | .....|..... 1687 115 | .....|..... 1688 116 | .....|..... 1689 117 | .....|..... 1690 118 | .....|..... 1691 119 | .....|..... 1692 120 | .....|..... 1693 121 | .....|..... 1694 122 | .....|..... 1695 123 | .....|..... 1696 124 | .....|..... 1697 125 | .....|..... 1698 126 | .....|..... 1699 127 | .....|..... 1700 128 | .....|..... 1701 129 | .....|..... 1702 130 | .....|..... 1703 131 | .....|..... 1704 132 | .....|..... 1705 133 | .....|..... 1706 134 | .....|..... 1707 135 | .....|..... 1708 136 | .....|..... 1709 137 | .....|..... 1710 138 | .....|..... 1711 139 | .....|..... 1712 140 | .....|..... 1713 141 | .....|..... 1714 142 | .....|..... 1715 143 | .....|..... 1716 144 | .....|..... 1717 145 | .....|..... 1718 146 | .....|..... 1719 147 | .....|..... 1720 148 | .....|..... 1721 149 | .....|..... 1722 150 | .....|..... 1723 151 | .....|..... 1724 152 | .....|..... 1725 153 | .....|..... 1726 154 | .....|..... 1727 155 | .....|..... 1728 156 | .....|..... 1729 157 | .....|..... 1730 158 | .....|..... 1731 159 | .....|..... 1732 160 | .....|..... 1733 161 | .....|..... 1734 162 | .....|..... 1735 163 | .....|..... 1736 164 | .....|..... 1737 165 | .....|..... 1738 166 | .....|..... 1739 167 | .....|..... 1740 168 | .....U..... 1741 169 | .....|..... 1742 170 | .....|..... 1743 171 | .....|..... 1744 172 | .....|..... 1745 173 | .....|..... 1746 174 | .....|..... 1747 175 | .....|..... 1748 176 | .....|..... 1749 177 | .....|..... 1750 178 | .....|..... 1751 179 | .....u..... 1752 180 | .....|..... 1753 181 | .....|..... 1754 182 | .....|..... 1755 183 | .....|..... 1756 184 | .....|..... 1757 185 | .....|..... 1758 186 | .....|..... 1759 187 | .....|..... 1760 188 | .....|..... 1761 189 | .....|..... 1762 190 | .....|..... 1763 191 | .....|..... 1764 192 | .....|..... 1765 193 | .....|..... 1766 194 | .....|..... 1767 195 | .....|..... 1768 196 | .....|..... 1769 197 | .....|..... 1770 198 | .....|..... 1771 199 | .....|..... 1772 200 | .....|..... 1773 201 | .....|..... 1774 202 | .....|..... 1775 203 | .....|..... 1776 204 | .....|..... 1777 205 | .....|..... 1778 206 | .....|..... 1779 207 | .....|..... 1780 208 | .....|..... 1781 209 | .....|..... 1782 210 | .....|..... 1783 211 | .....|..... 1784 212 | .....|..... 1785 213 | .....|..... 1786 214 | .....|..... 1787 215 | .....|..... 1788 216 | .....|..... 1789 217 | .....|..... 1790 218 | .....|..... 1791 219 | .....|..... 1792 220 | .....|..... 1793 221 | .....|..... 1794 222 | .....|..... 1795 223 | .....|..... 1796 224 | .....|..... 1797 225 | .....|..... 1798 226 | .....|..... 1799 227 | .....|..... 1800 228 | .....U..... 1801 229 | .....|..... 1802 230 | .....|..... 1803 231 | .....|..... 1804 232 | .....|..... 1805 233 | .....|..... 1806 234 | .....|..... 1807 235 | .....|..... 1808 236 | .....|..... 1809 237 | .....|..... 1810 238 | .....|..... 1811 239 | .....|..... 1812 240 | .....|..... 1813 241 | .....|..[.. 1814 242 | .....|..... 1815 243 | .....|[.... 1816 244 | .....|..... 1817 245 | .....|.U... 1818 246 | .....|.|... 1819 247 | .....|.|... 1820 248 | .....|.|... 1821 249 | .....|.|... 1822 250 | .....|.|... 1823 251 | .....|.|... 1824 252 | .....|.|... 1825 253 | .....|.|... 1826 254 | .....|.|... 1827 255 | ..{..|.|... 1828 256 | .....|.|... 1829 257 | .....|.|... 1830 258 | .....|.|..[ 1831 259 | .....|.|... 1832 260 | .....|.|... 1833 261 | .....|.|... 1834 262 | .....|.|... 1835 263 | .....|.|... 1836 264 | .....|.|... 1837 265 | .....|.|... 1838 266 | .....|.|... 1839 267 | .....|.|... 1840 268 | .....|U|... 1841 269 | ....{|||... 1842 270 | .....|||... 1843 271 | .....|||... 1844 272 | .....|||... 1845 273 | .....|||... 1846 274 | U....E|UU.. 1847 275 | |....||||.. 1848 276 | |....||||.. 1849 277 | |....||||.. 1850 278 | |....||||.. 1851 279 | |....||||.. 1852 280 | |....||||.. 1853 281 | |....}|||.. 1854 282 | |.....|||.. 1855 283 | |.....|||.. 1856 284 | |.....|||.. 1857 285 | |.....|||.. 1858 286 | |.....|||.. 1859 287 | |.....|||.. 1860 288 | |{..M.|||.M 1861 289 | |...|.|||.| 1862 290 | |...|.|||.| 1863 291 | |...|.|||.| 1864 292 | |...|.|||.| 1865 293 | |...|.|||.| 1866 294 | |...|.|||.| 1867 295 | |...|.|||.| 1868 296 | |...|.|||.| 1869 297 | |...|.|||.| 1870 298 | |...|.|||.| 1871 299 | |...|.|||.| 1872 300 | |...|.|||.| 1873 301 | |...|.|||.| 1874 302 | |...|.|||.| 1875 303 | |...|.u||.| 1876 304 | |...|.|||.| 1877 305 | |...|.|||.| 1878 306 | |U..|.|||.| 1879 307 | ||..|.|||.| 1880 308 | ||..|.|||.| 1881 309 | ||..|.|||.| 1882 310 | ||..|.|||.| 1883 311 | ||..|.|||.| 1884 312 | ||..|.|||.| 1885 313 | ||..|.|||{| 1886 314 | ||..|.|||.| 1887 315 | ||..|.|||.| 1888 316 | ||..|.|||.| 1889 317 | ||..|.|d|.| 1890 318 | ||..|.|||.| 1891 319 | ||..|.|||.| 1892 320 | ||..|.|||.| 1893 321 | ||..|.|||.| 1894 322 | ||..|.|||.| 1895 323 | ||..|.|||.| 1896 324 | ||..|.|||.| 1897 325 | ||..|.|||.| 1898 326 | ||..|.|||.| 1899 327 | ||..|.|||.| 1900 328 | ||..|.|||.| 1901 329 | ||..|.|||.| 1902 330 | ||..|.|||.| 1903 331 | ||U.|.|||.| 1904 332 | |||.|.|||.| 1905 333 | |||.|.|||.| 1906 334 | |||.|.|||.| 1907 335 | |||.|.|||.| 1908 336 | |||.|.|||.| 1909 337 | |||.|.|||.| 1910 338 | |||.|.|||.| 1911 339 | |||.|.|||.| 1912 340 | |||{|.|||.| 1913 341 | |||.|.|||.| 1914 342 | |||.|.|||.| 1915 343 | |||.|.|||.| 1916 344 | |||.|.|||.| 1917 345 | |||.|.|||.| 1918 346 | |||.|.|||.| 1919 347 | |||.|.|||.| 1920 348 | |||.|.|||.| 1921 349 | |||.|.|||.| 1922 350 | |||.|.|||.| 1923 351 | |||.|.|||.| 1924 352 | |||U|.|||.| 1925 353 | |||||.|||.| 1926 354 | |||||.|||.| 1927 355 | |||||.|||.| 1928 356 | |||||.|||.| 1929 357 | |||||.|||.| 1930 358 | |||||.|||.| 1931 359 | |||||.|||.| 1932 360 | |||||.|||.| 1933 361 | |||||.|||.| 1934 362 | |||||.|||.| 1935 363 | |||||.|||u| 1936 364 | |||||.|||.| 1937 365 | |||||.|||.| 1938 366 | |||||.|||.| 1939 367 | |||||.|||.| 1940 368 | |||||.|||.| 1941 369 | ]||||.|||.| 1942 370 | .||||.|||.| 1943 371 | .||||.|||.| 1944 372 | .||||.|||.| 1945 373 | .||||.|||.| 1946 374 | .||||.|||.| 1947 375 | .||||.|||.| 1948 376 | .||||.|||.| 1949 377 | .||||.|||.| 1950 378 | .||||.|||.| 1951 379 | .||||.|||.| 1952 380 | .||||.|||.| 1953 381 | .||||.|||.| 1954 382 | .||||.|||.| 1955 383 | .||||.|||.| 1956 384 | .||||.u||.| 1957 385 | .||||.|||.| 1958 386 | .||||.|||.| 1959 387 | .||||.|||.| 1960 388 | .||||.|||.| 1961 389 | .||||.|||.| 1962 390 | .||||.|||.| 1963 391 | .||||.|||.| 1964 392 | .||||.|||u| 1965 393 | .||||.|||.| 1966 394 | .||||.|||.| 1967 395 | .||||.|||.| 1968 396 | .||||.|||.| 1969 397 | .||||.|||.| 1970 398 | .||||.|||.| 1971 399 | .||||.|||.| 1972 400 | .||||.|||.| 1973 401 | .||||.|||.| 1974 402 | .||||.|||.| 1975 403 | .||||.|||.| 1976 404 | .||||.|||.| 1977 405 | .||||.|||.| 1978 406 | .||||.|||.| 1979 407 | .||||.|||.| 1980 408 | .||||.|||.| 1981 409 | .||||.|||.| 1982 410 | .||||.|||.| 1983 411 | .||||.|||.| 1984 412 | .||||.|||.| 1985 413 | .||||.|||.| 1986 414 | .||||.|||.| 1987 415 | .||||.|||.| 1988 416 | .||||.|||.| 1989 417 | .||||.|||]| 1990 418 | .||||.|||.| 1991 419 | .||||.|||.| 1992 420 | .]}]].]]].] 1993 421 | -------------------------------------------------------------------------------- /vignettes/introduction.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Introduction to burnr" 3 | author: "S. Brewster Malevich" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Introduction to burnr} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | \usepackage[utf8]{inputenc} 10 | --- 11 | 12 | This is a brief tutorial to cover some general ideas and basic features in burnr. This is a simple tutorial so you won't need crazy coding skills. I am going to assume that you have a [recent version of R](https://www.r-project.org) installed and are familiar with the basics of R. 13 | 14 | If you are not familiar with R, hit Google with the search "R stat tutorial", or some variation there of. You will find a plethora of useful learning material and helpful people from a wide array of backgrounds. 15 | 16 | People pickup this coding stuff more quickly if they try the examples I give and play around with the interesting things they discover. I recommend you open a terminal with an R session and follow along as you read this. It's more fun that way. 17 | 18 | ## What's burnr? 19 | 20 | burnr is a package for forest fire history analysis in the R statistical environment. This package isn't designed to be a comprehensive suite for fire analysis. Rather the idea is to provide a transparent, flexible, and powerful set of core tools. 21 | 22 | -------- 23 | 24 | ## Citing burnr in your research 25 | 26 | Please cite our peer-reviewed paper introducing burnr. The preferred citation is: 27 | 28 | > Malevich, Steven B., Christopher H. Guiterman, and Ellis Q. Margolis. 2018. “Burnr: Fire History Analysis and Graphics in R.” Dendrochronologia 49 (June): 9–15. https://doi.org/10.1016/j.dendro.2018.02.005. 29 | 30 | You can see also this information by running `citation('burnr')` in an R session. 31 | 32 | -------- 33 | 34 | ## Install burnr 35 | 36 | You can install burnr from the CRAN repository with: 37 | 38 | ```r 39 | install.packages('burnr') 40 | ``` 41 | 42 | Most burnr development is centered at https://github.com/ltrr-arizona-edu/burnr. If I get hit by a bus, the people at the Laboratory of Tree-Ring Research will hopefully make sure that burnr doesn't disappear. You can download burnr directly from this github repository with the `devtools` package: 43 | 44 | ```r 45 | devtools::install_github('ltrr-arizona-edu/burnr') 46 | ``` 47 | 48 | Note that this will give you the bleeding-edge, development version of the package. It changes often and it may be unstable. Beware. 49 | 50 | Once burnr has been installed, you can load it just as you'd load any other R package 51 | 52 | ```{r} 53 | library('burnr') 54 | ``` 55 | 56 | and you're good to go. 57 | 58 | ## Reading and writing fire history data 59 | 60 | Loading data from FHX files is fairly straightforward. 61 | 62 | ```r 63 | d <- read_fhx('my_fhx_file.fhx') 64 | ``` 65 | 66 | This loads any given FHX file into an fhx object in R and assigns it to the `d` variable. 67 | 68 | We can also write simple FHX files from fhx objects in R: 69 | 70 | ```r 71 | write_fhx(d, fname = 'notacreativeoutputfilename.fhx') 72 | ``` 73 | 74 | Fairly straightforward stuff. 75 | 76 | ## Manipulating fhx objects 77 | 78 | The fhx objects are like very specialized data.frames. We can do some useful things with these fhx objects. Let's use some example fhx objects that we bundled with burnr (or you can read in your own FHX files). 79 | 80 | ```{r} 81 | data(lgr2) # fire data from Los Griegos Peak, New Mexico 82 | 83 | head(lgr2) 84 | ``` 85 | Peaking at the head of the `lgr2` data shows that we have information about the years of observations, the series (which can correspond to a tree, sample, plot, site, whatever you like), and the type of record for a given year. You'll notice that we don't keep track of "null" years. Removing null years lets us keep the code quick and nimble (usually). 86 | 87 | Looking at the structure of the `lgr2` object can give us some more technical details, if that's your thing: 88 | 89 | ```{r} 90 | str(lgr2) 91 | ``` 92 | 93 | The important thing to keep in mind is you can parse these fhx objects all you like, but be careful modifying or changing an fhx object's data with your own functions as this might have unintended consequences. Manually modifying the data is something I recommend for advanced (or brave) users with a working knowledge of R's S3 classes and generic function. 94 | 95 | Let's pull in another example dataset and combine it with `lgr2`. 96 | 97 | ```{r} 98 | data(pgm) # Peggy Mesa fire data. 99 | 100 | both <- lgr2 + pgm 101 | ``` 102 | 103 | As you might suspect, `both` is a concatenation, combing the fire information in `lgr2` and `pgm`. We can prove this by looking at the series names. 104 | 105 | ```{r} 106 | series_names(lgr2) 107 | 108 | series_names(both) 109 | ``` 110 | 111 | We can also delete specific series or years from an fhx object. 112 | 113 | ```r 114 | delete(lgr2, s = 'LGR46') # Remove series. 115 | delete(lgr2, yr = 1752) # Remove year from all series. 116 | delete(lgr2, s = 'LGR46', yr = 1752) # Remove year from select series. 117 | ``` 118 | Note that our use of `delete()` is not modifying `lgr2` in place. `lgr2` is unchanged unless we assign the output of `delete()` back to the `lgr2` variable. 119 | 120 | Use `help()` to find more information on these functions. Be sure to check out `get_series()`, `get_year()`, and `sort.fhx()`. 121 | 122 | ## Basic plotting 123 | 124 | Now that we have some fire data in R, let's put this into real use! The simplest way to plot an fhx object, is to use the `plot()` function. 125 | 126 | ```{r} 127 | plot(lgr2) 128 | ``` 129 | 130 | This gives us a fire history demographic plot. Solid circles indicate "solid" starting and stopping dates (i.e. "pith-date", "bark-date"). Triangles indicate any kind of fire event. You will also notice that solid lines in a series are periods when the tree is sensitive to fire events ("recording"). The dashed line indicates periods when the tree is not sensitive to fire events. Back when I first started writing burnr in 2011 - 2012, one of the main goals of the package was to easily plot a *ridiculous* amount of fire-history data. The package's spartan plotting design is a consequence of this. 131 | 132 | We can clean things up by removing the labels on the y-axis. 133 | 134 | ```{r} 135 | plot(lgr2, ylabels = FALSE) 136 | ``` 137 | 138 | We can also add color to our plots. This is one of the fancier features of burnr, that will hopefully become standard for fire-history analysis tools. First, we'll load in some metadata for the `lgr2` object. 139 | 140 | ```{r} 141 | data(lgr2_meta) 142 | 143 | head(lgr2_meta) 144 | ``` 145 | 146 | `lgr2_meta` is just a data.frame that links series names with extra information like sample species. These can easily be made for your own data. The cool thing is how we use this information in our plots. 147 | 148 | ```{r} 149 | plot(lgr2, 150 | color_group = lgr2_meta$SpeciesID, 151 | color_id = lgr2_meta$TreeID, 152 | ylabels = FALSE, 153 | plot_legend = TRUE) # Include a legend! 154 | ``` 155 | 156 | Now that we add color, we can see our data suggests a change in species composition from PIPO (*Pinus ponderosa*) to PSME (*Pseudotsuga menziesii*) and POTR (*Populus tremuloides*). The help function, `help(lgr2)`, will give you more information on `lgr2` if you're curious. 157 | 158 | Alternatively, we can create a faceted plot using the same information. 159 | 160 | ```{r} 161 | plot(lgr2, 162 | facet_group = lgr2_meta$SpeciesID, 163 | facet_id = lgr2_meta$TreeID, 164 | ylabels = FALSE) 165 | ``` 166 | 167 | Generally, people use the color to represent species and then use facets for different sample locations (yes, you can use colors and facets together). I've seen facets from site data create plots large enough to plaster across an office wall. It looks cool. Some people find it helpful. 168 | 169 | ## Advanced plotting 170 | 171 | Plotting in burnr does not use the base plotting system in R. Instead, our plotting is handled by the grid-based ggplot2 package. This give us a way to create sophisticated plots that are modular and user customizable. The drawback to this is that ggplot2 graphics have a steep learning curve and can seem obtuse to new (or advanced) users who are used to other plotting systems. 172 | 173 | Beneath its simple exterior the `plot()` method passes its plotting to `plot_demograph()`. The key here is that `plot_demograph()` returns ggplot objects which you can modify. So, lets load the ggplot2 package and create the same colored fire demographic plots that we created above. But this time, we'll capture the function's output. 174 | 175 | ```{r} 176 | library(ggplot2) 177 | p <- plot_demograph(lgr2, 178 | color_group = lgr2_meta$SpeciesID, 179 | color_id = lgr2_meta$TreeID) 180 | print(p) 181 | ``` 182 | 183 | Same as before, but without the legend. Now, let's can use the output from `plot_demographic()` to add an annotation: 184 | 185 | ```{r} 186 | # Add transparent box as annotation to plot. 187 | p + annotate('rect', 188 | xmin = 1750, xmax = 1805, 189 | ymin = 3.5, ymax = 13.5, alpha = 0.2) 190 | ``` 191 | 192 | We can annotate with text to point out something "important" (ha ha). 193 | 194 | ```{r} 195 | p + annotate('text', x = 1650, y = 7.5, label = 'important!') 196 | ``` 197 | 198 | We can use the same approach to change plot colors, labels, etc. Try adding ggplot2's `theme_grey()` and see what happens! Using what you've learned, try to combine the `lgr2` and `pgm` objects and create a plot with facets for each of these locations. You can load burnr's `pgm_meta` if you need. 199 | 200 | Check out ggplot2 (https://ggplot2.tidyverse.org/) to learn more. 201 | -------------------------------------------------------------------------------- /tests/testthat/test-utils.R: -------------------------------------------------------------------------------- 1 | library(burnr) 2 | context("Utils") 3 | 4 | data(lgr2) 5 | TARGET_SERIES <- "LGR53" 6 | REF_MULTI <- lgr2 7 | REF_SINGLE <- get_series(REF_MULTI, TARGET_SERIES) 8 | 9 | test_that("spotcheck get_series", { 10 | test_subj <- get_series(REF_MULTI, TARGET_SERIES) 11 | expect_true(all(test_subj$series == TARGET_SERIES)) 12 | }) 13 | 14 | test_that("make_rec_type handles single character vector", { 15 | test_subj <- make_rec_type("late_fs") 16 | expect_true(is.factor(test_subj)) 17 | expect_equal(length(levels(test_subj)), length(burnr:::rec_type_all)) 18 | }) 19 | 20 | test_that("make_rec_type handles multiple character vector", { 21 | test_subj <- make_rec_type(c("null_year", "late_fs")) 22 | expect_equal(length(test_subj), 2) 23 | expect_true(is.factor(test_subj)) 24 | expect_equal(length(levels(test_subj)), length(burnr:::rec_type_all)) 25 | }) 26 | 27 | test_that("make_rec_type throws error on bad levels", { 28 | expect_error(make_rec_type("BACON!"), "not TRUE") 29 | expect_error(make_rec_type(c("null_year", "BACON!")), "not all TRUE") 30 | }) 31 | 32 | test_that("series_names on single series", { 33 | expect_match(series_names(REF_SINGLE), TARGET_SERIES) 34 | }) 35 | 36 | test_that("series_names on multi-series FHX object", { 37 | a <- c( 38 | "LGR54", "LGR44", "LGR47", "LGR48", "LGR46", "LGR41", "LGR52", 39 | "LGR51", "LGR45", "LGR49", "LGR53", "LGR43", "LGR55", "LGR56", 40 | "LGR36", "LGR33", "LGR31", "LGR32", "LGR27", "LGR29", "LGR25", 41 | "LGR35", "LGR30", "LGR26", "LGR42", "LGR34" 42 | ) 43 | test_subj <- series_names(REF_MULTI) 44 | expect_true(length(union(a, test_subj)) == length(a)) 45 | }) 46 | 47 | test_that("get_year on single series", { 48 | test_subj <- get_year(REF_SINGLE, 1825) 49 | expect_match(as.character(test_subj$series), TARGET_SERIES) 50 | expect_equal(test_subj$year, 1825) 51 | expect_match(as.character(test_subj$rec_type), "recorder_year") 52 | }) 53 | 54 | test_that("delete series on multi-series FHX object", { 55 | test_subj <- delete(REF_MULTI, s = TARGET_SERIES) 56 | expect_false(TARGET_SERIES %in% series_names(test_subj)) 57 | }) 58 | 59 | test_that("delete year on multi-series FHX object", { 60 | target_year <- 1825 61 | test_subj <- delete(REF_MULTI, yr = target_year) 62 | expect_false(target_year %in% series_names(test_subj)) 63 | }) 64 | 65 | test_that("delete series and year on multi-series FHX object", { 66 | target_year <- 1825 67 | test_subj <- delete(REF_MULTI, s = TARGET_SERIES, yr = target_year) 68 | expect_false( 69 | as.character(TARGET_SERIES) 70 | %in% as.character(series_names(get_year(test_subj, target_year))) 71 | ) 72 | expect_false(target_year %in% get_series(test_subj, TARGET_SERIES)$year) 73 | }) 74 | 75 | test_that("year_range on multi-series FHX object", { 76 | test_subj <- year_range(REF_MULTI) 77 | expect_true(all(test_subj == c(1366, 2012))) 78 | }) 79 | 80 | test_that("count_event_position on FHX object without injuries as events", { 81 | test_subj <- count_event_position(REF_MULTI) 82 | expect_equal(subset(test_subj, event == "unknown_fs")$count, 2) 83 | expect_equal(subset(test_subj, event == "early_fs")$count, 4) 84 | }) 85 | 86 | test_that("count_event_position on FHX object with injuries as events", { 87 | test_subj <- count_event_position(REF_MULTI, injury_event = TRUE) 88 | expect_equal(subset(test_subj, event == "unknown_fs")$count, 2) 89 | expect_equal(subset(test_subj, event == "unknown_fi")$count, 6) 90 | }) 91 | 92 | ## Depreciated argument 93 | # test_that("count_event_position on FHX object with multiple select positions", { 94 | # test_subj <- count_event_position( 95 | # REF_MULTI, 96 | # position = c("unknown", "dormant") 97 | # ) 98 | # expect_equal(subset(test_subj, event == "dormant_fs")$count, 3) 99 | # expect_equal(subset(test_subj, event == "unknown_fs")$count, 2) 100 | # expect_false("early_fs" %in% as.character(test_subj$event)) 101 | # }) 102 | 103 | test_that("count_event_position on FHX object groupby list", { 104 | grplist <- list( 105 | foo = c("unknown_fs", "early_fs"), 106 | bar = c("dormant_fs", "unknown_fi") 107 | ) 108 | test_subj <- count_event_position(REF_MULTI, groupby = grplist) 109 | ## Events not listed in groupby are not inlcuded in output 110 | # expect_equal(subset(test_subj, event == "unknown_fs")$count, 2) 111 | # expect_equal(subset(test_subj, event == "early_fs")$count, 4) 112 | expect_equal(subset(test_subj, event == "foo")$count, 6) 113 | expect_equal(subset(test_subj, event == "bar")$count, 3) 114 | }) 115 | 116 | 117 | test_that("sort.fhx on FHX object by first_year", { 118 | goal <- c("a", "b") 119 | test_fhx <- fhx( 120 | year = c(1850, 2010, 1900, 2000), 121 | series = factor(c("a", "a", "b", "b")), 122 | rec_type = c( 123 | "pith_year", "bark_year", 124 | "pith_year", "bark_year" 125 | ) 126 | ) 127 | sorted <- sort(test_fhx) 128 | expect_equal(goal, levels(sorted$series)) 129 | }) 130 | 131 | test_that("sort.fhx on FHX object by first_year with decreasing=TRUE", { 132 | goal <- c("b", "a") 133 | test_fhx <- fhx( 134 | year = c(1850, 2010, 1900, 2000), 135 | series = factor(c("a", "a", "b", "b")), 136 | rec_type = c( 137 | "pith_year", "bark_year", 138 | "pith_year", "bark_year" 139 | ) 140 | ) 141 | sorted <- sort(test_fhx, sort_by = "first_year", decreasing = TRUE) 142 | expect_equal(goal, levels(sorted$series)) 143 | }) 144 | 145 | 146 | test_that("sort.fhx on FHX object by last_year", { 147 | goal <- c("b", "a") 148 | test_fhx <- fhx( 149 | year = c(1850, 2010, 1900, 2000), 150 | series = factor(c("a", "a", "b", "b")), 151 | rec_type = c( 152 | "pith_year", "bark_year", 153 | "pith_year", "bark_year" 154 | ) 155 | ) 156 | sorted <- sort(test_fhx, sort_by = "last_year") 157 | expect_equal(goal, levels(sorted$series)) 158 | }) 159 | 160 | test_that("+.fhx on FHX objects", { 161 | year1 <- c(1850, 2010) 162 | series1 <- c("a", "a") 163 | rt1 <- c("pith_year", "bark_year") 164 | year2 <- c(1900, 2000) 165 | series2 <- c("b", "b") 166 | rt2 <- c("pith_year", "bark_year") 167 | test_fhx1 <- fhx( 168 | year = year1, 169 | series = factor(series1), 170 | rec_type = rt1 171 | ) 172 | test_fhx2 <- fhx( 173 | year = year2, 174 | series = factor(series2), 175 | rec_type = rt2 176 | ) 177 | test_fhx3 <- test_fhx1 + test_fhx2 178 | expect_equal(test_fhx3$year, c(year1, year2)) 179 | expect_equal(test_fhx3$series, factor(c(series1, series2))) 180 | expect_equal(test_fhx3$rec_type, make_rec_type(c(rt1, rt2))) 181 | }) 182 | 183 | test_that("check_duplicates returns with OK fhx obj", { 184 | test_fhx <- fhx( 185 | year = c(1850, 2010, 1900, 2000), 186 | series = factor(c("a", "a", "b", "b")), 187 | rec_type = c( 188 | "pith_year", "bark_year", 189 | "pith_year", "bark_year" 190 | ) 191 | ) 192 | checked <- burnr:::check_duplicates(test_fhx) 193 | expect_equal(test_fhx, checked) 194 | }) 195 | 196 | test_that("check_duplicates throws error when fhx obj has duplicates", { 197 | test_fhx <- fhx( 198 | year = c(1850, 2010, 1900, 2000), 199 | series = factor(c("a", "a", "b", "b")), 200 | rec_type = c( 201 | "pith_year", "bark_year", 202 | "pith_year", "bark_year" 203 | ) 204 | ) 205 | test_fhx <- rbind(test_fhx, test_fhx) 206 | expect_error( 207 | burnr:::check_duplicates(test_fhx), 208 | "*Please resolve duplicate records*" 209 | ) 210 | }) 211 | 212 | test_that("as_fhx works on data.frame input", { 213 | yrs <- c(1850, 2010) 214 | series_chr <- c("a", "a") 215 | events_chr <- c("pith_year", "bark_year") 216 | 217 | test_df <- data.frame( 218 | year = yrs, 219 | series = series_chr, 220 | rec_type = events_chr 221 | ) 222 | 223 | new_fhx <- burnr::as_fhx(test_df) 224 | expect_equal(new_fhx$year, yrs) 225 | expect_equal(new_fhx$series, factor(series_chr)) 226 | expect_equal(new_fhx$rec_type, burnr::make_rec_type(events_chr)) 227 | }) 228 | 229 | test_that("as_fhx works on list input", { 230 | yrs <- c(1850, 2010) 231 | series_chr <- c("a", "a") 232 | events_chr <- c("pith_year", "bark_year") 233 | 234 | test_df <- list( 235 | year = yrs, 236 | series = series_chr, 237 | rec_type = events_chr 238 | ) 239 | 240 | new_fhx <- burnr::as_fhx(test_df) 241 | expect_equal(new_fhx$year, yrs) 242 | expect_equal(new_fhx$series, factor(series_chr)) 243 | expect_equal(new_fhx$rec_type, burnr::make_rec_type(events_chr)) 244 | }) 245 | 246 | test_that("as_fhx throws error when input missing key element", { 247 | yrs <- c(1850, 2010) 248 | series_chr <- c("a", "a") 249 | events_chr <- c("pith_year", "bark_year") 250 | 251 | test_df <- list( 252 | year = yrs, 253 | serie = series_chr, # bad spelling 254 | rec_type = events_chr 255 | ) 256 | 257 | expect_error( 258 | burnr:::as_fhx(test_df), 259 | "`x` must have members 'year', 'series', and 'rec_type'" 260 | ) 261 | }) 262 | 263 | 264 | test_that("internal violates_canon catches bad, passes good", { 265 | test_case_good <- fhx( 266 | year = c(1850, 2010), 267 | series = c("a", "a"), 268 | rec_type = c("pith_year", "bark_year") 269 | ) 270 | 271 | test_case_bad <- fhx( 272 | year = c(1850, 2010), 273 | series = c("a", "a"), 274 | rec_type = c("pith_year", "estimate") 275 | ) 276 | 277 | expect_true(!burnr:::violates_canon(test_case_good)) 278 | expect_true(burnr:::violates_canon(test_case_bad)) 279 | }) 280 | 281 | 282 | test_that("composite returns empty fhx when no fire events", { 283 | test_case <- fhx( 284 | year = c(1850, 2010), 285 | series = c("a", "a"), 286 | rec_type = c("pith_year", "bark_year") 287 | ) 288 | test_comp <- composite(test_case) 289 | 290 | empty_fhx <- fhx(as.numeric(c()), as.factor(c()), make_rec_type(c())) 291 | 292 | expect_equal(test_comp, empty_fhx) 293 | }) 294 | 295 | 296 | test_that("composite returns empty fhx when no worthy fire events", { 297 | test_case <- fhx( 298 | year = c(1850, 2010, 1860, 2005), 299 | series = c("a", "a", "b", "b"), 300 | rec_type = c("pith_year", "unknown_fs", "inner_year", "unknown_fs") 301 | ) 302 | test_comp <- composite(test_case) 303 | 304 | empty_fhx <- fhx(as.numeric(c()), as.factor(c()), make_rec_type(c())) 305 | 306 | expect_equal(test_comp, empty_fhx) 307 | }) 308 | -------------------------------------------------------------------------------- /R/stats.R: -------------------------------------------------------------------------------- 1 | #' Generate series-level descriptive statistics for `fhx` object 2 | #' 3 | #' @param x An `fhx` object. 4 | #' @param func_list A list of named functions that will be run on each series 5 | #' in the `fhx` object. The list name for each function is the corresponding 6 | #' column name in the output data frame. 7 | #' 8 | #' @return A `data.frame` containing series-level statistics. 9 | #' 10 | #' @seealso 11 | #' * [fhx()] creates an `fhx` object. 12 | #' * [as_fhx()] casts data frame into an `fhx` object. 13 | #' * [first_year()] gets earliest year in an `fhx` object. 14 | #' * [last_year()] gets latest year in an `fhx` object. 15 | #' * [count_year_span()] counts the year span of an `fhx` object. 16 | #' * [inner_type()] gets "rec_type" for inner event of an `fhx` object. 17 | #' * [outer_type()] get "rec_type" for outside event of an `fhx` object. 18 | #' * [count_scar()] counts scars in an `fhx` object. 19 | #' * [count_injury()] counts injuries in an `fhx` object. 20 | #' * [count_recording()] counts recording years in `fhx` object. 21 | #' * [series_mean_interval()] quickly estimates mean fire-interval of `fhx` 22 | #' object. 23 | #' * [sample_depth()] gets sample depth of an `fhx` object. 24 | #' * [summary.fhx()] brief summary of an `fhx` object. 25 | #' * [composite()] create a fire `composite` from an `fhx` object. 26 | #' * [intervals()] get fire `intervals` analysis from `composite`. 27 | #' * [sea()] superposed epoch analysis. 28 | #' 29 | #' @examples 30 | #' data(lgr2) 31 | #' series_stats(lgr2) 32 | #' 33 | #' # You can create your own list of statistics to output. You can also create 34 | #' # your own functions: 35 | #' flist <- list( 36 | #' n = count_year_span, 37 | #' xbar_interval = function(x) mean_interval(x, injury_event = TRUE) 38 | #' ) 39 | #' sstats <- series_stats(lgr2) 40 | #' head(sstats) 41 | #' @export 42 | series_stats <- function(x, func_list = list( 43 | first = first_year, last = last_year, 44 | years = count_year_span, 45 | inner_type = inner_type, outer_type = outer_type, 46 | number_scars = count_scar, 47 | number_injuries = count_injury, 48 | recording_years = count_recording, 49 | mean_interval = series_mean_interval 50 | )) { 51 | stopifnot(is_fhx(x)) 52 | plyr::ddply(x, c("series"), 53 | function(df) data.frame(lapply(func_list, function(f) f(df))) 54 | ) 55 | } 56 | 57 | 58 | #' First (earliest) year of an `fhx` object 59 | #' 60 | #' @param x An `fhx` object. 61 | #' 62 | #' @return The minimum or first year of series in `x`. 63 | #' 64 | #' @seealso 65 | #' * [last_year()] get last year of `fhx` object. 66 | #' * [series_stats()] basic statistics for series in an `fhx` object. 67 | #' 68 | #' @export 69 | first_year <- function(x) { 70 | min(x$year) 71 | } 72 | 73 | 74 | #' Last (most recent) year of an `fhx` object 75 | #' 76 | #' @param x An `fhx` object. 77 | #' 78 | #' @return The maximum or last year of series in `x`. `NA` will be returned if 79 | #' `NA` is in `x$year`. 80 | #' 81 | #' @seealso 82 | #' * [first_year()] get first year of `fhx` object. 83 | #' * [series_stats()] basic statistics for series in an `fhx` object. 84 | #' 85 | #' @export 86 | last_year <- function(x) { 87 | max(x$year) 88 | } 89 | 90 | 91 | #' Number of years of an `fhx` object 92 | #' 93 | #' @param x An `fhx` object. 94 | #' 95 | #' @return The difference between the first and last observations in the `fhx` 96 | #' object. `NA` will be returned if `NA` is in `x$year`. 97 | #' 98 | #' @seealso 99 | #' * [first_year()] get first year of `fhx` object. 100 | #' * [last_year()] get last year of `fhx` object. 101 | #' * [series_stats()] basic statistics for series in an `fhx` object. 102 | #' 103 | #' @export 104 | count_year_span <- function(x) { 105 | max(x$year) - min(x$year) + 1 106 | } 107 | 108 | 109 | #' Type of observation in the last (most recent) year of an `fhx` object 110 | #' 111 | #' @param x An `fhx` object. 112 | #' 113 | #' @return The a factor giving the type of observation in the last observation 114 | #' of `x`. 115 | #' 116 | #' @seealso 117 | #' * [inner_type()] get observation type in inner-most year of `fhx` object. 118 | #' * [series_stats()] basic statistics for series in an `fhx` object. 119 | #' 120 | #' @export 121 | outer_type <- function(x) { 122 | x$rec_type[which.max(x$year)] 123 | } 124 | 125 | 126 | #' Type of observation in the first (earliest) year of an `fhx` object 127 | #' 128 | #' @param x An `fhx` object. 129 | #' 130 | #' @return The a factor giving the type of observation in the first observation 131 | #' of `x`. 132 | #' 133 | #' @seealso 134 | #' * [outer_type()] get observation type in outer-most year of `fhx` object. 135 | #' * [series_stats()] basic statistics for series in an `fhx` object. 136 | #' 137 | #' @export 138 | inner_type <- function(x) { 139 | x$rec_type[which.min(x$year)] 140 | } 141 | 142 | 143 | #' Number of scar events in an `fhx` object 144 | #' 145 | #' @param x An `fhx` object. 146 | #' 147 | #' @return The number of fire scar events in `x` 148 | #' 149 | #' @seealso 150 | #' * [count_injury()] Count the injuries in an `fhx` object. 151 | #' * [series_stats()] basic statistics for series in an `fhx` object. 152 | #' 153 | #' @export 154 | count_scar <- function(x) { 155 | length(grep("_fs", x$rec_type)) 156 | } 157 | 158 | 159 | #' Number of injury events in an `fhx` object 160 | #' 161 | #' @param x An `fhx` object. 162 | #' 163 | #' @return The number of injury events in `x` 164 | #' 165 | #' @seealso 166 | #' * [count_scar()] Count the injuries in an `fhx` object. 167 | #' * [series_stats()] basic statistics for series in an `fhx` object. 168 | #' 169 | #' @export 170 | count_injury <- function(x) { 171 | length(grep("_fi", x$rec_type)) 172 | } 173 | 174 | 175 | #' Number of recording years in an `fhx` object 176 | #' 177 | #' @param x An `fhx` object. 178 | #' @param injury_event Boolean indicating whether injuries should be considered 179 | #' event. 180 | #' 181 | #' @return The number of recording events in `x`. 182 | #' 183 | #' @seealso [series_stats()] basic statistics for series in an `fhx` object. 184 | #' 185 | #' @export 186 | count_recording <- function(x, injury_event = FALSE) { 187 | nrow(find_recording(x, injury_event = injury_event)) 188 | } 189 | 190 | 191 | #' Calculate quick mean fire interval of an `fhx` object with single series 192 | #' 193 | #' You really should be using [intervals()]. 194 | #' 195 | #' @param x An `fhx` object with a single series. 196 | #' @param injury_event Boolean indicating whether injuries should be considered 197 | #' event. 198 | #' 199 | #' @return The mean fire interval observed `x`. 200 | #' 201 | #' @seealso 202 | #' * [intervals()] Proper way to do fire-interval analysis of `fhx` object. 203 | #' * [series_stats()] basic statistics for series in an `fhx` object. 204 | #' 205 | #' @export 206 | series_mean_interval <- function(x, injury_event = FALSE) { 207 | if (length(unique(x$series)) > 1) { 208 | warning( 209 | "`series_mean_interval()` run on object with multiple series - ", 210 | "results may not be correct" 211 | ) 212 | } 213 | search_str <- "_fs" 214 | if (injury_event) { 215 | search_str <- paste0("_fi|", search_str) 216 | } 217 | event_years <- sort(x$year[grepl(search_str, x$rec_type)]) 218 | out <- NA 219 | if (length(event_years) > 1) { 220 | intervals <- diff(event_years) 221 | out <- round(mean(intervals), 1) 222 | } 223 | out 224 | } 225 | 226 | #' Calculate the sample depth of an `fhx` object 227 | #' 228 | #' @param x An `fhx` object. 229 | #' 230 | #' @return A data frame containing the years and number of observations. 231 | #' 232 | #' @seealso [series_stats()] basic statistics for series in an `fhx` object. 233 | #' 234 | #' @export 235 | sample_depth <- function(x) { 236 | if (!is_fhx(x)) stop("x must be an fhx object") 237 | x_stats <- series_stats(x) 238 | n_trees <- nrow(x_stats) 239 | out <- data.frame(year = min(x_stats$first):max(x_stats$last)) 240 | for (i in 1:n_trees) { 241 | yrs <- x_stats[i, ]$first:x_stats[i, ]$last 242 | treespan <- data.frame(year = yrs, z = 1) 243 | names(treespan)[2] <- paste(x_stats$series[i]) 244 | out <- merge(out, treespan, by = c("year"), all = TRUE) 245 | } 246 | if (n_trees > 1) { 247 | out$samp_depth <- rowSums(out[, -1], na.rm = TRUE) 248 | } 249 | else { 250 | out$samp_depth <- out[, -1] 251 | } 252 | out <- subset(out, select = c("year", "samp_depth")) 253 | return(out) 254 | } 255 | 256 | 257 | #' Summary of `fhx` object 258 | #' 259 | #' @param object An `fhx` object. 260 | #' @param ... Additional arguments that are tossed out. 261 | #' 262 | #' @return A `summary.fhx` object. 263 | #' 264 | #' @seealso [series_stats()] basic statistics for series in an `fhx` object. 265 | #' 266 | #' @export 267 | summary.fhx <- function(object, ...) { 268 | out <- list( 269 | number_series = length(series_names(object)), 270 | first_year = first_year(object), 271 | last_year = last_year(object), 272 | number_scars = count_scar(object), 273 | number_injuries = count_injury(object) 274 | ) 275 | class(out) <- "summary.fhx" 276 | out 277 | } 278 | 279 | 280 | #' Percent scarred time series for `fhx` object 281 | #' 282 | #' @param x An `fhx` object. 283 | #' @param injury_event Boolean indicating whether years with injury events 284 | #' should be considered as scars. Default is `FALSE`. 285 | #' 286 | #' @return `data.frame` with four columns: 287 | #' * "Year": The year. 288 | #' * "NumRec": The number of recording trees. 289 | #' * "NumScars": Number of fire scars and possibly fire injuries. 290 | #' * "PercScarred": The proportion of scars (and possibly injuries) to 291 | #' non-scar/injury series in the year. 292 | #' 293 | #' @seealso [series_stats()] basic statistics for series in an `fhx` object. 294 | #' 295 | #' @examples 296 | #' data("pgm") 297 | #' percent_scarred(pgm) 298 | #' @export 299 | percent_scarred <- function(x, injury_event = FALSE) { 300 | series_rec <- plyr::ddply(x, "series", find_recording, injury_event = TRUE) 301 | rec_count <- plyr::count(series_rec, "recording") 302 | series_fs <- x[grepl("_fs", x$rec_type), ] 303 | fs_count <- plyr::count(series_fs, "year") 304 | if (injury_event) { 305 | series_fs <- x[grepl("_fs", x$rec_type) | grepl("_fi", x$rec_type), ] 306 | fs_count <- plyr::count(series_fs, "year") 307 | } 308 | out <- merge(rec_count, fs_count, 309 | by.x = "recording", by.y = "year", all = TRUE 310 | ) 311 | names(out) <- c("year", "num_rec", "num_scars") 312 | out[is.na(out$num_scars), "num_scars"] <- 0 313 | out$percent_scarred <- round(out$num_scars / out$num_rec * 100, 0) 314 | return(out) 315 | } 316 | -------------------------------------------------------------------------------- /data-raw/uspme001.fhx: -------------------------------------------------------------------------------- 1 | Name of site : Pajarito Mountains North East 2 | Site code : PME 3 | Collection date: 4 | Collectors : Craig Allen, Ramzi Touchan, Tom Swetnam 5 | Crossdaters : 6 | Number samples : 7 | Species name : Conifer spp (CONI) 8 | Common name : conifer 9 | Habitat type : 10 | Country : USA 11 | State : NM 12 | County : 13 | Park/Monument : 14 | National Forest: Sante Fe 15 | Ranger district: 16 | Township : 17 | Range : 18 | Section : 19 | Quarter section: 20 | UTM easting : 21 | UTM northing : 22 | Latitude : 35.88583 N 23 | Longitude : -106.369 E 24 | Topographic map: 25 | Lowest elev : 2850 m 26 | Highest elev : 3075 m 27 | Slope : 28 | Aspect : 29 | Area sampled : 30 | Substrate type : 31 | Begin comments BELOW this line: 32 | Principal Investigator(s) Ramzi Touchan, Thomas W. Swetnam, Craig Allen; 33 | Mixed conifer 34 | End comments ABOVE this line: 35 | 36 | FHX2 FORMAT 37 | 1617 17 5 38 | PPPPPPPPPPPPPPPPP 39 | MMMMMMMMMMMMMMMMM 40 | EEEEEEEEEEEEEEEEE 41 | 00000000111111111 42 | 12345689012356789 43 | 44 | ................. 1617 45 | ................. 1618 46 | ................. 1619 47 | ................. 1620 48 | ................. 1621 49 | ................. 1622 50 | ................. 1623 51 | ................. 1624 52 | ................. 1625 53 | ................. 1626 54 | ................. 1627 55 | ................. 1628 56 | ................. 1629 57 | ................. 1630 58 | ................. 1631 59 | ................. 1632 60 | ................. 1633 61 | ................. 1634 62 | ................. 1635 63 | ................. 1636 64 | ................. 1637 65 | ................. 1638 66 | ................. 1639 67 | ................. 1640 68 | ................. 1641 69 | ................. 1642 70 | ................. 1643 71 | ................. 1644 72 | ................. 1645 73 | ................. 1646 74 | ................. 1647 75 | ................. 1648 76 | ................. 1649 77 | ................. 1650 78 | ................. 1651 79 | ................. 1652 80 | ................. 1653 81 | ................. 1654 82 | ................. 1655 83 | ................. 1656 84 | ................. 1657 85 | ................. 1658 86 | ................. 1659 87 | ................. 1660 88 | ................. 1661 89 | ................. 1662 90 | ................. 1663 91 | ................. 1664 92 | ................. 1665 93 | ................. 1666 94 | ................. 1667 95 | ................. 1668 96 | ................. 1669 97 | ................. 1670 98 | ................. 1671 99 | ................. 1672 100 | ................. 1673 101 | ................. 1674 102 | ................. 1675 103 | ................. 1676 104 | ................. 1677 105 | ................. 1678 106 | ................. 1679 107 | ................. 1680 108 | ................. 1681 109 | ................. 1682 110 | ................. 1683 111 | ................. 1684 112 | ................. 1685 113 | ................. 1686 114 | ................. 1687 115 | ................. 1688 116 | ................. 1689 117 | ................. 1690 118 | ................. 1691 119 | ................. 1692 120 | ................. 1693 121 | ................. 1694 122 | ................. 1695 123 | ................. 1696 124 | ................. 1697 125 | ................. 1698 126 | ................. 1699 127 | ................. 1700 128 | ................. 1701 129 | ........[........ 1702 130 | ................. 1703 131 | ................. 1704 132 | ................. 1705 133 | ..........[...... 1706 134 | ................. 1707 135 | ................. 1708 136 | ................. 1709 137 | ................. 1710 138 | ................. 1711 139 | ................. 1712 140 | ................. 1713 141 | ................. 1714 142 | ................. 1715 143 | ................. 1716 144 | ................. 1717 145 | ................. 1718 146 | ................. 1719 147 | ................. 1720 148 | ................. 1721 149 | ................. 1722 150 | ................. 1723 151 | ................. 1724 152 | ................. 1725 153 | ................. 1726 154 | ................. 1727 155 | ................. 1728 156 | ................. 1729 157 | ................. 1730 158 | ................. 1731 159 | ................. 1732 160 | .........[....... 1733 161 | ................. 1734 162 | ................. 1735 163 | ................. 1736 164 | ................. 1737 165 | ................. 1738 166 | ................. 1739 167 | ................. 1740 168 | ................. 1741 169 | ................. 1742 170 | ................. 1743 171 | ................. 1744 172 | ...........[..... 1745 173 | ................. 1746 174 | ................. 1747 175 | ................. 1748 176 | ................. 1749 177 | .......[......... 1750 178 | ..[.............. 1751 179 | ................. 1752 180 | ................. 1753 181 | ................. 1754 182 | ................. 1755 183 | ................. 1756 184 | ................. 1757 185 | ................. 1758 186 | ................. 1759 187 | .[............... 1760 188 | ................. 1761 189 | ................. 1762 190 | ................. 1763 191 | ................. 1764 192 | ................. 1765 193 | ................. 1766 194 | ................. 1767 195 | ............{.... 1768 196 | ................. 1769 197 | ................. 1770 198 | ................. 1771 199 | ...............[. 1772 200 | ..........U...... 1773 201 | ..........|...... 1774 202 | ..........|...... 1775 203 | ..........|...... 1776 204 | ..........|...... 1777 205 | ..........|...... 1778 206 | ..........|L..... 1779 207 | ..........||..... 1780 208 | ..........||..... 1781 209 | ..........||..... 1782 210 | ..........||..... 1783 211 | ..........||..... 1784 212 | ..........||..... 1785 213 | ..........||..... 1786 214 | ..........||..... 1787 215 | ..........||..... 1788 216 | ..........||..... 1789 217 | ...[......||..... 1790 218 | ..........||..... 1791 219 | ..........||..... 1792 220 | ..........||..... 1793 221 | ..........||..... 1794 222 | ..........||..... 1795 223 | ..........||..... 1796 224 | ..........||..... 1797 225 | ..........||..... 1798 226 | ..........||..... 1799 227 | ..........||..... 1800 228 | ........M.E|...U. 1801 229 | ........|.||...|. 1802 230 | ........|.||...|. 1803 231 | ........|.||...|. 1804 232 | ........|.||...|. 1805 233 | ........|.||...|. 1806 234 | ........|.||...|. 1807 235 | ........|.||...|. 1808 236 | ........|.||...|. 1809 237 | ........|.||...|. 1810 238 | ........|.||...|. 1811 239 | ........|.||...|. 1812 240 | ........|.||...|. 1813 241 | ........|.||...|. 1814 242 | ........|.||...|. 1815 243 | ........|.||...|. 1816 244 | ........|.||...|. 1817 245 | ........|.||...|. 1818 246 | ........|.||...|. 1819 247 | ........|.||...|. 1820 248 | ........|.||...|. 1821 249 | ........U.||...M. 1822 250 | ........|.||...|. 1823 251 | ........|.||...|. 1824 252 | .U......|.||...|. 1825 253 | .|......|.||.{.|. 1826 254 | .|......|.||...|. 1827 255 | .|......|.||...|. 1828 256 | .|......|.||...|. 1829 257 | .|......|.||..[|. 1830 258 | {|......|.||...|. 1831 259 | .|......|.||...|. 1832 260 | .|......|.||...|. 1833 261 | .|......|.||...|. 1834 262 | .|......|.||...|. 1835 263 | .|......|.||...|. 1836 264 | .|......|.||...|. 1837 265 | .|......|.||...|. 1838 266 | .|......|.||...|. 1839 267 | .|......|.||...|. 1840 268 | .|......|.||...|. 1841 269 | .|......|.||...|. 1842 270 | .|......|.||...|. 1843 271 | .|......|.||...|. 1844 272 | .|......|.||...|. 1845 273 | .|......|.||...|. 1846 274 | .|.....U|E||...E. 1847 275 | .|.....|||||...|. 1848 276 | .|.....|||||...|. 1849 277 | .|.....|||||...|. 1850 278 | .|....U|||||...|. 1851 279 | m|....||||||...|. 1852 280 | .|....||||||...|. 1853 281 | .|....||||||...|. 1854 282 | .|....||||||...|. 1855 283 | u|....||||||...|. 1856 284 | .|....||||||...|. 1857 285 | .|....||||||...|. 1858 286 | .|....||||||...|. 1859 287 | .|....||||||...|. 1860 288 | .|.U..||||u|E..D. 1861 289 | .|.|..|||||||..|. 1862 290 | .|.|..|||||||..|. 1863 291 | .|.|..|||||||..|. 1864 292 | .|.|..u||||||..|. 1865 293 | .|.|..|||||||..|. 1866 294 | .|.|..|||||||..|. 1867 295 | .|.|..|||||||..|. 1868 296 | .|.|..|||||||..|. 1869 297 | .|.|..|||||||..|. 1870 298 | .|.|..|||||||..|. 1871 299 | .|.|..|||||||..|. 1872 300 | .|.|..|||||||..|. 1873 301 | .|.|..|||||||..|. 1874 302 | .|.|[.|||||||.MM. 1875 303 | .|.|..|||||||.||. 1876 304 | .|.|..|||||||.||. 1877 305 | .|.|..|||||||.||. 1878 306 | .|MU.U|U|L|||.||. 1879 307 | .|||.||||||||.||. 1880 308 | .|||.||||||||.||. 1881 309 | .|||.||||||||.||. 1882 310 | .|||.||||||||.||. 1883 311 | .||u.||||||||.||. 1884 312 | .|||.||||||||.||. 1885 313 | .|||.||||||||.||. 1886 314 | .|||.||||||||.||[ 1887 315 | .|||.||||||||.||. 1888 316 | .|||.||||||||.||. 1889 317 | .|||.||||||||.||. 1890 318 | .|||.||||||||.||. 1891 319 | .|||.||||||||.||. 1892 320 | .|||.|||||u||.||. 1893 321 | .|||.||||||||.||. 1894 322 | .|||.||||||||.||. 1895 323 | .|||.||||||||.||. 1896 324 | .|||.||A|||||.||. 1897 325 | .|||.||||||||.||. 1898 326 | .|||.||||||||.||. 1899 327 | .|||.||||||||.||. 1900 328 | .|||.||||||||.||. 1901 329 | .|||.||||||||.||. 1902 330 | .|||.||||||||.||. 1903 331 | .|||.||||||||.||. 1904 332 | .|||.||||||||.||. 1905 333 | .|||.||||||||.||. 1906 334 | .|||.||||||||.||. 1907 335 | .|||.||||||||.||. 1908 336 | .|||.||||||||.||. 1909 337 | .|U|.||||||||.||. 1910 338 | .|||.||||||||.||. 1911 339 | .|||.||||||||.||. 1912 340 | .|||.||||||||.||. 1913 341 | .|||.||||||||.||. 1914 342 | .|||.||||||||.||. 1915 343 | .|||.||||||||.||. 1916 344 | .|||.||||||||.||. 1917 345 | .|||.||||||||.||. 1918 346 | .|||.||||||||.||. 1919 347 | .|||.||||||||.||. 1920 348 | .|||.||||||||.||. 1921 349 | .|||.||||||||.||. 1922 350 | .|||.||||||||.||. 1923 351 | .||}.||||||||.||. 1924 352 | .||..||||||||.||. 1925 353 | .||..||||||||.||. 1926 354 | .||..||||||||.||. 1927 355 | .||..||||||||.||. 1928 356 | .||..||||||||.||. 1929 357 | .||..||||||||.||. 1930 358 | .||..||||||||.||. 1931 359 | .||..||||||||.||. 1932 360 | .||..||||||||.||. 1933 361 | .||..||||||||.||. 1934 362 | .||..||||||||.||. 1935 363 | .||..||||||||.||. 1936 364 | .||..|}||||||.||. 1937 365 | .||..|.||||||.||. 1938 366 | .||..|.||||||.||. 1939 367 | .||..|.||||||.||. 1940 368 | .||..|.||||||.||. 1941 369 | .||.A|.||||||.||. 1942 370 | .||.||.||||||.||. 1943 371 | .||.||.||||||.||. 1944 372 | .||.||.||||||.||. 1945 373 | .||.||.||||||.||. 1946 374 | .||.||.||||||.||. 1947 375 | .||.||.||||||.||. 1948 376 | .||.||.||||||U||. 1949 377 | .||.||.|||||||||. 1950 378 | .||.||.|||||||||. 1951 379 | .||.||.|||||||||. 1952 380 | .||.||.|||||||||. 1953 381 | .||.||.|||||||||. 1954 382 | .||.||.|||||||||. 1955 383 | .||.||.|||||||||. 1956 384 | .||.||.|||||||||. 1957 385 | .||.||.|||||||||. 1958 386 | .||.||.|||||||||. 1959 387 | .||.||.|||||||||. 1960 388 | .||.u|.|||||||||. 1961 389 | .||.||.|||||||||A 1962 390 | .|u.||.|||||||||| 1963 391 | .||.||.|||||||||| 1964 392 | .||.||.|||||||||| 1965 393 | .||.||.|||||||||| 1966 394 | .||.||.|||||||||| 1967 395 | .||.||.|||||||||| 1968 396 | .||.||.|||||||||| 1969 397 | .||.||.|||||||||| 1970 398 | .||.||.]||||||||| 1971 399 | .]|.||..||||||||| 1972 400 | ..|.||..||||||||| 1973 401 | ..|.||..||||||||| 1974 402 | ..|.||..||}|||||| 1975 403 | ..|.||..||.|||||| 1976 404 | ..|.||..||.|||||| 1977 405 | ..|.]|..||.|||||| 1978 406 | ..|..|..||.|||||| 1979 407 | ..|..|..||.|||||| 1980 408 | ..|..|..||.|||||| 1981 409 | ..|..|..||.|||||| 1982 410 | ..|..|..||.|||||| 1983 411 | ..|..|..||.|||||| 1984 412 | ..|..|..||.|||||} 1985 413 | ..|..|..||.|||||. 1986 414 | ..|..|..|}.|||||. 1987 415 | ..|..|..|..|||||. 1988 416 | ..|..|..|..||||]. 1989 417 | ..|..|..|..]]|}.. 1990 418 | ].|..|..]....|... 1991 419 | ..|..|.......|... 1992 420 | ..]..].......]... 1993 421 | -------------------------------------------------------------------------------- /vignettes/uspme001.fhx: -------------------------------------------------------------------------------- 1 | Name of site : Pajarito Mountains North East 2 | Site code : PME 3 | Collection date: 4 | Collectors : Craig Allen, Ramzi Touchan, Tom Swetnam 5 | Crossdaters : 6 | Number samples : 7 | Species name : Conifer spp (CONI) 8 | Common name : conifer 9 | Habitat type : 10 | Country : USA 11 | State : NM 12 | County : 13 | Park/Monument : 14 | National Forest: Sante Fe 15 | Ranger district: 16 | Township : 17 | Range : 18 | Section : 19 | Quarter section: 20 | UTM easting : 21 | UTM northing : 22 | Latitude : 35.88583 N 23 | Longitude : -106.369 E 24 | Topographic map: 25 | Lowest elev : 2850 m 26 | Highest elev : 3075 m 27 | Slope : 28 | Aspect : 29 | Area sampled : 30 | Substrate type : 31 | Begin comments BELOW this line: 32 | Principal Investigator(s) Ramzi Touchan, Thomas W. Swetnam, Craig Allen; 33 | Mixed conifer 34 | End comments ABOVE this line: 35 | 36 | FHX2 FORMAT 37 | 1617 17 5 38 | PPPPPPPPPPPPPPPPP 39 | MMMMMMMMMMMMMMMMM 40 | EEEEEEEEEEEEEEEEE 41 | 00000000111111111 42 | 12345689012356789 43 | 44 | ................. 1617 45 | ................. 1618 46 | ................. 1619 47 | ................. 1620 48 | ................. 1621 49 | ................. 1622 50 | ................. 1623 51 | ................. 1624 52 | ................. 1625 53 | ................. 1626 54 | ................. 1627 55 | ................. 1628 56 | ................. 1629 57 | ................. 1630 58 | ................. 1631 59 | ................. 1632 60 | ................. 1633 61 | ................. 1634 62 | ................. 1635 63 | ................. 1636 64 | ................. 1637 65 | ................. 1638 66 | ................. 1639 67 | ................. 1640 68 | ................. 1641 69 | ................. 1642 70 | ................. 1643 71 | ................. 1644 72 | ................. 1645 73 | ................. 1646 74 | ................. 1647 75 | ................. 1648 76 | ................. 1649 77 | ................. 1650 78 | ................. 1651 79 | ................. 1652 80 | ................. 1653 81 | ................. 1654 82 | ................. 1655 83 | ................. 1656 84 | ................. 1657 85 | ................. 1658 86 | ................. 1659 87 | ................. 1660 88 | ................. 1661 89 | ................. 1662 90 | ................. 1663 91 | ................. 1664 92 | ................. 1665 93 | ................. 1666 94 | ................. 1667 95 | ................. 1668 96 | ................. 1669 97 | ................. 1670 98 | ................. 1671 99 | ................. 1672 100 | ................. 1673 101 | ................. 1674 102 | ................. 1675 103 | ................. 1676 104 | ................. 1677 105 | ................. 1678 106 | ................. 1679 107 | ................. 1680 108 | ................. 1681 109 | ................. 1682 110 | ................. 1683 111 | ................. 1684 112 | ................. 1685 113 | ................. 1686 114 | ................. 1687 115 | ................. 1688 116 | ................. 1689 117 | ................. 1690 118 | ................. 1691 119 | ................. 1692 120 | ................. 1693 121 | ................. 1694 122 | ................. 1695 123 | ................. 1696 124 | ................. 1697 125 | ................. 1698 126 | ................. 1699 127 | ................. 1700 128 | ................. 1701 129 | ........[........ 1702 130 | ................. 1703 131 | ................. 1704 132 | ................. 1705 133 | ..........[...... 1706 134 | ................. 1707 135 | ................. 1708 136 | ................. 1709 137 | ................. 1710 138 | ................. 1711 139 | ................. 1712 140 | ................. 1713 141 | ................. 1714 142 | ................. 1715 143 | ................. 1716 144 | ................. 1717 145 | ................. 1718 146 | ................. 1719 147 | ................. 1720 148 | ................. 1721 149 | ................. 1722 150 | ................. 1723 151 | ................. 1724 152 | ................. 1725 153 | ................. 1726 154 | ................. 1727 155 | ................. 1728 156 | ................. 1729 157 | ................. 1730 158 | ................. 1731 159 | ................. 1732 160 | .........[....... 1733 161 | ................. 1734 162 | ................. 1735 163 | ................. 1736 164 | ................. 1737 165 | ................. 1738 166 | ................. 1739 167 | ................. 1740 168 | ................. 1741 169 | ................. 1742 170 | ................. 1743 171 | ................. 1744 172 | ...........[..... 1745 173 | ................. 1746 174 | ................. 1747 175 | ................. 1748 176 | ................. 1749 177 | .......[......... 1750 178 | ..[.............. 1751 179 | ................. 1752 180 | ................. 1753 181 | ................. 1754 182 | ................. 1755 183 | ................. 1756 184 | ................. 1757 185 | ................. 1758 186 | ................. 1759 187 | .[............... 1760 188 | ................. 1761 189 | ................. 1762 190 | ................. 1763 191 | ................. 1764 192 | ................. 1765 193 | ................. 1766 194 | ................. 1767 195 | ............{.... 1768 196 | ................. 1769 197 | ................. 1770 198 | ................. 1771 199 | ...............[. 1772 200 | ..........U...... 1773 201 | ..........|...... 1774 202 | ..........|...... 1775 203 | ..........|...... 1776 204 | ..........|...... 1777 205 | ..........|...... 1778 206 | ..........|L..... 1779 207 | ..........||..... 1780 208 | ..........||..... 1781 209 | ..........||..... 1782 210 | ..........||..... 1783 211 | ..........||..... 1784 212 | ..........||..... 1785 213 | ..........||..... 1786 214 | ..........||..... 1787 215 | ..........||..... 1788 216 | ..........||..... 1789 217 | ...[......||..... 1790 218 | ..........||..... 1791 219 | ..........||..... 1792 220 | ..........||..... 1793 221 | ..........||..... 1794 222 | ..........||..... 1795 223 | ..........||..... 1796 224 | ..........||..... 1797 225 | ..........||..... 1798 226 | ..........||..... 1799 227 | ..........||..... 1800 228 | ........M.E|...U. 1801 229 | ........|.||...|. 1802 230 | ........|.||...|. 1803 231 | ........|.||...|. 1804 232 | ........|.||...|. 1805 233 | ........|.||...|. 1806 234 | ........|.||...|. 1807 235 | ........|.||...|. 1808 236 | ........|.||...|. 1809 237 | ........|.||...|. 1810 238 | ........|.||...|. 1811 239 | ........|.||...|. 1812 240 | ........|.||...|. 1813 241 | ........|.||...|. 1814 242 | ........|.||...|. 1815 243 | ........|.||...|. 1816 244 | ........|.||...|. 1817 245 | ........|.||...|. 1818 246 | ........|.||...|. 1819 247 | ........|.||...|. 1820 248 | ........|.||...|. 1821 249 | ........U.||...M. 1822 250 | ........|.||...|. 1823 251 | ........|.||...|. 1824 252 | .U......|.||...|. 1825 253 | .|......|.||.{.|. 1826 254 | .|......|.||...|. 1827 255 | .|......|.||...|. 1828 256 | .|......|.||...|. 1829 257 | .|......|.||..[|. 1830 258 | {|......|.||...|. 1831 259 | .|......|.||...|. 1832 260 | .|......|.||...|. 1833 261 | .|......|.||...|. 1834 262 | .|......|.||...|. 1835 263 | .|......|.||...|. 1836 264 | .|......|.||...|. 1837 265 | .|......|.||...|. 1838 266 | .|......|.||...|. 1839 267 | .|......|.||...|. 1840 268 | .|......|.||...|. 1841 269 | .|......|.||...|. 1842 270 | .|......|.||...|. 1843 271 | .|......|.||...|. 1844 272 | .|......|.||...|. 1845 273 | .|......|.||...|. 1846 274 | .|.....U|E||...E. 1847 275 | .|.....|||||...|. 1848 276 | .|.....|||||...|. 1849 277 | .|.....|||||...|. 1850 278 | .|....U|||||...|. 1851 279 | m|....||||||...|. 1852 280 | .|....||||||...|. 1853 281 | .|....||||||...|. 1854 282 | .|....||||||...|. 1855 283 | u|....||||||...|. 1856 284 | .|....||||||...|. 1857 285 | .|....||||||...|. 1858 286 | .|....||||||...|. 1859 287 | .|....||||||...|. 1860 288 | .|.U..||||u|E..D. 1861 289 | .|.|..|||||||..|. 1862 290 | .|.|..|||||||..|. 1863 291 | .|.|..|||||||..|. 1864 292 | .|.|..u||||||..|. 1865 293 | .|.|..|||||||..|. 1866 294 | .|.|..|||||||..|. 1867 295 | .|.|..|||||||..|. 1868 296 | .|.|..|||||||..|. 1869 297 | .|.|..|||||||..|. 1870 298 | .|.|..|||||||..|. 1871 299 | .|.|..|||||||..|. 1872 300 | .|.|..|||||||..|. 1873 301 | .|.|..|||||||..|. 1874 302 | .|.|[.|||||||.MM. 1875 303 | .|.|..|||||||.||. 1876 304 | .|.|..|||||||.||. 1877 305 | .|.|..|||||||.||. 1878 306 | .|MU.U|U|L|||.||. 1879 307 | .|||.||||||||.||. 1880 308 | .|||.||||||||.||. 1881 309 | .|||.||||||||.||. 1882 310 | .|||.||||||||.||. 1883 311 | .||u.||||||||.||. 1884 312 | .|||.||||||||.||. 1885 313 | .|||.||||||||.||. 1886 314 | .|||.||||||||.||[ 1887 315 | .|||.||||||||.||. 1888 316 | .|||.||||||||.||. 1889 317 | .|||.||||||||.||. 1890 318 | .|||.||||||||.||. 1891 319 | .|||.||||||||.||. 1892 320 | .|||.|||||u||.||. 1893 321 | .|||.||||||||.||. 1894 322 | .|||.||||||||.||. 1895 323 | .|||.||||||||.||. 1896 324 | .|||.||A|||||.||. 1897 325 | .|||.||||||||.||. 1898 326 | .|||.||||||||.||. 1899 327 | .|||.||||||||.||. 1900 328 | .|||.||||||||.||. 1901 329 | .|||.||||||||.||. 1902 330 | .|||.||||||||.||. 1903 331 | .|||.||||||||.||. 1904 332 | .|||.||||||||.||. 1905 333 | .|||.||||||||.||. 1906 334 | .|||.||||||||.||. 1907 335 | .|||.||||||||.||. 1908 336 | .|||.||||||||.||. 1909 337 | .|U|.||||||||.||. 1910 338 | .|||.||||||||.||. 1911 339 | .|||.||||||||.||. 1912 340 | .|||.||||||||.||. 1913 341 | .|||.||||||||.||. 1914 342 | .|||.||||||||.||. 1915 343 | .|||.||||||||.||. 1916 344 | .|||.||||||||.||. 1917 345 | .|||.||||||||.||. 1918 346 | .|||.||||||||.||. 1919 347 | .|||.||||||||.||. 1920 348 | .|||.||||||||.||. 1921 349 | .|||.||||||||.||. 1922 350 | .|||.||||||||.||. 1923 351 | .||}.||||||||.||. 1924 352 | .||..||||||||.||. 1925 353 | .||..||||||||.||. 1926 354 | .||..||||||||.||. 1927 355 | .||..||||||||.||. 1928 356 | .||..||||||||.||. 1929 357 | .||..||||||||.||. 1930 358 | .||..||||||||.||. 1931 359 | .||..||||||||.||. 1932 360 | .||..||||||||.||. 1933 361 | .||..||||||||.||. 1934 362 | .||..||||||||.||. 1935 363 | .||..||||||||.||. 1936 364 | .||..|}||||||.||. 1937 365 | .||..|.||||||.||. 1938 366 | .||..|.||||||.||. 1939 367 | .||..|.||||||.||. 1940 368 | .||..|.||||||.||. 1941 369 | .||.A|.||||||.||. 1942 370 | .||.||.||||||.||. 1943 371 | .||.||.||||||.||. 1944 372 | .||.||.||||||.||. 1945 373 | .||.||.||||||.||. 1946 374 | .||.||.||||||.||. 1947 375 | .||.||.||||||.||. 1948 376 | .||.||.||||||U||. 1949 377 | .||.||.|||||||||. 1950 378 | .||.||.|||||||||. 1951 379 | .||.||.|||||||||. 1952 380 | .||.||.|||||||||. 1953 381 | .||.||.|||||||||. 1954 382 | .||.||.|||||||||. 1955 383 | .||.||.|||||||||. 1956 384 | .||.||.|||||||||. 1957 385 | .||.||.|||||||||. 1958 386 | .||.||.|||||||||. 1959 387 | .||.||.|||||||||. 1960 388 | .||.u|.|||||||||. 1961 389 | .||.||.|||||||||A 1962 390 | .|u.||.|||||||||| 1963 391 | .||.||.|||||||||| 1964 392 | .||.||.|||||||||| 1965 393 | .||.||.|||||||||| 1966 394 | .||.||.|||||||||| 1967 395 | .||.||.|||||||||| 1968 396 | .||.||.|||||||||| 1969 397 | .||.||.|||||||||| 1970 398 | .||.||.]||||||||| 1971 399 | .]|.||..||||||||| 1972 400 | ..|.||..||||||||| 1973 401 | ..|.||..||||||||| 1974 402 | ..|.||..||}|||||| 1975 403 | ..|.||..||.|||||| 1976 404 | ..|.||..||.|||||| 1977 405 | ..|.]|..||.|||||| 1978 406 | ..|..|..||.|||||| 1979 407 | ..|..|..||.|||||| 1980 408 | ..|..|..||.|||||| 1981 409 | ..|..|..||.|||||| 1982 410 | ..|..|..||.|||||| 1983 411 | ..|..|..||.|||||| 1984 412 | ..|..|..||.|||||} 1985 413 | ..|..|..||.|||||. 1986 414 | ..|..|..|}.|||||. 1987 415 | ..|..|..|..|||||. 1988 416 | ..|..|..|..||||]. 1989 417 | ..|..|..|..]]|}.. 1990 418 | ].|..|..]....|... 1991 419 | ..|..|.......|... 1992 420 | ..]..].......]... 1993 421 | -------------------------------------------------------------------------------- /R/intervals.R: -------------------------------------------------------------------------------- 1 | #' Calculate fire intervals from a `composite` 2 | #' 3 | #' @param comp A `composite` instance, usually output from [composite()]. 4 | #' Should contain only one series. 5 | #' @param densfun String giving desired distribution to fit. Either "weibull" 6 | #' or "lognormal". Default is "weibull". 7 | #' 8 | #' @return An `intervals` object. `intervals` have components: 9 | #' * "intervals" an integer vector giving the actual fire intervals. 10 | #' * "fitdistr" a `fitdistr` object from [MASS::fitdistr()] representing the 11 | #' density function fit. 12 | #' * "densfun" a string giving the name of the density function used. 13 | #' * "kstest" an `htest` object from [stats::ks.test()] giving the result of a 14 | #' one-sample Kolmogorov-Smirnov test. 15 | #' * "shapirotest" an `htest` object from [stats::shapiro.test()] giving the 16 | #' result of a Shapiro-Wilk normality test. 17 | #' * "comp_name" a string giving the name of the interval's input composite. 18 | #' * "event_range" an integer vector giving the year range (min, max) of 19 | #' events used to create this intervals. 20 | #' 21 | #' @seealso 22 | #' * [composite()] to create a `composite` object. 23 | #' * [mean.intervals()] gets mean fire interval. 24 | #' * [median.intervals()] gets median fire interval. 25 | #' * [quantile.intervals()] get fit distribution quantiles. 26 | #' * [plot_intervals_dist()] plots `intervals`. 27 | #' * [min.intervals()] gives the minimum fire interval. 28 | #' * [max.intervals()] gives the maximum fire interval. 29 | #' * [print.intervals()] prints common fire-interval summary statistics. 30 | #' 31 | #' @examples 32 | #' data(pgm) 33 | #' interv <- intervals(composite(pgm)) 34 | #' print(interv) 35 | #' 36 | #' mean(interv) # Mean interval 37 | #' 38 | #' # Now fit log-normal distribution instead of Weibull. 39 | #' intervals(composite(pgm), densfun = "lognormal") 40 | #' \dontrun{ 41 | #' # Boxplot of fire interval distribution. 42 | #' boxplot(intervals(composite(pgm))$intervals) 43 | #' } 44 | #' 45 | #' @export 46 | intervals <- function(comp, densfun = "weibull") { 47 | stopifnot(is_fhx(comp)) 48 | stopifnot(densfun %in% c("weibull", "lognormal")) 49 | if (length(series_names(comp)) > 1) { 50 | stop("Found multiple series in `comp`. There can only be one.") 51 | } 52 | dens2cum <- list(weibull = stats::pweibull, lognormal = stats::plnorm) 53 | x <- list() 54 | x$intervals <- diff(get_event_years(comp)[[1]]) 55 | if (length(x$intervals) < 2) { 56 | stop("Too few fire events to compute intervals") 57 | } 58 | class(x) <- c("intervals") 59 | x$fitdistr <- MASS::fitdistr(x$intervals, densfun) 60 | x$densfun <- densfun 61 | p_densfun <- dens2cum[[densfun]] 62 | kstest_args <- c( 63 | list(x = x$intervals, y = p_densfun), 64 | x$fitdistr$estimate 65 | ) 66 | x$kstest <- do.call(stats::ks.test, kstest_args) 67 | x$shapirotest <- stats::shapiro.test(x$intervals) 68 | x$comp_name <- series_names(comp) 69 | x$event_range <- range(unlist(get_event_years(comp))) 70 | x 71 | } 72 | 73 | 74 | #' Check if object is fire `intervals` 75 | #' 76 | #' @param x An R object. 77 | #' 78 | #' @return Boolean indicating whether x is an `intervals` object. 79 | #' 80 | #' @seealso [intervals()] creates an `intervals` object. 81 | #' @export 82 | is_intervals <- function(x) inherits(x, "intervals") 83 | 84 | 85 | #' Alias to [is_intervals()] 86 | #' 87 | #' @inherit is_intervals 88 | #' 89 | #' @export 90 | is.intervals <- function(x) is_intervals(x) 91 | 92 | 93 | #' Fire `intervals` arithmetic mean 94 | #' 95 | #' @param x An `intervals` object. 96 | #' @param ... Additional arguments passed to [mean()]. 97 | #' 98 | #' @return Numeric or NA. 99 | #' 100 | #' @seealso 101 | #' * [intervals()] to create a fire `intervals` object. 102 | #' * [median.intervals()] gets median fire interval. 103 | #' * [quantile.intervals()] get fit distribution quantiles. 104 | #' * [min.intervals()] gives the minimum fire interval. 105 | #' * [max.intervals()] gives the maximum fire interval. 106 | #' * [print.intervals()] prints common fire-interval summary statistics. 107 | #' 108 | #' @export 109 | mean.intervals <- function(x, ...) { 110 | mean(x$intervals, ...) 111 | } 112 | 113 | 114 | #' Fire `intervals` median 115 | #' 116 | #' @param x An `intervals` object. 117 | #' @param ... Additional arguments passed to [stats::median()]. 118 | #' 119 | #' @return Numeric or NA. 120 | #' 121 | #' @seealso 122 | #' * [intervals()] to create a fire `intervals` object. 123 | #' * [mean.intervals()] gets mean fire interval. 124 | #' * [quantile.intervals()] get fit distribution quantiles. 125 | #' * [min.intervals()] gives the minimum fire interval. 126 | #' * [max.intervals()] gives the maximum fire interval. 127 | #' * [print.intervals()] prints common fire-interval summary statistics. 128 | #' 129 | #' @importFrom stats median 130 | #' @export 131 | median.intervals <- function(x, ...) { 132 | median(x$intervals, ...) 133 | } 134 | 135 | 136 | #' Minimum interval in fire `intervals` 137 | #' 138 | #' @param x An `intervals` object. 139 | #' @param ... Additional arguments passed to [min()]. 140 | #' 141 | #' @return Numeric or NA. 142 | #' 143 | #' @seealso 144 | #' * [intervals()] to create a fire `intervals` object. 145 | #' * [mean.intervals()] gets median fire interval. 146 | #' * [median.intervals()] gets median fire interval. 147 | #' * [quantile.intervals()] get fit distribution quantiles. 148 | #' * [max.intervals()] gives the maximum fire interval. 149 | #' * [print.intervals()] prints common fire-interval summary statistics. 150 | #' 151 | #' @export 152 | min.intervals <- function(x, ...) { 153 | min(x$intervals) 154 | } 155 | 156 | 157 | #' Maximum interval in fire `intervals` 158 | #' 159 | #' @param x An `intervals` object. 160 | #' @param ... Additional arguments passed to [max()]. 161 | #' 162 | #' @return Numeric or NA. 163 | #' 164 | #' @seealso 165 | #' * [intervals()] to create a fire `intervals` object. 166 | #' * [mean.intervals()] gets median fire interval. 167 | #' * [median.intervals()] gets median fire interval. 168 | #' * [quantile.intervals()] get fit distribution quantiles. 169 | #' * [min.intervals()] gives the minimum fire interval. 170 | #' * [print.intervals()] prints common fire-interval summary statistics. 171 | #' 172 | #' @export 173 | max.intervals <- function(x, ...) { 174 | max(x$intervals) 175 | } 176 | 177 | 178 | #' Fit distribution quantiles to fire `intervals` 179 | #' 180 | #' @param x An `intervals` object. 181 | #' @param q Vector giving the desired quantiles. 182 | #' @param ... Additional arguments passed to the [quantile()] method for the 183 | #' fit distribution. 184 | #' 185 | #' @seealso 186 | #' * [intervals()] to create a fire `intervals` object. 187 | #' * [mean.intervals()] gets median fire interval. 188 | #' * [median.intervals()] gets median fire interval. 189 | #' * [quantile.intervals()] get fit distribution quantiles. 190 | #' * [min.intervals()] gives the minimum fire interval. 191 | #' * [max.intervals()] gives the maximum fire interval. 192 | #' * [print.intervals()] prints common fire-interval summary statistics. 193 | #' 194 | #' @examples 195 | #' data(pgm) 196 | #' intervs <- intervals(composite(pgm)) 197 | #' quantile(intervs) 198 | #' 199 | #' # Or you can pass in your own quantiles: 200 | #' quantile(intervs, q = c(0.25, 0.5, 0.75)) 201 | #' @importFrom stats quantile 202 | #' @export 203 | quantile.intervals <- function(x, q = c(0.125, 0.5, 0.875), ...) { 204 | dens2cum <- list(weibull = stats::qweibull, lognormal = stats::qlnorm) 205 | q_densfun <- dens2cum[[x$densfun]] 206 | quant_args <- c( 207 | list(q, ...), 208 | x$fitdistr$estimate 209 | ) 210 | quants <- do.call(q_densfun, quant_args) 211 | quants 212 | } 213 | 214 | 215 | #' Plot a fire `intervals` object 216 | #' 217 | #' @param ... Arguments passed to [plot_intervals_dist()]. 218 | #' 219 | #' @seealso [plot_intervals_dist()] plot `intervals` distributions. 220 | #' 221 | #' @examples 222 | #' data(pgm) 223 | #' interv <- intervals(composite(pgm)) 224 | #' 225 | #' plot(interv, binwidth = 5) 226 | #' @export 227 | plot.intervals <- function(...) { 228 | print(plot_intervals_dist(...)) 229 | } 230 | 231 | 232 | #' Basic fire `intervals` distribution plot 233 | #' 234 | #' @param x An `intervals` object, from [intervals()]. 235 | #' @inheritParams ggplot2::geom_histogram 236 | #' 237 | #' @return A ggplot object. 238 | #' 239 | #' @seealso 240 | #' * [intervals()] to create a fire `intervals` object. 241 | #' * [mean.intervals()] gets mean fire interval. 242 | #' * [median.intervals()] gets median fire interval. 243 | #' * [quantile.intervals()] get fit distribution quantiles. 244 | #' * [min.intervals()] gives the minimum fire interval. 245 | #' * [max.intervals()] gives the maximum fire interval. 246 | #' * [print.intervals()] prints common fire-interval summary statistics. 247 | #' 248 | #' @export 249 | plot_intervals_dist <- function(x, binwidth = NULL) { 250 | p <- ggplot2::ggplot( 251 | data.frame("intervals" = x[["intervals"]]), 252 | ggplot2::aes_string(x = "intervals") 253 | ) 254 | if (is.null(binwidth)) { 255 | p <- (p + ggplot2::geom_histogram()) 256 | } else { 257 | p <- (p + ggplot2::geom_histogram(binwidth = binwidth)) 258 | } 259 | p <- (p + ggplot2::geom_rug() + ggplot2::theme_bw()) 260 | p 261 | } 262 | 263 | 264 | #' Print a fire `intervals` object 265 | #' 266 | #' @param x An `intervals` object. 267 | #' @param ... Additional arguments that are tossed. 268 | #' 269 | #' @seealso [intervals()] to create a fire `intervals` object. 270 | #' 271 | #' @examples 272 | #' data(pgm) 273 | #' interv <- intervals(composite(pgm)) 274 | #' print(interv) 275 | #' 276 | #' # Note, you can also catch the printed table: 277 | #' summary_stats <- print(interv) 278 | #' 279 | #' @export 280 | print.intervals <- function(x, ...) { 281 | wfit <- MASS::fitdistr(x$intervals, "weibull") 282 | 283 | weib_invshape <- 1 / wfit$estimate["shape"] 284 | weibull_median <- wfit$estimate["scale"] * log(2)^weib_invshape # nolint 285 | 286 | quants <- quantile(x, q = c(0.847, 0.5, 0.125)) 287 | cat(strwrap("Interval Analysis", prefix = "\t"), sep = "\n") 288 | cat(strwrap("=================", prefix = "\t"), sep = "\n") 289 | cat("\n") 290 | cat(paste0("Composite name: ", x$comp_name, "\n")) 291 | cat(paste0( 292 | "Events range: ", x$event_range[1], 293 | " to ", x$event_range[2], "\n" 294 | )) 295 | cat("\n") 296 | cat(paste0("\tTotal intervals: ", length(x$intervals), "\n")) 297 | cat(paste0("\tMean interval: ", round(mean(x), 1), "\n")) 298 | cat(paste0("\tMedian interval: ", round(median(x), 1), "\n")) 299 | cat(paste0("\tWeibull median: ", round(weibull_median, 1), "\n")) 300 | cat(paste0("\tStandard deviation: ", round(stats::sd(x$intervals), 1), "\n")) 301 | cat(paste0("\tMinimum interval: ", min(x), "\n")) 302 | cat(paste0("\tMaximum interval: ", max(x), "\n")) 303 | 304 | cat("\n\n") 305 | 306 | cat(strwrap("Theoretical distribution"), sep = "\n") 307 | cat(strwrap("------------------------"), sep = "\n") 308 | cat("\n") 309 | cat(paste0("Fit distribution: ", x$densfun, "\n\n")) 310 | print(x$fitdistr) 311 | 312 | cat("\n\n") 313 | 314 | cat(strwrap("Percentiles"), sep = "\n") 315 | cat(strwrap("-----------"), sep = "\n") 316 | cat("\n") 317 | 318 | cat(strwrap(paste0( 319 | "lower (12.5%): ", round(quants[1], 1), " | ", x$densfun, " ", 320 | "median (50.0%): ", round(quants[2], 1), " | ", 321 | "upper (87.5%): ", round(quants[3], 1), "\n" 322 | ))) 323 | 324 | cat("\n\n") 325 | 326 | cat(strwrap(x$kstest$method), sep = "\n") 327 | cat(strwrap(strrep("-", nchar(x$kstest$method))), sep = "\n") 328 | cat("\n") 329 | cat(paste0( 330 | "D^- = ", round(x$kstest$statistic, 5), 331 | ", p = ", round(x$kstest$p.value, 5), "\n" 332 | )) 333 | 334 | null_msg <- paste0( 335 | "Null hypothesis: ", 336 | "The intervals were sampled from the theoretical distribution." 337 | ) 338 | cat(strwrap(null_msg, exdent = 4), sep = "\n") 339 | 340 | alt_msg <- paste0( 341 | "Alt. hypothesis: ", 342 | "The intervals were not sampled from the theoretical distribution." 343 | ) 344 | cat(strwrap(alt_msg, exdent = 4), sep = "\n") 345 | cat("\n\n") 346 | 347 | invisible(x) 348 | } 349 | --------------------------------------------------------------------------------