diff --git a/DESCRIPTION b/DESCRIPTION index 81d2ea9..e61342f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,9 +1,9 @@ Package: RFishBC -Version: 0.2.6 -Date: 2023-8-28 +Version: 0.2.7 +Date: 2023-12-18 Title: Back-Calculation of Fish Length -Authors@R: person("Derek","Ogle", - email="derek@derekogle.com", +Authors@R: person(c("Derek","H."),"Ogle", + email="DerekOgle51@gmail.com", role=c("aut","cre"), comment=c(ORCID="0000-0002-0370-9299")) Description: Helps fisheries scientists collect measurements from calcified diff --git a/NAMESPACE b/NAMESPACE index dd97605..55b4859 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -13,4 +13,5 @@ export(findScalingFactor) export(gConvert) export(getID) export(listFiles) +export(saveDigitizedImage) export(showDigitizedImage) diff --git a/NEWS.md b/NEWS.md index 71d4ee2..a68638c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,16 @@ -# RFishBC 0.2.5.9000 +# RFishBC 0.2.7 +* Updated my (DHO) e-mail address in description and all `@author` tags in the documentation files. +* Removed use of `captioner` package in vignettes as it is no longer available on CRAN (address [#54](https://github.com/fishR-Core-Team/RFishBC/issues/54)). +* Removed `itemize()` in `@return` section of `digitizeRadii()` documentation (addresses note in R-devel CRAN check). +* Replaced `itemize()` with `describe()` in `@details` section of `RFBCoptions()` documentation (addresses note in R-devel CRAN check). +* `backCalc()`: replaced use of `gather()` and `spread()` with `pivot_longer()` and `pivot_wider()` as `gather()` and `spread()` are no longer actively developed. +* `backCalc()`: added ability to retain fish for which no radial measurements were made (addresses [#49](https://github.com/fishR-Core-Team/RFishBC/issues/49)). +* `backCalc()`: added a warning if the r-squared value for the length-structure relationship used in the back-calculation technique is below 0.80 (only for those functions that use a linear model). This attempts to address [#47](https://github.com/fishR-Core-Team/RFishBC/issues/47). +* `backCalc()`: Added simple examples to documentation. +* `saveDigitizedImage()`: Added (address [#44](https://github.com/fishR-Core-Team/RFishBC/issues/44)). +* `showDigitizedImage()`: Added `Encoding()` to unicode "arrows" for plotting to address an issue in the upcoming R v4.4.0 (will address [#59](https://github.com/fishR-Core-Team/RFishBC/issues/59)). + +# RFishBC 0.2.6 * Updated `test-coverage.yaml` to [latest version](https://github.com/r-lib/actions/blob/v2/examples/test-coverage.yaml). * Updated `pkgdown.yaml` to [latest version](https://github.com/r-lib/actions/blob/v2/examples/pkgdown.yaml). * `listFiles()`: Corrected URL errors in documentation. diff --git a/R/RFBCoptions.R b/R/RFBCoptions.R index 48a21c7..ad00154 100644 --- a/R/RFBCoptions.R +++ b/R/RFBCoptions.R @@ -10,7 +10,7 @@ #' @return None, but the list in \code{RFBCoptions} will be modified. #' #' @details The arguments that can be set with this function are: -#' \itemize{ +#' \describe{ #' \item{\code{reading}: }{A single character string (or an object that can be coerced to a character) that identifies the reading for a structure. If the structure will be read multiple times, then this may be used to specify the particular reading. Defaults to \code{NULL}. Used in \code{\link{digitizeRadii}}.} #' \item{\code{description}: }{A single character string that contains a short (but more detailed than in \code{reading}) description for a reading of a structure. Defaults to \code{NULL}. Used in \code{\link{digitizeRadii}}.} #' \item{\code{suffix}: }{A single character string that will be added to the RData file name. If \code{NULL} and \code{reading} is not \code{NULL}, then this will be replaced with the value in \code{reading}. Defaults to \code{NULL}. Used in \code{\link{digitizeRadii}}.} @@ -60,7 +60,7 @@ #' #' @seealso \code{\link{digitizeRadii}} and \code{\link{showDigitizedImage}} #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com} +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} #' #' @export #' diff --git a/R/aStandard.R b/R/aStandard.R index 9831fa7..07f7ed3 100644 --- a/R/aStandard.R +++ b/R/aStandard.R @@ -5,7 +5,7 @@ #' @param species A string that contains the species name for which to find teh standard intercept value. #' @return A single value from \code{\link{StdIntLit}} that is the standard intercept value (a; mm) for the species provided in \code{species}. #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com} +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} #' #' @seealso \code{\link{StdIntLit}} #' diff --git a/R/addFindNotes.R b/R/addFindNotes.R index 72107e6..16b9fd6 100644 --- a/R/addFindNotes.R +++ b/R/addFindNotes.R @@ -9,7 +9,7 @@ #' #' @details A detailed description of its use is in the "Other Features" vignette on the \href{https://fishr-core-team.github.io/RFishBC/index.html}{RFishBC website}. #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com} +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} #' #' @export #' @@ -42,7 +42,7 @@ addNote <- function(nms,note) { #' #' @details A detailed description of its use is in the "Other Features" vignette on the \href{https://fishr-core-team.github.io/RFishBC/index.html}{RFishBC website}. #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com} +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} #' #' @export #' diff --git a/R/backCalc.R b/R/backCalc.R index 33a137f..33e7c66 100644 --- a/R/backCalc.R +++ b/R/backCalc.R @@ -7,7 +7,7 @@ #' @param BCM A single numeric between 1 and 22 or a string that indicates which model to use (based on numbers and names in Vigliola and Meekan (2009)). See Details in \code{\link{bcFuns}} for the list of available models. #' @param a The fish length when the structure first forms as used in the Fraser-Lee model (i.e., \code{BCM=1} or \code{BCM="FRALE"}). If this is missing then \code{a} will be estimated as the intercept from the fish length on structure radius linear regression. #' @param L0p The length at the \dQuote{Biological Intercept} point. Only used in the \dQuote{Biological Intercept} (\code{BCM=3}), \dQuote{Watanabe and Kuroki} (\code{BCM=12}), and \dQuote{Modified Fry} (\code{BCM=14}) models. -#' @param R0p The stucture radius at the \dQuote{Biological Intercept} point. Only used in the \dQuote{Biological Intercept} (\code{BCM=3}), \dQuote{Watanabe and Kuroki} (\code{BCM=12}), and \dQuote{Modified Fry} (\code{BCM=14}) models. +#' @param R0p The structure radius at the \dQuote{Biological Intercept} point. Only used in the \dQuote{Biological Intercept} (\code{BCM=3}), \dQuote{Watanabe and Kuroki} (\code{BCM=12}), and \dQuote{Modified Fry} (\code{BCM=14}) models. #' @param L0 The length at the arbitrarily selected point in the \dQuote{Fry} (\code{BCM=13}) model. #' @param R0 The structure radius at the arbitrarily selected point in the \dQuote{Fry} (\code{BCM=13}) model. #' @param inFormat The format of the data in \code{dat}. The two choices are \code{"long"} with one radial measurement per line (and all radial measurements for a fish in separate rows) and \code{"wide"} with one fish per line (and all radial measurements in separate variables). Defaults to \code{"long"}. @@ -17,8 +17,61 @@ #' #' @return A data.frame similar to \code{dat} but with the radial measurements replaced by back-calculated lengths at previous ages. #' +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} +#' +#' @keywords manip +#' #' @examples -#' ## None yet. +#' ## Get some data +#' data(SMBassWB1,package="RFishBC") ## fish data +#' data(SMBassWB2,package="RFishBC") ## rad data +#' +#' # Simplify to 3 fish so we can see what is going on +#' tmp1 <- subset(SMBassWB1,id %in% c(377,378,379)) +#' tmp2 <- subset(SMBassWB2,id %in% c(377,378,379)) +#' +#' # Combine data frames to form a wide data frame (i.e., a left join) +#' wdat1 <- merge(tmp1,tmp2,by="id",all.x=TRUE) +#' wdat1 +#' +#' # Make a long data frame for examples (remove annuli with NA rads) +#' ldat1 <- tidyr::pivot_longer(wdat1,rad1:rad9,names_to="ann",names_prefix="rad", +#' values_to="rad") +#' ldat1 <- subset(ldat1,!is.na(rad)) +#' ldat1 <- as.data.frame(ldat1) +#' ldat1 +#' +#' ## Back-calculate using Dahl-Lea method +#' # wide in and wide out +#' wwres1 <- backCalc(wdat1,lencap,BCM="DALE",inFormat="wide",digits=0) +#' wwres1 +#' +#' # wide in and long out +#' wlres1 <- backCalc(wdat1,lencap,BCM="DALE",inFormat="wide", +#' outFormat="long",digits=0) +#' wlres1 +#' +#' # long in and wide out +#' lwres1 <- backCalc(ldat1,lencap,BCM="DALE",inFormat="long",digits=0) +#' lwres1 +#' +#' # wide in and long out +#' llres1 <- backCalc(ldat1,lencap,BCM="DALE",inFormat="long", +#' outFormat="long",digits=0) +#' llres1 +#' +#' ## Situation with no radial measurements for some fish +#' # Create an extra fish with length (tmp1) but no rad +#' tmp1a <- rbind(tmp1, +#' data.frame(id=999, +#' species="SMB",lake="WB",gear="E", +#' yearcap=1990,lencap=225)) +#' wdat2 <- merge(tmp1a,tmp2,by="id",all.x=TRUE) +#' wdat2 +#' +#' # wide in and wide out +#' wwres2 <- backCalc(wdat2,lencap,BCM="DALE",inFormat="wide",digits=0) +#' wwres2 #' #' @export backCalc <- function(dat,lencap,BCM,inFormat,outFormat=inFormat, @@ -48,20 +101,25 @@ backCalc <- function(dat,lencap,BCM,inFormat,outFormat=inFormat, ## Convert wide to long nms <- names(dat) rads <- nms[grepl("rad",nms) & !grepl("radcap",nms)] - dat <- tidyr::gather(dat,key=ann,value=rad,rads[1]:rads[length(rads)]) + dat <- tidyr::pivot_longer(dat,rads[1]:rads[length(rads)], + names_to="ann",values_to="rad") ## Change annuli labels into annuli numbers dat$ann <- as.numeric(stringr::str_replace_all(dat$ann,"rad","")) - ## Remove annuli where the radius was missing - dat <- dat[!is.na(dat$rad),] - ## Delete plus-growth if asked to do so - if (deletePlusGrowth) dat <- dat[dat$ann<=dat$agecap,] - ## Sort by id and then ann number - dat <- dat[order(dat$id,dat$ann),] } + ## Extract fish for which a radius was not measured (save to add back at end) + ## assumes no rads measured if first was not measured + norad_dat <- dat[dat$ann==1 & is.na(dat$rad),] + + ## Remove annuli where the radius was missing + dat <- dat[!is.na(dat$rad),] + ## Delete plus-growth if asked to do so + if (deletePlusGrowth) dat <- dat[dat$ann<=dat$agecap,] + ## Sort by id and then ann number + dat <- dat[order(dat$id,dat$ann),] ## Perform relevant regressions if needed ### initiate all possible regression variables (except for a) - b <- c <- A <- B <- C <- NULL + b <- c <- A <- B <- C <- rsq <- NULL ### Get data (one lencap and one radcap per id) for regressions regdat <- dat[dat$ann==1,] regLcap <- regdat[,rlang::quo_name(rlang::enquo(lencap)),drop=TRUE] @@ -72,23 +130,28 @@ backCalc <- function(dat,lencap,BCM,inFormat,outFormat=inFormat, regLR <- stats::lm(regLcap~regRcap) if (is.null(a) | BCM!=2) a <- stats::coef(regLR)[[1]] b <- stats::coef(regLR)[[2]] + rsq <- FSA::rSquared(regLR) } else if (BCM==6) { # SLR of R on L (extract A, B) regRL <- stats::lm(regRcap~regLcap) A <- stats::coef(regRL)[[1]] B <- stats::coef(regRL)[[2]] + rsq <- FSA::rSquared(regRL) } else if (BCM==7) { # MLR of R on L and A (extract A, B, C) regRLA <- stats::lm(regRcap~regLcap+regAcap) A <- stats::coef(regRLA)[[1]] B <- stats::coef(regRLA)[[2]] C <- stats::coef(regRLA)[[3]] + rsq <- FSA::rSquared(regRLA) } else if (BCM==8) { # MLR of L on R and A (extract a, b, c) regLRA <- stats::lm(regLcap~regRcap+regAcap) a <- stats::coef(regLRA)[[1]] b <- stats::coef(regLRA)[[2]] c <- stats::coef(regLRA)[[3]] + rsq <- FSA::rSquared(regLRA) } else if (BCM==9) { # SLR of log(L) on log(R) (extract c) regLR2 <- stats::lm(log(regLcap)~log(regRcap)) c <- stats::coef(regLR2)[[2]] + rsq <- FSA::rSquared(regLR2) } else if (BCM==10) { # NLS of L on R (extract c) tmp <- stats::lm(log(regLcap)~log(regRcap)) sv <- stats::coef(tmp) @@ -122,11 +185,13 @@ backCalc <- function(dat,lencap,BCM,inFormat,outFormat=inFormat, a <- stats::coef(qregLR)[[1]] b <- stats::coef(qregLR)[[2]] c <- stats::coef(qregLR)[[3]] + rsq <- FSA::rSquared(qregLR) } else if (BCM==18) { # QR of R on L (extract A,B,C) qregRL <- stats::lm(regRcap~regLcap+I(regLcap^2)) A <- stats::coef(qregRL)[[1]] B <- stats::coef(qregRL)[[2]] C <- stats::coef(qregRL)[[3]] + rsq <- FSA::rSquared(qregRL) } else if (BCM==21) { # NLS L on R (extract a, bb) tmp <- stats::lm(log(regLcap)~regRcap) sv <- stats::coef(tmp) @@ -144,6 +209,15 @@ backCalc <- function(dat,lencap,BCM,inFormat,outFormat=inFormat, B <- stats::coef(nlsRL)[[2]] } + # Warn about possible poor back-calculation values + if (!is.null(rsq)) { + if (rsq<0.80) + WARN("R-squared for the length-structure relationship is low (", + formatC(rsq,format="f",digits=3),"). The\n", + "computed model coefficients and resulting back-calculated lengths\n", + "may be suspect! Examine the length-structure plot for your data.\n") + } + ## Perform the back-calculation ### Get the back-calculation model function BCFUN <- bcFuns(BCM) @@ -158,12 +232,17 @@ backCalc <- function(dat,lencap,BCM,inFormat,outFormat=inFormat, dat$bclen <- round(dat$bclen,digits=digits) ## Prepare data to return + ### Add back fish with no radial measurements if they exist + if (nrow(norad_dat)>0) { + norad_dat$bclen <- NA + dat <- rbind(dat,norad_dat) + } ### Remove radii information dat <- dat[,!grepl("rad",names(dat))] ### Convert to wide format (if asked to do so) if (outFormat=="wide") { - dat <- tidyr::spread(dat,key=ann,value=bclen,sep="len") - names(dat) <- gsub("ann","",names(dat)) + dat <- tidyr::pivot_wider(dat,names_from="ann",names_prefix="len", + values_from="bclen") } ## Return the data dat diff --git a/R/bcFuns.R b/R/bcFuns.R index d58a1bc..d1799ea 100644 --- a/R/bcFuns.R +++ b/R/bcFuns.R @@ -33,7 +33,7 @@ #' } #' @return A function that can be used to predict length at previous age (Li) given length-at-capture (Lcap), hard-part radius-at-age i (Ri), and hard-part radius-at-capture (Rcap). In addition, some functions/models may require the previous age (agei) and the age-at-capture (agec), certain parameters related to the biological intercept (R0p & L0p), or certain parameters estimated from various regression models (a,b,c,A,B,C). See source for more information. #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com} +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} #' #' @section IFAR Supplement: \url{https://derekogle.com/IFAR/supplements/backcalculation.html} #' diff --git a/R/combineData.R b/R/combineData.R index 68c9870..50ff4d5 100644 --- a/R/combineData.R +++ b/R/combineData.R @@ -11,7 +11,7 @@ #' #' @details A detailed description of its use is in \href{https://fishr-core-team.github.io/RFishBC/articles/collectRadiiData.html}{this vignette} on the \href{https://fishr-core-team.github.io/RFishBC/index.html}{RFishBC website}. The list of R data file names may be efficiently created with \code{\link{listFiles}} as described in that vignette. The R data file names may also be selected from a dialog box if using Windows. #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com} +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} #' #' @export #' diff --git a/R/digitizeRadii.R b/R/digitizeRadii.R index d3ad6af..ed8c842 100644 --- a/R/digitizeRadii.R +++ b/R/digitizeRadii.R @@ -36,33 +36,31 @@ #' @param addNote See details in \code{\link{RFBCoptions}}. #' @param note A specific note about this reading (e.g., a note that the image was poor, some annulus were suspect, or the image should be re-read.). If missing then the user will be prompted to include a note if \code{addNote=TRUE}. #' -#' @return \code{NULL} if more than one file was given in \code{img} or, if only one file was given, a list that contains the following: -#' \itemize{ -#' \item{\code{image}: }{The full filename given in \code{img}.} -#' \item{\code{datanm}: }{The R data filename.} -#' \item{\code{description}: }{The description given in \code{description}.} -#' \item{\code{edgeIsAnnulus}: }{The logical given in \code{edgeIsAnnulus} that identified whether the structure edge/margin should be considered as an annulus.} -#' \item{\code{snap2Transect}: }{The logical from \code{snap2Transect} that identified whether the selected points were \dQuote{snapped} to the transect or not.} -#' \item{\code{scalingFactor}: }{A single numeric used to convert measurements on the structure image to actual measurements on the structure. Measurements on the structure image were multiplied by this value.} -#' \item{\code{sfSource}: }{A character string that identifies whether the scaling factor was \code{"Provided"} through the \code{scalingFactor} argument or derived from a \code{"scaleBar"}.} -#' \item{\code{sbPts}: }{A data.frame of \code{x} and \code{y} coordinates for the endpoints of the scale-bar if the scaling factor was derived from a scale-bar.} -#' \item{\code{sbLength}: }{A single numeric that is the known (actual) length of the scale-bar if the scaling factor was derived from a scale-bar.} -#' \item{\code{sbUnits}: }{A single character that is the units of measurement for the known (actual) length of the scale-bar if the scaling factor was derived from a scale-bar.} -#' \item{\code{slpTransect}: }{The slope of the transect.} -#' \item{\code{intTransect}: }{The intercept of the transect.} -#' \item{\code{slpPerpTransect}: }{The slope of the line perpendicular to the transect.} -#' \item{\code{windowSize}: }{A numeric of length two that contains the width and height of the window used to display the structure image. One of these units was set by the given \code{windowSize} value.} -#' \item{\code{pixW2H}: }{The ratio of pixel width to height. This is used to correct measurements for when an image is not square.} -#' \item{\code{pts}: }{A data.frame that contains the \code{x} and \code{y} coordinates on the image for the selected annuli. These points may have been \dQuote{snapped} to the transect if \code{snap2Transect==TRUE}.} -#' \item{\code{radii}: }{A data.frame that contains the unique \code{id}, the \code{reading} code, the age-at-capture in \code{agecap}, the annulus number in \code{ann}, the radial measurements in \code{rad}, and the radial measurement at capture in \code{radcap}.} -#' \item{\code{note}: }{A string that contains a note about the reading (e.g., a note that the image was poor, some annulus were suspect, or the image should be re-read.)} -#' }. +#' @return \code{NULL} if more than one file was given in \code{img}; otherwise (i.e., only one file was given) a list with the following: +#' \item{\code{image}: }{The full filename given in \code{img}.} +#' \item{\code{datanm}: }{The R data filename.} +#' \item{\code{description}: }{The description given in \code{description}.} +#' \item{\code{edgeIsAnnulus}: }{The logical given in \code{edgeIsAnnulus} that identified whether the structure edge/margin should be considered as an annulus.} +#' \item{\code{snap2Transect}: }{The logical from \code{snap2Transect} that identified whether the selected points were \dQuote{snapped} to the transect or not.} +#' \item{\code{scalingFactor}: }{A single numeric used to convert measurements on the structure image to actual measurements on the structure. Measurements on the structure image were multiplied by this value.} +#' \item{\code{sfSource}: }{A character string that identifies whether the scaling factor was \code{"Provided"} through the \code{scalingFactor} argument or derived from a \code{"scaleBar"}.} +#' \item{\code{sbPts}: }{A data.frame of \code{x} and \code{y} coordinates for the endpoints of the scale-bar if the scaling factor was derived from a scale-bar.} +#' \item{\code{sbLength}: }{A single numeric that is the known (actual) length of the scale-bar if the scaling factor was derived from a scale-bar.} +#' \item{\code{sbUnits}: }{A single character that is the units of measurement for the known (actual) length of the scale-bar if the scaling factor was derived from a scale-bar.} +#' \item{\code{slpTransect}: }{The slope of the transect.} +#' \item{\code{intTransect}: }{The intercept of the transect.} +#' \item{\code{slpPerpTransect}: }{The slope of the line perpendicular to the transect.} +#' \item{\code{windowSize}: }{A numeric of length two that contains the width and height of the window used to display the structure image. One of these units was set by the given \code{windowSize} value.} +#' \item{\code{pixW2H}: }{The ratio of pixel width to height. This is used to correct measurements for when an image is not square.} +#' \item{\code{pts}: }{A data.frame that contains the \code{x} and \code{y} coordinates on the image for the selected annuli. These points may have been \dQuote{snapped} to the transect if \code{snap2Transect==TRUE}.} +#' \item{\code{radii}: }{A data.frame that contains the unique \code{id}, the \code{reading} code, the age-at-capture in \code{agecap}, the annulus number in \code{ann}, the radial measurements in \code{rad}, and the radial measurement at capture in \code{radcap}.} +#' \item{\code{note}: }{A string that contains a note about the reading (e.g., a note that the image was poor, some annulus were suspect, or the image should be re-read.)} #' #' @details This function requires interaction from the user. A detailed description of its use is in the vignettes on the \href{https://fishr-core-team.github.io/RFishBC/index.html}{RFishBC website}. #' #' @seealso \code{\link{showDigitizedImage}} and \code{\link{RFBCoptions}}. #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com}. +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com}. #' #' @export #' diff --git a/R/findScalingFactor.R b/R/findScalingFactor.R index e7eac64..ec392f8 100644 --- a/R/findScalingFactor.R +++ b/R/findScalingFactor.R @@ -19,7 +19,7 @@ #' #' @return A single numeric that is the scaling factor (a multiplier that is used to convert image lengths to actual lengths). #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com} +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} #' #' @export #' diff --git a/R/getID.R b/R/getID.R index 34a3a4b..123ea6a 100644 --- a/R/getID.R +++ b/R/getID.R @@ -19,7 +19,7 @@ #' #' @return Character vector. #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com} +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} #' #' @export #' diff --git a/R/growthDataUtils.R b/R/growthDataUtils.R index 77b8772..e3add25 100644 --- a/R/growthDataUtils.R +++ b/R/growthDataUtils.R @@ -16,7 +16,7 @@ #' #' The newly computed data will be labeled with a prefix the same as \code{out.type=} (i.e., \code{"rad"} or \code{"inc"}) unless \code{out.pre=} is set by the user. For example, if the data are converted to radial measurements, then the output variables will be \dQuote{rad1}, \dQuote{rad2}, etc. unless \code{out.pre=} was changed from the default. This function assumes that the measurements start with age-1. #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com} +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} #' #' @seealso See \code{\link{addRadCap}} for related functionality. #' @@ -92,7 +92,7 @@ gConvert<-function(df,in.pre=NULL,in.var=NULL, #' #' @seealso See \code{\link{gConvert}} for related functionality. #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com} +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} #' #' @keywords manip #' @@ -147,4 +147,4 @@ bcUtilChecker <- function(df,in.pre,in.var) { } ## Return in.var in.var -} \ No newline at end of file +} diff --git a/R/listFiles.R b/R/listFiles.R index c928a84..d3d9a37 100644 --- a/R/listFiles.R +++ b/R/listFiles.R @@ -14,7 +14,7 @@ #' #' @return Character vector. #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com} +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} #' #' @export #' diff --git a/R/saveDigitizedImage.R b/R/saveDigitizedImage.R new file mode 100644 index 0000000..81eeba0 --- /dev/null +++ b/R/saveDigitizedImage.R @@ -0,0 +1,94 @@ +#' @title Save to a file the structure image saved in an R data file with selected points. +#' +#' @description Save to a file the structure image with points to represent annuli that were saved to an R data file using \code{\link{digitizeRadii}}. This allows the user to create a file of their selections that could be printed. +#' +#' @param nms A string (or vector of strings) that indicates the R data file(s) created with \code{\link{digitizeRadii}}. If missing the user will be provided a dialog box from which to choose the file(s). The file(s) must be in the current working directory (see \code{\link{getwd}} result). May also be a single \code{RFishBC} object created with \code{\link{digitizeRadii}}. +#' @param fileType Choose file type to be \code{jpeg}, \code{png}, or \code{pdf}. +#' @param suffix A string that will be appended to each saved filename prior to the extension. Defaults to \dQuote{_marked}. +#' @param res Device (for jpeg and png) resolution. Defaults to 72. +#' @param pch.show See details in \code{\link{RFBCoptions}}. +#' @param col.show See details in \code{\link{RFBCoptions}}. +#' @param cex.show See details in \code{\link{RFBCoptions}}. +#' @param connect See details in \code{\link{RFBCoptions}}. +#' @param col.connect See details in \code{\link{RFBCoptions}}. +#' @param lwd.connect See details in \code{\link{RFBCoptions}}. +#' @param col.scaleBar See details in \code{\link{RFBCoptions}}. +#' @param lwd.scaleBar See details in \code{\link{RFBCoptions}}. +#' @param showScaleBarLength See details in \code{\link{RFBCoptions}}. +#' @param cex.scaleBar See details in \code{\link{RFBCoptions}}. +#' @param showAnnuliLabels See details in \code{\link{RFBCoptions}}. +#' @param annuliLabels See details in \code{\link{RFBCoptions}}. +#' @param col.ann See details in \code{\link{RFBCoptions}}. +#' @param cex.ann See details in \code{\link{RFBCoptions}}. +#' @param offset.ann See details in \code{\link{RFBCoptions}}. +#' +#' @return None, but a file is created in the working directory. +#' +#' @details None. +#' +#' @seealso \code{\link{showDigitizedImage}}, \code{\link{digitizeRadii}}, \code{\link{RFBCoptions}}, and \code{\link{jpeg}}, \code{\link{png}}, and \code{\link{pdf}}. +#' +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} +#' +#' @export +#' +#' @examples +#' ## None because this requires interaction from the user. +#' ## See the link to the extensive documentation in the Details. +#' +saveDigitizedImage <- function(nms,fileType=c("jpeg","png","pdf"), + suffix="_marked",res=72, + pch.show,col.show,cex.show, + connect,col.connect,lwd.connect, + col.scaleBar,lwd.scaleBar, + showScaleBarLength,cex.scaleBar, + showAnnuliLabels,annuliLabels, + col.ann,cex.ann,offset.ann) { + ## handle options + fileType <- match.arg(fileType) + + ## Get image file names ###################################################### + ## If nms is missing then allow the user to choose a file or files + if (missing(nms)) nms <- iHndlFilenames(nms,filter="RData",multi=TRUE) # nocov start + ## If nms is an RFishBC object (and not a filename) then extract the + ## filename otherwise process the filename(s) + if (inherits(nms,"RFishBC")) nms <- nms$datanm # nocov end + else nms <- iHndlFilenames(nms,filter="RData",multi=TRUE) + + ## Get number of readings #################################################### + for (i in nms) { + if (!isRData(i)) { + WARN(i," is not an RData file saved from 'digitizeRadii().") + } else { + dat <- NULL # try to avoid "no visible binding" note + dat <- readRDS(i) + if (!inherits(dat,"RFishBC")) + WARN(i," does not appear to be from 'digitizeRadii().") + else { + d <- showDigitizedImage(dat,"default", + pch.show,col.show,cex.show, + connect,col.connect,lwd.connect, + col.scaleBar,lwd.scaleBar, + showScaleBarLength,cex.scaleBar, + showAnnuliLabels,annuliLabels, + col.ann,cex.ann,offset.ann) + if (fileType=="jpeg") { + nm <- paste0(tools::file_path_sans_ext(i),suffix,".jpg") + grDevices::dev.copy(grDevices::jpeg,nm, + width=d$windowSize[1],height=d$windowSize[2], + units="in",res=res) + } else if (fileType=="png") { + nm <- paste0(tools::file_path_sans_ext(i),suffix,".png") + grDevices::dev.copy(grDevices::png,nm, + width=d$windowSize[1],height=d$windowSize[2], + units="in",res=res) + } else { + nm <- paste0(tools::file_path_sans_ext(i),suffix,".pdf") + grDevices::dev.copy(grDevices::pdf,nm, + width=d$windowSize[1],height=d$windowSize[2]) + } + grDevices::dev.off() + } + } + } +} diff --git a/R/showDigitizedImage.R b/R/showDigitizedImage.R index c51c0ea..93a7d1d 100644 --- a/R/showDigitizedImage.R +++ b/R/showDigitizedImage.R @@ -1,6 +1,6 @@ #' @title Show points selected on a structure image and saved in an R data file #' -#' @description Show points selected on a structure image to represent annuli that were saved to an R data file using \code{\link{digitizeRadii}}. This allows the user to reexaminine the selected points or overlay selected points from multiple readings of the structure. +#' @description Show points selected on a structure image to represent annuli that were saved to an R data file using \code{\link{digitizeRadii}}. This allows the user to reexamine the selected points or overlay selected points from multiple readings of the structure. #' #' @param nms A string (or vector of strings) that indicates the R data file(s) created with \code{\link{digitizeRadii}}. If missing the user will be provided a dialog box from which to choose the file(s). The file(s) must be in the current working directory (see \code{\link{getwd}} result). May also be a single \code{RFishBC} object created with \code{\link{digitizeRadii}}. #' @param deviceType See details in \code{\link{RFBCoptions}}. @@ -26,7 +26,7 @@ #' #' @seealso \code{\link{digitizeRadii}} and \code{\link{RFBCoptions}}. #' -#' @author Derek H. Ogle, \email{derek@@derekogle.com} +#' @author Derek H. Ogle, \email{DerekOgle51@gmail.com} #' #' @export #' @@ -197,6 +197,7 @@ iShowOneDigitizedImage <- function(dat,deviceType, if (useArrows) { pos <- iFindLabelPos(dat) lbl <- intToUtf8(c(9650,9658,9660,9668)[pos]) + lbl <- Encoding(lbl) graphics::text(y~x,data=dat$pts[2:(nrow(dat$pts)-1),],labels=lbl, col=col.show,cex=cex.show,pos=pos,offset=0) if (dat$edgeIsAnnulus) diff --git a/RFishBC.Rproj b/RFishBC.Rproj index d573c57..9f96499 100644 --- a/RFishBC.Rproj +++ b/RFishBC.Rproj @@ -13,5 +13,6 @@ RnwWeave: knitr LaTeX: pdfLaTeX BuildType: Package +PackageUseDevtools: Yes PackageInstallArgs: --no-multiarch --with-keep.source PackageRoxygenize: rd,collate,namespace diff --git a/_pkgdown.yml b/_pkgdown.yml index 9edd9d5..506111a 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -20,6 +20,7 @@ reference: - RFBCoptions - digitizeRadii - showDigitizedImage + - saveDigitizedImage - combineData - findScalingFactor - title: Back-calculation diff --git a/cran-comments/cran-comments-v0_2_7.md b/cran-comments/cran-comments-v0_2_7.md new file mode 100644 index 0000000..76c74f5 --- /dev/null +++ b/cran-comments/cran-comments-v0_2_7.md @@ -0,0 +1,9 @@ +* This updates the RFishBC package that was archived earlier this month. This fixes all errors and notes that caused the archive, and includes some other updates. Importantly my e-mail address has been updated throughout (this may be why I did not receive notice from CRAN about the errors that caused the archiving). + +## Notes +* If there is a note about "fishBC" being misspelled in the description, then note that this is not a misspelling. + +## Testing Environments +* My Windows machine. +* Win Builder -- old-release, release, and development. +* GitHub Action (R-CMD-check.yaml) diff --git a/docs/404.html b/docs/404.html index 784eb97..51a57cf 100644 --- a/docs/404.html +++ b/docs/404.html @@ -39,7 +39,7 @@
@@ -123,7 +123,7 @@