From 8e205ea4767afe772e6f5dff8edbd9ab08643cce Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Thu, 27 Dec 2018 11:55:29 -0800 Subject: [PATCH 01/19] attempting new horizon ID and related management code --- R/Class-SoilProfileCollection.R | 2 + R/SoilProfileCollection-methods.R | 25 +++++ R/SoilProfileCollection-slice-methods.R | 13 ++- R/setters.R | 122 +++++++++++++++++++++++- tests/testthat/test-SPC-objects.R | 2 +- 5 files changed, 158 insertions(+), 6 deletions(-) diff --git a/R/Class-SoilProfileCollection.R b/R/Class-SoilProfileCollection.R index 0776d91b0..afe030b34 100644 --- a/R/Class-SoilProfileCollection.R +++ b/R/Class-SoilProfileCollection.R @@ -43,6 +43,7 @@ setClass( Class='SoilProfileCollection', representation=representation( idcol='character', # column name containing IDs + hzidcol='character', depthcols='character', # 2 element vector with column names for hz top, bottom metadata='data.frame', # single-row dataframe with key-value mapping horizons='data.frame', # all horizons sorted by ID, top @@ -52,6 +53,7 @@ setClass( ), prototype=prototype( idcol='id', + hzidcol='hzID', depthcols=c('top','bottom'), metadata=data.frame(stringsAsFactors=FALSE), # default units are unkown horizons=data.frame(stringsAsFactors=FALSE), diff --git a/R/SoilProfileCollection-methods.R b/R/SoilProfileCollection-methods.R index 008bd9639..6f08226c7 100644 --- a/R/SoilProfileCollection-methods.R +++ b/R/SoilProfileCollection-methods.R @@ -67,6 +67,28 @@ setMethod("idname", "SoilProfileCollection", return(object@idcol) ) +## horizon ID name +if (!isGeneric("hzidname")) + setGeneric("hzidname", function(object, ...) standardGeneric("hzidname")) + +setMethod("hzidname", "SoilProfileCollection", + function(object) + return(object@hzidcol) +) + +## get horizon IDs +if (!isGeneric("hzID")) + setGeneric("hzID", function(object, ...) standardGeneric("hzID")) + +setMethod("hzID", "SoilProfileCollection", + function(object) { + h <- horizons(object) + res <- h[[hzidname(object)]] + return(res) + } + +) + ## distinct profile IDs if (!isGeneric("profile_id")) @@ -269,6 +291,9 @@ rbind.SoilProfileCollection <- function(...) { # make SPC and return res <- SoilProfileCollection(idcol=o.idname[[1]], depthcols=o.hz.depths[[1]], metadata=o.m[[1]], horizons=o.h, site=o.s, sp=o.sp, diagnostic=o.d) + ## reset horizon IDs + hzID(res) <- 1:nrow(res) + # # one more final check: # print(profile_id(res)) # print( site(res)[[idname(res)]]) diff --git a/R/SoilProfileCollection-slice-methods.R b/R/SoilProfileCollection-slice-methods.R index 16876bc61..deecec44d 100644 --- a/R/SoilProfileCollection-slice-methods.R +++ b/R/SoilProfileCollection-slice-methods.R @@ -153,6 +153,7 @@ slice.fast <- function(object, fm, top.down=TRUE, just.the.data=FALSE, strict=TR if(just.the.data) return(hd.slices) + ## TODO: WTF (AGB: loafercreek[, 2]) # if spatial data and only a single slice: SPDF if(nrow(coordinates(object)) == length(object) & length(z) == 1) { cat('result is a SpatialPointsDataFrame object\n') @@ -169,7 +170,17 @@ slice.fast <- function(object, fm, top.down=TRUE, just.the.data=FALSE, strict=TR # otherwise return an SPC, be sure to copy over the spatial data - depths(hd.slices) <- as.formula(paste(id, '~', top, '+', bottom)) + # NOTE: suppressing warning due to non-unique horizon IDs, don't panic + suppressWarnings(depths(hd.slices) <- as.formula(paste(id, '~', top, '+', bottom))) + + ## TODO: hack + # reset auto-generated horizon ID so that we know it is now the slice ID + hz.names <- names(hd.slices@horizons) + idx <- match(hzidname(hd.slices), hz.names) + names(hd.slices@horizons)[idx] <- 'sliceID' + hzidname(hd.slices) <- 'sliceID' + + # copy spatial data hd.slices@sp <- object@sp # if site data: return an SPC + @site diff --git a/R/setters.R b/R/setters.R index 5fd0253a5..828d44241 100644 --- a/R/setters.R +++ b/R/setters.R @@ -1,4 +1,43 @@ +## horizon IDs +if (!isGeneric('hzID<-')) + setGeneric('hzID<-', function(object, value) standardGeneric('hzID<-')) + +setReplaceMethod("hzID", "SoilProfileCollection", + function(object, value) { + + # can't be missing + if(is.null(value)) { + stop('horizon IDs cannot be NULL or NA', call. = FALSE) + } + + if(any(is.na(value)) | any(is.null(value))) { + stop('horizon IDs cannot be NULL or NA', call. = FALSE) + } + + # length + if(length(value) != nrow(object)) { + stop('replacement horizon IDs must have same length as original', call. = FALSE) + } + + # unique + if(length(value) != length(unique(value))) { + stop('replacement horizon IDs must be unique', call. = FALSE) + } + + + # extract horizon and replace IDs + h <- horizons(object) + # note that horizon IDs may be specified in custom-set column + h[[hzidname(object)]] <- value + # re-pack horizons + horizons(object) <- h + + return(object) + } +) + + ## profile IDs if (!isGeneric('profile_id<-')) setGeneric('profile_id<-', function(object, value) standardGeneric('profile_id<-')) @@ -17,12 +56,12 @@ setReplaceMethod("profile_id", "SoilProfileCollection", # length if(length(value) != length(profile_id(object))) { - stop('replacement IDs must have same length as original', call. = FALSE) + stop('replacement profile IDs must have same length as original', call. = FALSE) } # unique if(length(value) != length(unique(value))) { - stop('replacement IDs must be unique', call. = FALSE) + stop('replacement profile IDs must be unique', call. = FALSE) } # lookup table for converting old -> new IDs @@ -58,6 +97,7 @@ setReplaceMethod("profile_id", "SoilProfileCollection", } ) + ## horizon depth columns if (!isGeneric('horizonDepths<-')) setGeneric('horizonDepths<-', function(object, value) standardGeneric('horizonDepths<-')) @@ -156,6 +196,45 @@ setReplaceMethod("siteNames", "SoilProfileCollection", ) + + + +## +## reset hz ID name +## +if (!isGeneric('hzidname<-')) + setGeneric('hzidname<-', function(object, value) standardGeneric('hzidname<-')) + +setReplaceMethod("hzidname", "SoilProfileCollection", + function(object, value) { + + # quick sanity check + if(length(value) != 1) + stop("horizon ID name should have length of 1", call.=FALSE) + + + # sanity checks + + # test: does it exist? + if(! value %in% horizonNames(object)) { + stop("ID name not in horizon data", call.=FALSE) + } + + # test: unique? + x <- horizons(object)[[value]] + if(length(unique(x)) != nrow(object)){ + stop("target ID name not unique", call.=FALSE) + } + + # replace + object@hzidcol <- value + + # done + return(object) + } +) + + ## ## initialize metadata: object modification in-place ## @@ -262,11 +341,46 @@ setReplaceMethod("depths", "data.frame", warning('converting IDs from factor to character', call.=FALSE) data[[nm[1]]] <- as.character(data[[nm[1]]]) } - - # create object + + # depths depthcols <- c(nm[2], nm[3]) + + # create object res <- SoilProfileCollection(idcol=nm[1], depthcols=depthcols, horizons=data[new.order, ]) + # check for horizon ID name conflict + if(hzidname(res) %in% names(data)) { + + # original hz ID + o.hzid <- hzidname(res) + + # is this a good candidate horizon ID? + res.status <- try(hzID(res) <- data[[o.hzid]], silent = TRUE) + + # if not, re-make one + if(class(res.status) == 'try-error') { + # add unique horizon IDs to a new column + n.hzid <- sprintf("%s_", o.hzid) + + # add non-conflicting hz ID + res@horizons[[n.hzid]] <- 1:nrow(res) + + # update object + hzidname(res) <- n.hzid + + # notify + warning(sprintf('`%s` is not a unique horizon ID, using `%s`', o.hzid, n.hzid), call. = FALSE) + } else { + # notify that everything is fine + message(sprintf('using `%s` as a unique horizon ID', o.hzid)) + } + + } else { + # no conflict, add a reasonable horizon ID + hzID(res) <- 1:nrow(res) + } + + # done return(res) } diff --git a/tests/testthat/test-SPC-objects.R b/tests/testthat/test-SPC-objects.R index f74ba8266..3705112b9 100644 --- a/tests/testthat/test-SPC-objects.R +++ b/tests/testthat/test-SPC-objects.R @@ -161,7 +161,7 @@ test_that("SPC horizonNames get/set ", { expect_equal(hn, c("id", "top", "bottom", "bound_distinct", "bound_topography", "name", "texture", "prop", "structure_grade", "structure_size", "structure_type", "stickiness", "plasticity", "field_ph", "hue", - "value", "chroma")) + "value", "chroma", "hzID")) # setting idx <- match('chroma', hn) From 12550d0bae0a193d2f87bd56d75a7e8cb87f9338 Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Thu, 27 Dec 2018 13:27:07 -0800 Subject: [PATCH 02/19] fixing docs --- man/SPC-utils.Rd | 11 +++++++++++ man/SoilProfileCollection-class.Rd | 1 + tests/testthat/test-SPC-objects.R | 13 ++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/man/SPC-utils.Rd b/man/SPC-utils.Rd index 2041e24dc..b896fbe21 100644 --- a/man/SPC-utils.Rd +++ b/man/SPC-utils.Rd @@ -42,6 +42,17 @@ \alias{profile_id<-} \alias{profile_id<-,SoilProfileCollection-method} +\alias{hzID} +\alias{hzID,SoilProfileCollection-method} +\alias{hzID<-} +\alias{hzID<-,SoilProfileCollection-method} + +\alias{hzidname} +\alias{hzidname,SoilProfileCollection-method} +\alias{hzidname<-} +\alias{hzidname<-,SoilProfileCollection-method} + + \title{Getters, Setters, and Utility Methods for SoilProfileCollection Objects} \description{Getters, Setters, and Utility Methods for SoilProfileCollection Objects} \section{Methods}{ diff --git a/man/SoilProfileCollection-class.Rd b/man/SoilProfileCollection-class.Rd index 65874510b..0b84b61dd 100644 --- a/man/SoilProfileCollection-class.Rd +++ b/man/SoilProfileCollection-class.Rd @@ -38,6 +38,7 @@ Objects can be created by calls of the form \code{new("SoilProfileCollection", . \section{Slots}{ \describe{ \item{\code{idcol}:}{Object of class \code{"character"} the name of the column used to uniquely identify profiles } + \item{\code{hzidcol}:}{Object of class \code{"character"} the name of the column used to uniquely identify horizons } \item{\code{depthcols}:}{Object of class \code{"character"} with the names of columns containing the horizon top and bottom boundaries} \item{\code{metadata}:}{Object of class \code{"data.frame"} with collection-level metadata, having a single row, and user-defined columns} \item{\code{horizons}:}{Object of class \code{"data.frame"} with 1 or more rows per profile} diff --git a/tests/testthat/test-SPC-objects.R b/tests/testthat/test-SPC-objects.R index 3705112b9..5b2a992e9 100644 --- a/tests/testthat/test-SPC-objects.R +++ b/tests/testthat/test-SPC-objects.R @@ -217,8 +217,19 @@ test_that("SPC rbind-ing ", { }) -test_that("SPC ID edits ", { +test_that("SPC profile ID get/set ", { }) +test_that("SPC horizon ID get/set ", { + +}) + + +test_that("SPC horizon ID init conflicts", { + +}) + + + From 15e538c41021010c1418810ea8a56c97df7100ea Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Thu, 27 Dec 2018 13:35:53 -0800 Subject: [PATCH 03/19] removing some cruft --- data/amarillo.rda | Bin 24883 -> 0 bytes man/amarillo.Rd | 148 ---------------------------------------------- 2 files changed, 148 deletions(-) delete mode 100644 data/amarillo.rda delete mode 100644 man/amarillo.Rd diff --git a/data/amarillo.rda b/data/amarillo.rda deleted file mode 100644 index 790a3f937365362d688b4758b59aa924607df93f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24883 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 PkUm-dwrC`Iz0`jIP2A{$ diff --git a/man/amarillo.Rd b/man/amarillo.Rd deleted file mode 100644 index b1d3d3d59..000000000 --- a/man/amarillo.Rd +++ /dev/null @@ -1,148 +0,0 @@ -\name{amarillo} -\alias{amarillo} -\docType{data} -\title{Amarillo Soils} -\description{This sample dataset contains laboratory and published soil survey (i.e. generalized) data on the Amarillo soil series.} -\usage{data(amarillo)} -\format{ - The format is: -List of 2 - $ lab:'data.frame': 323 obs. of 40 variables: - ..$ ID : int [1:323] 1 2 3 4 5 6 7 8 9 10 ... - ..$ user_pedon_id : chr [1:323] "53TX305059" "53TX305059" "53TX305059" "53TX305059" ... - ..$ user_site_id : chr [1:323] "53TX305059" "53TX305059" "53TX305059" "53TX305059" ... - ..$ horizontal_datum_name : chr [1:323] "" "" "" "" ... - ..$ latitude_direction : chr [1:323] "north" "north" "north" "north" ... - ..$ latitude_degrees : int [1:323] 33 33 33 33 33 33 33 33 33 33 ... - ..$ latitude_minutes : int [1:323] 10 10 10 10 10 10 11 11 11 11 ... - ..$ latitude_seconds : num [1:323] 30 30 30 30 30 30 5 5 5 5 ... - ..$ longitude_direction : chr [1:323] "west" "west" "west" "west" ... - ..$ longitude_degrees : int [1:323] 101 101 101 101 101 101 101 101 101 101 ... - ..$ longitude_minutes : int [1:323] 47 47 47 47 47 47 46 46 46 46 ... - ..$ longitude_seconds : num [1:323] 40 40 40 40 40 40 48 48 48 48 ... - ..$ latitude_std_decimal_degrees : num [1:323] 33.2 33.2 33.2 33.2 33.2 ... - ..$ longitude_std_decimal_degrees: num [1:323] -102 -102 -102 -102 -102 ... - ..$ taxon_name : chr [1:323] "Amarillo" "Amarillo" "Amarillo" "Amarillo" ... - ..$ class_type : chr [1:323] "correlated" "correlated" "correlated" "correlated" ... - ..$ natural_key : chr [1:323] "40A34174" "40A34175" "40A34176" "40A34177" ... - ..$ hzn_desgn : chr [1:323] "Ap" "B1" "Bt1" "Bt2" ... - ..$ hzn_top : int [1:323] 0 18 51 86 137 190 0 20 51 76 ... - ..$ hzn_bot : int [1:323] 18 51 86 137 190 236 20 51 76 102 ... - ..$ CEC : num [1:323] NA NA NA NA NA NA NA NA NA NA ... - ..$ ECEC : logi [1:323] NA NA NA NA NA NA ... - ..$ ph_h2o : num [1:323] 7.5 7.2 7.5 8 8.4 8.4 NA NA NA NA ... - ..$ ph_cacl2 : num [1:323] NA NA NA NA NA NA NA NA NA NA ... - ..$ caco3 : int [1:323] NA NA NA 8 53 38 NA NA NA NA ... - ..$ c_gypl2 : int [1:323] NA NA NA NA NA NA NA NA NA NA ... - ..$ EC : num [1:323] NA NA NA NA NA NA NA NA NA NA ... - ..$ SAR : int [1:323] NA NA NA NA NA NA NA NA NA NA ... - ..$ Total.Clay : num [1:323] 17.9 19.5 25.2 29.2 37.8 32.6 10.8 26.8 25.5 30.8 ... - ..$ Total.Silt : num [1:323] 9.4 9.4 14.7 18.7 26.8 25.5 10.5 13.6 16.6 15.3 ... - ..$ Total.Sand : num [1:323] 72.7 71.1 60.1 52.1 35.4 41.9 78.7 59.6 57.9 53.9 ... - ..$ dB.33.bar : num [1:323] NA NA NA NA NA NA NA NA 1.2 NA ... - ..$ dB.15.bar : num [1:323] NA NA NA NA NA NA NA NA NA NA ... - ..$ LE : num [1:323] NA NA NA NA NA NA NA NA NA NA ... - ..$ Water.Ret..2mm.33.bar : num [1:323] NA NA NA NA NA NA NA NA NA NA ... - ..$ Water.Ret.clod.33.bar : num [1:323] NA NA NA NA NA NA NA NA 36.6 NA ... - ..$ Water.Ret..2mm.15.bar : num [1:323] NA NA NA NA NA NA NA NA NA NA ... - ..$ OC_lab : num [1:323] NA NA NA NA NA NA NA NA NA NA ... - ..$ OM : num [1:323] NA NA NA NA NA NA NA NA NA NA ... - ..$ model_desg : chr [1:323] "Ap" "B" "Bt" "Bt" ... - $ dmu:'data.frame': 383 obs. of 88 variables: - ..$ ID : int [1:383] 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 ... - ..$ State : chr [1:383] "NM" "NM" "NM" "NM" ... - ..$ Database : chr [1:383] "SSURGO" "SSURGO" "SSURGO" "SSURGO" ... - ..$ Area.Symbol : chr [1:383] "NM021" "NM021" "NM021" "NM021" ... - ..$ Area.Name : chr [1:383] "Harding County, New Mexico" "Harding County, New Mexico" "Harding County, New Mexico" "Harding County, New Mexico" ... - ..$ mukey : int [1:383] 376313 376313 376313 376379 376379 376379 376380 376380 376380 376405 ... - ..$ Mapunit.Symbol : chr [1:383] "AM" "AM" "AM" "SR" ... - ..$ Component.Name : chr [1:383] "Amarillo" "Amarillo" "Amarillo" "Amarillo" ... - ..$ SIR....obsolete: chr [1:383] "TX0130" "TX0130" "TX0130" "TX0130" ... - ..$ cokey : int [1:383] 504646 504646 504646 504918 504918 504918 504923 504923 504923 505030 ... - ..$ RV : int [1:383] 85 85 85 40 40 40 40 40 40 85 ... - ..$ Local.Phase : chr [1:383] "" "" "" "" ... - ..$ chkey : int [1:383] 1113073 1113074 1113075 1113731 1113732 1113733 1113743 1113744 1113745 1114027 ... - ..$ Designation : chr [1:383] "H1" "H2" "H3" "H1" ... - ..$ top : int [1:383] 0 13 122 0 20 122 0 13 122 0 ... - ..$ bott : int [1:383] 13 122 165 20 122 152 13 122 152 20 ... - ..$ CECL : num [1:383] 5 8 8 3 8 8 3 8 8 15 ... - ..$ CECR : num [1:383] 10 14 14 6.5 14 14 6.5 14 14 20 ... - ..$ S : int [1:383] 3 3 3 3 3 3 3 3 3 3 ... - ..$ CECH : num [1:383] 15 20 20 10 20 20 10 20 20 25 ... - ..$ cec_mean : num [1:383] 10 14 14 6.5 14 14 6.5 14 14 20 ... - ..$ ECECL : num [1:383] NA NA NA NA NA NA NA NA NA NA ... - ..$ ECECR : num [1:383] NA NA NA NA NA NA NA NA NA NA ... - ..$ S1 : int [1:383] NA NA NA NA NA NA NA NA NA NA ... - ..$ ECECH : num [1:383] NA NA NA NA NA NA NA NA NA NA ... - ..$ PHWL : num [1:383] 6.6 7.4 7.9 6.6 7.4 7.9 6.6 7.4 7.9 6.6 ... - ..$ PHWR : num [1:383] 7.2 7.9 8.2 7.2 7.9 8.2 7.2 7.9 8.2 7 ... - ..$ PHWH : num [1:383] 7.8 8.4 8.4 7.8 8.4 8.4 7.8 8.4 8.4 7.3 ... - ..$ PHWM : num [1:383] 7.2 7.9 8.15 7.2 7.9 8.15 7.2 7.9 8.15 6.95 ... - ..$ PHCL : num [1:383] NA NA NA NA NA NA NA NA NA NA ... - ..$ PHCR : num [1:383] NA NA NA NA NA NA NA NA NA NA ... - ..$ PHCH : num [1:383] NA NA NA NA NA NA NA NA NA NA ... - ..$ CACOL : int [1:383] 0 0 5 0 0 5 0 0 5 0 ... - ..$ CACOR : int [1:383] 3 3 7 3 3 7 3 5 7 0 ... - ..$ CACOH : int [1:383] 5 5 10 5 5 10 5 7 10 1 ... - ..$ CACOM : num [1:383] 2.5 2.5 7.5 2.5 2.5 7.5 2.5 3.5 7.5 0.5 ... - ..$ GYPL : int [1:383] 0 0 0 0 0 0 0 0 0 0 ... - ..$ GYPR : int [1:383] 0 0 0 0 0 0 0 0 0 0 ... - ..$ GYPH : int [1:383] 0 0 0 0 0 0 0 0 0 1 ... - ..$ GYPM : num [1:383] 0 0 0 0 0 0 0 0 0 0.5 ... - ..$ ECL : int [1:383] 0 0 0 0 0 0 0 0 0 0 ... - ..$ ECR : num [1:383] 1 1 1 1 1 1 1 1 1 0 ... - ..$ ECH : num [1:383] 2 2 2 2 2 2 2 2 2 2 ... - ..$ ECM : num [1:383] 1 1 1 1 1 1 1 1 1 1 ... - ..$ SARL : int [1:383] 0 0 0 0 0 0 0 0 0 0 ... - ..$ SARR : int [1:383] 0 0 0 1 1 1 0 0 0 0 ... - ..$ SARH : int [1:383] 1 1 1 2 2 2 1 1 1 2 ... - ..$ SARM : num [1:383] 0.5 0.5 0.5 1 1 1 0.5 0.5 0.5 1 ... - ..$ CLAYL : int [1:383] 10 20 20 5 20 20 5 20 20 13 ... - ..$ CLAYR : num [1:383] 14 27.5 27.5 10 27.5 27.5 10 27.5 27.5 21.5 ... - ..$ CLAYH : int [1:383] 18 35 35 15 35 35 15 35 35 30 ... - ..$ CLAYM : num [1:383] 14 27.5 27.5 10 27.5 27.5 10 27.5 27.5 21.5 ... - ..$ SILL : num [1:383] NA NA NA NA NA NA NA NA NA 30 ... - ..$ SILR : num [1:383] 16.4 17.4 17.4 9.2 37.8 37.8 9.2 37.8 37.8 37.1 ... - ..$ SILH : num [1:383] NA NA NA NA NA NA NA NA NA 45 ... - ..$ SILM : num [1:383] NA NA NA NA NA NA NA NA NA 37.5 ... - ..$ SANL : num [1:383] NA NA NA NA NA NA NA NA NA 35 ... - ..$ SANR : num [1:383] 69.6 55.1 55.1 80.8 34.7 34.7 80.8 34.7 34.7 41.4 ... - ..$ SANH : int [1:383] NA NA NA NA NA NA NA NA NA 50 ... - ..$ SANM : num [1:383] NA NA NA NA NA NA NA NA NA 42.5 ... - ..$ S2 : int [1:383] 1 1 1 1 1 1 1 1 1 1 ... - ..$ DB3L : num [1:383] 1.35 1.3 1.4 1.4 1.3 1.4 1.4 1.3 1.4 1.3 ... - ..$ DB3R : num [1:383] 1.48 1.48 1.6 1.5 1.48 1.6 1.5 1.48 1.6 1.43 ... - ..$ DB3H : num [1:383] 1.6 1.65 1.8 1.6 1.65 1.8 1.6 1.65 1.8 1.55 ... - ..$ DB3M : num [1:383] 1.47 1.47 1.6 1.5 1.47 1.6 1.5 1.47 1.6 1.42 ... - ..$ S3 : int [1:383] 3 3 3 3 3 3 3 3 3 3 ... - ..$ KSATL : num [1:383] 14.11 4.23 4.23 14.11 4.23 ... - ..$ KSATR : num [1:383] 28.23 9.17 9.17 28.23 9.17 ... - ..$ KSATH : num [1:383] 42.3 14.1 14.1 42.3 14.1 ... - ..$ KSATM : num [1:383] 28.22 9.17 9.17 28.22 9.17 ... - ..$ AWCL : num [1:383] 0.11 0.14 0.1 0.06 0.14 0.1 0.06 0.14 0.1 0.12 ... - ..$ AWCR : num [1:383] 0.13 0.16 0.13 0.08 0.16 0.13 0.08 0.16 0.13 0.15 ... - ..$ AWCH : num [1:383] 0.15 0.18 0.15 0.1 0.18 0.15 0.1 0.18 0.15 0.18 ... - ..$ AWCM : num [1:383] 0.13 0.16 0.12 0.08 0.16 0.12 0.08 0.16 0.12 0.15 ... - ..$ LEPL : num [1:383] 0 0 0 0 0 0 0 0 0 0 ... - ..$ LEPR : num [1:383] 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 ... - ..$ LEPH : num [1:383] 2.9 2.9 2.9 2.9 2.9 2.9 2.9 2.9 2.9 2.9 ... - ..$ LEPM : num [1:383] 1.45 1.45 1.45 1.45 1.45 1.45 1.45 1.45 1.45 1.45 ... - ..$ OML : num [1:383] 0.5 0.2 0.1 0.5 0.2 0.1 0.5 0.2 0.1 1 ... - ..$ OMR : num [1:383] 0.75 0.3 0.2 0.75 0.3 0.2 0.75 0.3 0.2 1.5 ... - ..$ OMH : num [1:383] 1 0.5 0.3 1 0.5 0.3 1 0.5 0.3 2 ... - ..$ OMM : num [1:383] 0.75 0.35 0.2 0.75 0.35 0.2 0.75 0.35 0.2 1.5 ... - ..$ DB15L : logi [1:383] NA NA NA NA NA NA ... - ..$ DB15R : num [1:383] NA NA NA NA NA NA NA NA NA NA ... - ..$ DB15H : logi [1:383] NA NA NA NA NA NA ... - ..$ DB15M : int [1:383] 0 0 0 0 0 0 0 0 0 0 ... - ..$ S4 : int [1:383] NA NA NA NA NA NA NA NA NA NA ... - ..$ model_desg : chr [1:383] "" "" "" "" ... -} - -\source{USDA-NRCSS SSURGO database, and the KSSL database; c/o Skye Wills.} - -\examples{ -data(amarillo) -## maybe str(amarillo) ; plot(amarillo) ... -} -\keyword{datasets} From 5eb5e23645872221d962edbf32875f50ecf0547f Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Thu, 27 Dec 2018 13:36:03 -0800 Subject: [PATCH 04/19] re-making sp5 with new SPC structure --- data/sp5.rda | Bin 42208 -> 47732 bytes misc/test_suite/process_OSACA-data.R | 30 ++++++++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/data/sp5.rda b/data/sp5.rda index de81168e59ab599d022068cbb492079b7d5932ad..4c022827114a6df523a79d2f5a8ab5edd99fc3f7 100644 GIT binary patch literal 47732 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 n<)x2$m4El%oO%QOc-~*?Yb3de7QxpS^4ozhCk1 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 hQc{ Date: Thu, 27 Dec 2018 14:12:47 -0800 Subject: [PATCH 05/19] moving rbind.SoilProfileCollection in anticipation of re-write --- R/SoilProfileCollection-methods.R | 100 ----------------------------- R/union.R | 101 ++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 100 deletions(-) create mode 100644 R/union.R diff --git a/R/SoilProfileCollection-methods.R b/R/SoilProfileCollection-methods.R index 6f08226c7..c8826f596 100644 --- a/R/SoilProfileCollection-methods.R +++ b/R/SoilProfileCollection-methods.R @@ -211,106 +211,6 @@ setMethod("horizonNames", "SoilProfileCollection", ## overloads ## -### This will be greatly improved with new class structure -## concatentation -## # https://github.com/ncss-tech/aqp/issues/71 -## TODO: concatenation of data with duplicated IDs in @site, but unique data in other @site fields, will result in corrupt SPC -## TODO: duplicates in @sp will cause errors -## TODO: duplicates are removed in all other slots... does this make sense? -rbind.SoilProfileCollection <- function(...) { - # setup some defaults - options(stringsAsFactors=FALSE) - - # parse dots - objects <- list(...) - names(objects) <- NULL - - # short-circuits - if(length(objects) == 0) - return(NULL) - if(length(objects) == 1) - return(objects[1]) - - ## TODO: normalize idname and horizonDepths - # profile_id() <- - # horizonDepths() <- - - - # combine pieces - # should have length of 1 - o.idname <- unique(lapply(objects, idname)) - o.depth.units <- unique(lapply(objects, depth_units)) - o.hz.depths <- unique(lapply(objects, horizonDepths)) - o.m <- unique(lapply(objects, aqp::metadata)) - o.coords <- unique(lapply(objects, function(i) ncol(coordinates(i)))) - o.p4s <- unique(lapply(objects, proj4string)) - - # should have length > 1 - o.h <- lapply(objects, horizons) - o.s <- lapply(objects, site) - o.d <- lapply(objects, diagnostic_hz) - o.sp <- lapply(objects, slot, 'sp') - - # sanity checks: - if(length(o.idname) > 1) - stop('inconsistent ID names', call.=FALSE) - if(length(o.depth.units) > 1) - stop('inconsistent depth units', call.=FALSE) - if(length(o.hz.depths) > 1) - stop('inconsistent depth columns', call.=FALSE) - if(length(o.m) > 1) - stop('inconsistent metadata', call.=FALSE) - - # spatial data may be missing... - if(length(o.coords) > 1) - stop('inconsistent spatial data', call.=FALSE) - if(length(o.p4s) > 1) - stop('inconsistent CRS', call.=FALSE) - - # generate new SPC components - # using plyr::rbind.fill seems to solve the problem on non-conformal DF - # is it safe? - # https://github.com/ncss-tech/aqp/issues/71 - o.h <- unique(do.call('rbind.fill', o.h)) # horizon data - o.s <- unique(do.call('rbind.fill', o.s)) # site data - o.d <- unique(do.call('rbind.fill', o.d)) # diagnostic data, leave as-is - - ## 2015-12-18: removed re-ordering, was creating corrupt SPC objects - ## site and horizon data - - # spatial points require some more effort when spatial data are missing - o.1.sp <- objects[[1]]@sp - if(ncol(coordinates(o.1.sp)) == 1) # missing spatial data - o.sp <- o.1.sp # copy the first filler - - ## 2015-12-18: added call to specific function: "sp::rbind.SpatialPoints" - # not missing spatial data - else - o.sp <- do.call("rbind.SpatialPoints", o.sp) # rbind properly - - # make SPC and return - res <- SoilProfileCollection(idcol=o.idname[[1]], depthcols=o.hz.depths[[1]], metadata=o.m[[1]], horizons=o.h, site=o.s, sp=o.sp, diagnostic=o.d) - - ## reset horizon IDs - hzID(res) <- 1:nrow(res) - -# # one more final check: -# print(profile_id(res)) -# print( site(res)[[idname(res)]]) -# print(site(res)) - - if(length(profile_id(res)) != length(site(res)[[idname(res)]])) - stop("SPC object corruption. This shouldn't happen and will be fixed in aqp 2.0", call. = FALSE) - if(! all.equal(profile_id(res), site(res)[[idname(res)]])) - stop("SPC object corruption. This shouldn't happen and will be fixed in aqp 2.0", call. = FALSE) - - return(res) -} - - -## TODO: this doesn't work as expected ... fix in 2.0 -## overload rbind -#setMethod("rbind", "SoilProfileCollection", .rbind.SoilProfileCollection) diff --git a/R/union.R b/R/union.R new file mode 100644 index 000000000..4553c436d --- /dev/null +++ b/R/union.R @@ -0,0 +1,101 @@ + + +## rbind() ---> union() would make more sense +## +## https://github.com/ncss-tech/aqp/issues/71 +## TODO: concatenation of data with duplicated IDs in @site, but unique data in other @site fields, will result in corrupt SPC +## TODO: duplicates in @sp will cause errors +## TODO: duplicates are removed in all other slots... does this make sense? +rbind.SoilProfileCollection <- function(...) { + # setup some defaults + options(stringsAsFactors=FALSE) + + # parse dots + objects <- list(...) + names(objects) <- NULL + + # short-circuits + if(length(objects) == 0) + return(NULL) + if(length(objects) == 1) + return(objects[1]) + + ## TODO: normalize idname and horizonDepths + # profile_id() <- + # horizonDepths() <- + # idname() <- + + + # combine pieces + # should have length of 1 + o.idname <- unique(lapply(objects, idname)) + o.depth.units <- unique(lapply(objects, depth_units)) + o.hz.depths <- unique(lapply(objects, horizonDepths)) + o.m <- unique(lapply(objects, aqp::metadata)) + o.coords <- unique(lapply(objects, function(i) ncol(coordinates(i)))) + o.p4s <- unique(lapply(objects, proj4string)) + + # should have length > 1 + o.h <- lapply(objects, horizons) + o.s <- lapply(objects, site) + o.d <- lapply(objects, diagnostic_hz) + o.sp <- lapply(objects, slot, 'sp') + + # sanity checks: + if(length(o.idname) > 1) + stop('inconsistent ID names', call.=FALSE) + if(length(o.depth.units) > 1) + stop('inconsistent depth units', call.=FALSE) + if(length(o.hz.depths) > 1) + stop('inconsistent depth columns', call.=FALSE) + if(length(o.m) > 1) + stop('inconsistent metadata', call.=FALSE) + + # spatial data may be missing... + if(length(o.coords) > 1) + stop('inconsistent spatial data', call.=FALSE) + if(length(o.p4s) > 1) + stop('inconsistent CRS', call.=FALSE) + + # generate new SPC components + # using plyr::rbind.fill seems to solve the problem on non-conformal DF + # https://github.com/ncss-tech/aqp/issues/71 + o.h <- unique(do.call('rbind.fill', o.h)) # horizon data + o.s <- unique(do.call('rbind.fill', o.s)) # site data + o.d <- unique(do.call('rbind.fill', o.d)) # diagnostic data, leave as-is + + # spatial points require some more effort when spatial data are missing + o.1.sp <- objects[[1]]@sp + + # missing spatial data + if(ncol(coordinates(o.1.sp)) == 1) { + o.sp <- o.1.sp # copy the first filler + } else { + # not missing spatial data + # 2015-12-18: added call to specific function: "sp::rbind.SpatialPoints" + o.sp <- do.call("rbind.SpatialPoints", o.sp) + } + + + ## make SPC and return + res <- SoilProfileCollection(idcol=o.idname[[1]], depthcols=o.hz.depths[[1]], metadata=o.m[[1]], horizons=o.h, site=o.s, sp=o.sp, diagnostic=o.d) + + ## reset horizon IDs + hzID(res) <- 1:nrow(res) + + + ## final sanity checks + if(length(profile_id(res)) != length(site(res)[[idname(res)]])) + stop("SPC object corruption. This shouldn't happen and will be fixed in aqp 2.0", call. = FALSE) + + if(! all.equal(profile_id(res), site(res)[[idname(res)]])) + stop("SPC object corruption. This shouldn't happen and will be fixed in aqp 2.0", call. = FALSE) + + return(res) +} + + +## TODO: this doesn't work as expected ... fix in 2.0 +## overload rbind +#setMethod("rbind", "SoilProfileCollection", .rbind.SoilProfileCollection) + From 43c240a080deecf2ef5a119098a09f67a6f91132 Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Thu, 27 Dec 2018 14:45:24 -0800 Subject: [PATCH 06/19] moving union and rbind.SoilProfileCollection is deprecated --- R/union.R | 32 +++++++++++++++++++------------ tests/testthat/test-SPC-objects.R | 6 +++--- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/R/union.R b/R/union.R index 4553c436d..30ad56089 100644 --- a/R/union.R +++ b/R/union.R @@ -1,17 +1,17 @@ -## rbind() ---> union() would make more sense -## -## https://github.com/ncss-tech/aqp/issues/71 -## TODO: concatenation of data with duplicated IDs in @site, but unique data in other @site fields, will result in corrupt SPC -## TODO: duplicates in @sp will cause errors -## TODO: duplicates are removed in all other slots... does this make sense? -rbind.SoilProfileCollection <- function(...) { + +# TODO: https://github.com/ncss-tech/aqp/issues/71 +# +# TODO: concatenation of data with duplicated IDs in @site, but unique data in other @site fields, will result in corrupt SPC +# TODO: duplicates in @sp will cause errors +# TODO: duplicates are removed in all other slots... does this make sense? +union <- function(spc=list(), method='all', ...) { # setup some defaults options(stringsAsFactors=FALSE) # parse dots - objects <- list(...) + objects <- spc names(objects) <- NULL # short-circuits @@ -20,7 +20,7 @@ rbind.SoilProfileCollection <- function(...) { if(length(objects) == 1) return(objects[1]) - ## TODO: normalize idname and horizonDepths + ## TODO: normalize profile ID, horizon ID, horizon depths # profile_id() <- # horizonDepths() <- # idname() <- @@ -95,7 +95,15 @@ rbind.SoilProfileCollection <- function(...) { } -## TODO: this doesn't work as expected ... fix in 2.0 -## overload rbind -#setMethod("rbind", "SoilProfileCollection", .rbind.SoilProfileCollection) +## ease the transition +rbind.SoilProfileCollection <- function(...) { + .Deprecated('please use union()') + + # parse dots + objects <- list(...) + names(objects) <- NULL + + res <- union(spc=objects, method='all', ...) + return(res) +} diff --git a/tests/testthat/test-SPC-objects.R b/tests/testthat/test-SPC-objects.R index 5b2a992e9..0b06069c0 100644 --- a/tests/testthat/test-SPC-objects.R +++ b/tests/testthat/test-SPC-objects.R @@ -185,7 +185,7 @@ test_that("SPC horizonNames get/set ", { -test_that("SPC rbind-ing ", { +test_that("SPC union ", { # test data x <- sp1 @@ -198,13 +198,13 @@ test_that("SPC rbind-ing ", { diagnostic_hz(y) <- data.frame(id='P001', type='pizza') # this should not work, IDs aren't unqiue - expect_error(rbind(x, y)) + expect_error(union(list(x, y))) # fix IDs manually profile_id(y) <- sprintf("%s-copy", profile_id(y)) # this should work - z <- rbind(x,y) + z <- union(list(x,y)) expect_match(class(z), 'SoilProfileCollection') expect_equal(length(z), length(x) + length(y)) From 0e80f01ab652e81d202556b1033d04828667211e Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Thu, 27 Dec 2018 15:01:51 -0800 Subject: [PATCH 07/19] moving related to #71 --- R/union.R | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/R/union.R b/R/union.R index 30ad56089..29fc2886b 100644 --- a/R/union.R +++ b/R/union.R @@ -1,3 +1,23 @@ +# 2018-12-17 +# D.E. Beaudette +# A.G. Brown +# +# This function replaces the previous +# + + +# ease the transition to union() +rbind.SoilProfileCollection <- function(...) { + .Deprecated('please use union()') + + # parse dots + objects <- list(...) + names(objects) <- NULL + + # make compatible + res <- union(spc=objects) + return(res) +} @@ -95,15 +115,4 @@ union <- function(spc=list(), method='all', ...) { } -## ease the transition -rbind.SoilProfileCollection <- function(...) { - .Deprecated('please use union()') - - # parse dots - objects <- list(...) - names(objects) <- NULL - - res <- union(spc=objects, method='all', ...) - return(res) -} From 9c4a66ce6993df77fe69d924a641e8f0cb541452 Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Thu, 27 Dec 2018 15:23:55 -0800 Subject: [PATCH 08/19] more notes on union, #71 --- R/Class-SoilProfileCollection.R | 1 + R/union.R | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/R/Class-SoilProfileCollection.R b/R/Class-SoilProfileCollection.R index afe030b34..d3b800f9e 100644 --- a/R/Class-SoilProfileCollection.R +++ b/R/Class-SoilProfileCollection.R @@ -1,3 +1,4 @@ +# https://github.com/ncss-tech/aqp/issues/75 # class def for main class within aqp .SoilProfileCollectionValidity <- function(object) { diff --git a/R/union.R b/R/union.R index 29fc2886b..f90981127 100644 --- a/R/union.R +++ b/R/union.R @@ -2,7 +2,8 @@ # D.E. Beaudette # A.G. Brown # -# This function replaces the previous +# +# This function replaces the previous rbind.SoilProfileCollection function. # From dcd43dda10486466737172e8a22e4817c61e8757 Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Thu, 27 Dec 2018 15:49:28 -0800 Subject: [PATCH 09/19] forgot that horizonNames<- existed --- R/SoilProfileCollection-slice-methods.R | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/R/SoilProfileCollection-slice-methods.R b/R/SoilProfileCollection-slice-methods.R index deecec44d..081bbfc8f 100644 --- a/R/SoilProfileCollection-slice-methods.R +++ b/R/SoilProfileCollection-slice-methods.R @@ -173,11 +173,9 @@ slice.fast <- function(object, fm, top.down=TRUE, just.the.data=FALSE, strict=TR # NOTE: suppressing warning due to non-unique horizon IDs, don't panic suppressWarnings(depths(hd.slices) <- as.formula(paste(id, '~', top, '+', bottom))) - ## TODO: hack # reset auto-generated horizon ID so that we know it is now the slice ID - hz.names <- names(hd.slices@horizons) - idx <- match(hzidname(hd.slices), hz.names) - names(hd.slices@horizons)[idx] <- 'sliceID' + idx <- match(hzidname(hd.slices), horizonNames(hd.slices)) + horizonNames(hd.slices)[idx] <- 'sliceID' hzidname(hd.slices) <- 'sliceID' # copy spatial data From 88e748a4999fc998d3b45a13c1c54c1562667a73 Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Thu, 27 Dec 2018 15:49:37 -0800 Subject: [PATCH 10/19] more tests --- tests/testthat/test-SPC-objects.R | 117 +++++++++++++++++++++++++++--- tests/testthat/test-slice.R | 17 +++-- 2 files changed, 117 insertions(+), 17 deletions(-) diff --git a/tests/testthat/test-SPC-objects.R b/tests/testthat/test-SPC-objects.R index 0b06069c0..91492e086 100644 --- a/tests/testthat/test-SPC-objects.R +++ b/tests/testthat/test-SPC-objects.R @@ -184,6 +184,111 @@ test_that("SPC horizonNames get/set ", { }) +test_that("SPC horizon ID get/set ", { + + # automatically generated horizon IDs + auto.hz.ids <- hzID(sp1) + + # should be 1:nrow(sp1) + expect_equivalent(auto.hz.ids, seq_len(nrow(sp1))) + + # try replacing with reasonable IDs + hzID(sp1) <- rev(hzID(sp1)) + expect_equivalent(hzID(sp1), rev(seq_len(nrow(sp1)))) + + # try replacing with bogus values + expect_error(hzID(sp1) <- 1) + # non-unique + expect_error(hzID(sp1) <- sample(hzID(sp1), replace = TRUE)) + +}) + + +test_that("SPC horizon ID name get/set ", { + + # check default + expect_equivalent(hzidname(sp1), 'hzID') + + # make a new horizon ID + sp1$junk <- 1:nrow(sp1) + hzidname(sp1) <- 'junk' + expect_equivalent(hzidname(sp1), 'junk') + + # error conditions: + # no column + expect_error(hzidname(sp1) <- 'xxx') + + # not unique + expect_error(hzidname(sp1) <- 'top') + +}) + +test_that("SPC horizon ID get/set ", { + + # automatically generated horizon IDs + auto.hz.ids <- hzID(sp1) + + # should be 1:nrow(sp1) + expect_equivalent(auto.hz.ids, seq_len(nrow(sp1))) + + # try replacing with reasonable IDs + hzID(sp1) <- rev(hzID(sp1)) + expect_equivalent(hzID(sp1), rev(seq_len(nrow(sp1)))) + + # try replacing with bogus values + expect_error(hzID(sp1) <- 1) + # non-unique + expect_error(hzID(sp1) <- sample(hzID(sp1), replace = TRUE)) + +}) + + +test_that("SPC profile ID get/set ", { + + # original + pIDs <- profile_id(sp1) + + # new + pIDs.new <- sprintf("%s-copy", pIDs) + + # try re-setting + profile_id(sp1) <- pIDs.new + + # were the IDs altered? + expect_equivalent(profile_id(sp1), pIDs.new) + + # bogus edits + expect_error(profile_id(sp1) <- 1) + expect_error(profile_id(sp1) <- sample(pIDs, replace = TRUE)) + expect_error(profile_id(sp1) <- c(NA, pIDs[-1])) + +}) + + +test_that("SPC horizon ID init conflicts", { + + # decompose, re-init and test for message + x <- sp1 + x <- as(x, 'data.frame') + expect_message(depths(x) <- id ~ top + bottom, "^using") + expect_equivalent(hzidname(x), 'hzID') + + # decompose, add non-unique column conflicing with hzID + x <- sp1 + x <- as(x, 'data.frame') + x$hzID <- 1 + expect_warning(depths(x) <- id ~ top + bottom, "not a unique horizon ID, using") + # test backup name + expect_equivalent(hzidname(x), 'hzID_') + + # special case: IDs resulting from slice() + s <- slice(sp1, 0:100 ~ .) + expect_equivalent(hzidname(s), 'sliceID') + # check to make sure hzID and sliceID are present + expect_equal(grep('hzID|sliceID', horizonNames(s)), c(18, 20)) + +}) + test_that("SPC union ", { @@ -217,19 +322,7 @@ test_that("SPC union ", { }) -test_that("SPC profile ID get/set ", { - -}) -test_that("SPC horizon ID get/set ", { - -}) - - -test_that("SPC horizon ID init conflicts", { - -}) - diff --git a/tests/testthat/test-slice.R b/tests/testthat/test-slice.R index 85af20e66..c80aa2e85 100644 --- a/tests/testthat/test-slice.R +++ b/tests/testthat/test-slice.R @@ -21,17 +21,24 @@ test_that("basic slice functionality", { expect_equal(nrow(horizons(s[1, ])), 101) # ID correctly initialized? - expect_equal(idname(sp1), 'id') - expect_true(length(profile_id(sp1)) == length(sp1)) + expect_equal(idname(s), 'id') + expect_true(length(profile_id(s)) == length(s)) + expect_equivalent(profile_id(s), profile_id(sp1)) # ID in the correct order? - expect_identical(profile_id(sp1), site(sp1)[[idname(sp1)]]) + expect_identical(profile_id(s), site(s)[[idname(s)]]) # depth names? - expect_equal(horizonDepths(sp1), c('top', 'bottom')) + expect_equal(horizonDepths(s), horizonDepths(sp1)) # site-level attributes correctly initialized? - expect_true(length(sp1$group) == length(sp1)) + expect_true(length(s$group) == length(s)) + + # original horizon IDs + expect_true('hzID' %in% horizonNames(s)) + + # new slice IDs + expect_true('sliceID' %in% hzidname(s)) }) From 68ad0652ddec7f29155ce5973d5932e0d138cbb2 Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Thu, 27 Dec 2018 15:55:50 -0800 Subject: [PATCH 11/19] news updates --- NEWS | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 350d31d91..080a08546 100644 --- a/NEWS +++ b/NEWS @@ -4,8 +4,12 @@ * new functions: previewColors(), colorQuantiles(), plotColorQuantiles() * new function: horizonDepths()<-, edit top/bottom names after SPC init * new function: profile_id()<-, edit profile IDs after init; be careful! -* rbind method for SoilProfileCollection objects [...] +* new functions: hzID() and hzID()<-, get/set unique horizon IDs +* new functions: hzidname() and hzidname()<-, get/set column containing unique horizon IDs +* rbind.SoilProfileCollection() has been deprecated in favor of union(), gains new functionality: * bug fixes in sanity checks for horizonNames()<- +* !!! SoilProfileCollection internal structure has changed: +* -------------------------- aqp 1.16-6 (2018-12-12) ------------------------ * partial bug fix in test_hz_logic() related to missing top AND bottom depths, needs work: https://github.com/ncss-tech/aqp/issues/65 From 666723cd563ae09871979bfef448157b85de2844 Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Thu, 27 Dec 2018 20:57:45 -0800 Subject: [PATCH 12/19] initial validity checking and repair methods for SPC, #74 --- R/SPC-validity-repair.R | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 R/SPC-validity-repair.R diff --git a/R/SPC-validity-repair.R b/R/SPC-validity-repair.R new file mode 100644 index 000000000..6417cd0a3 --- /dev/null +++ b/R/SPC-validity-repair.R @@ -0,0 +1,48 @@ + +# test for valid SPC, based on presence / absense of slots as compared to +# class prototype +# likely only used between major versions of aqp where internal structure of SPC has changed +isValidSPC <- function(x) { + + # get slot names from prototype + sn <- slotNames(x) + + # test for all slots in the prototype + s.test <- sapply(sn, function(i) .hasSlot(x, name=i)) + + # a valid object will have all slots present + if(all(s.test)) { + res <- TRUE + } else { + res <- FALSE + } + + return(res) +} + +# repair an SPC by breaking into pieces and re-assembling +# likely only used to fix outdated SPC objects that are missing slots +repairSPC <- function(x) { + # break into pieces + id <- idname(x) + hd <- horizonDepths(x) + m <- metadata(x) + h <- horizons(x) + s <- site(x) + # hack, no getter function defined + sp <- x@sp + d <- diagnostic_hz(x) + + # init SPC from pieces + # note: using depths<- because it will generate a horizon ID + fm <- as.formula(sprintf("%s ~ %s + %s", id, hd[1], hd[2])) + depths(h) <- fm + + # add additional pieces + metadata(h) <- m + site(h) <- s + h@sp <- sp + diagnostic_hz(h) <- d + + return(h) +} From e9bee73bbae6849b9dffc24b0155969598c817e5 Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Thu, 27 Dec 2018 21:01:36 -0800 Subject: [PATCH 13/19] data for testing related to #74 --- misc/sp5-old.rda | Bin 0 -> 42208 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 misc/sp5-old.rda diff --git a/misc/sp5-old.rda b/misc/sp5-old.rda new file mode 100644 index 0000000000000000000000000000000000000000..de81168e59ab599d022068cbb492079b7d5932ad GIT binary patch literal 42208 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 hQc{ Date: Thu, 27 Dec 2018 21:10:41 -0800 Subject: [PATCH 14/19] basic documentation, #74 --- man/isValidSPC.Rd | 23 +++++++++++++++++++++++ man/repairSPC.Rd | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 man/isValidSPC.Rd create mode 100644 man/repairSPC.Rd diff --git a/man/isValidSPC.Rd b/man/isValidSPC.Rd new file mode 100644 index 000000000..ec4b4a91f --- /dev/null +++ b/man/isValidSPC.Rd @@ -0,0 +1,23 @@ +\name{isValidSPC} +\alias{isValidSPC} + +\title{Test for a valid SoilProfileCollection} +\description{Test for a valid SoilProfileCollection} + +\usage{ +isValidSPC(x) +} + +\arguments{ + \item{x}{a \code{SoilProfileCollection} object} +} + +\details{Test for valid \code{SoilProfileCollection} by checking for slots defined in the class prototype. Likely only used between major versions of `aqp` where internal structure of \code{SoilProfileCollection} has changed.} + +\value{TRUE or FALSE. Consider using \code{repairSPC()} if FALSE.} + +\author{D.E. Beaudette} + +\seealso{ +\code{\link{repairSPC}} +} diff --git a/man/repairSPC.Rd b/man/repairSPC.Rd new file mode 100644 index 000000000..909512d84 --- /dev/null +++ b/man/repairSPC.Rd @@ -0,0 +1,23 @@ +\name{repairSPC} +\alias{repairSPC} + +\title{Repair a SoilProfileCollection object} +\description{Repair a SoilProfileCollection object} + +\usage{ +repairSPC(x) +} + +\arguments{ + \item{x}{a \code{SoilProfileCollection} object} +} + +\details{Attempt repair of a \code{SoilProfileCollection} object by splitting into components and re-assembling. Likely only used to fix outdated \code{SoilProfileCollection} objects that are missing slots.} + +\value{A valid \code{SoilProfileCollection} object.} + +\author{D.E. Beaudette} + +\seealso{ +\code{\link{isValidSPC}} +} From bcf25d8532f92e185a5115b1dc2dc667a531bfc9 Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Fri, 28 Dec 2018 10:34:49 -0800 Subject: [PATCH 15/19] re-working SPC checking and rebulding code, #74 --- R/SPC-validity-repair.R | 48 ------------------------------ R/SoilProfileCollection-coercion.R | 33 ++++++++++++++++++++ R/checkSPC.R | 23 ++++++++++++++ R/rebuildSPC.R | 24 +++++++++++++++ man/{isValidSPC.Rd => checkSPC.Rd} | 8 ++--- man/rebuildSPC.Rd | 23 ++++++++++++++ man/repairSPC.Rd | 23 -------------- 7 files changed, 107 insertions(+), 75 deletions(-) delete mode 100644 R/SPC-validity-repair.R create mode 100644 R/checkSPC.R create mode 100644 R/rebuildSPC.R rename man/{isValidSPC.Rd => checkSPC.Rd} (79%) create mode 100644 man/rebuildSPC.Rd delete mode 100644 man/repairSPC.Rd diff --git a/R/SPC-validity-repair.R b/R/SPC-validity-repair.R deleted file mode 100644 index 6417cd0a3..000000000 --- a/R/SPC-validity-repair.R +++ /dev/null @@ -1,48 +0,0 @@ - -# test for valid SPC, based on presence / absense of slots as compared to -# class prototype -# likely only used between major versions of aqp where internal structure of SPC has changed -isValidSPC <- function(x) { - - # get slot names from prototype - sn <- slotNames(x) - - # test for all slots in the prototype - s.test <- sapply(sn, function(i) .hasSlot(x, name=i)) - - # a valid object will have all slots present - if(all(s.test)) { - res <- TRUE - } else { - res <- FALSE - } - - return(res) -} - -# repair an SPC by breaking into pieces and re-assembling -# likely only used to fix outdated SPC objects that are missing slots -repairSPC <- function(x) { - # break into pieces - id <- idname(x) - hd <- horizonDepths(x) - m <- metadata(x) - h <- horizons(x) - s <- site(x) - # hack, no getter function defined - sp <- x@sp - d <- diagnostic_hz(x) - - # init SPC from pieces - # note: using depths<- because it will generate a horizon ID - fm <- as.formula(sprintf("%s ~ %s + %s", id, hd[1], hd[2])) - depths(h) <- fm - - # add additional pieces - metadata(h) <- m - site(h) <- s - h@sp <- sp - diagnostic_hz(h) <- d - - return(h) -} diff --git a/R/SoilProfileCollection-coercion.R b/R/SoilProfileCollection-coercion.R index d88832b33..e54aacacc 100644 --- a/R/SoilProfileCollection-coercion.R +++ b/R/SoilProfileCollection-coercion.R @@ -1,4 +1,37 @@ ## Coercition methods: general + +# safely deconstruct as list +setAs("SoilProfileCollection", "list", function(from) { + + # get slot names from prototype + sn <- slotNames(from) + + # test for presence of all slots + # copy contents over to list with same name + # if missing return NULL + warning + s.list <- lapply(sn, function(i) { + if(.hasSlot(from, name=i)) { + res <- slot(from, i) + } else { + res <- NULL + } + return(res) + }) + + # copy slot names + names(s.list) <- sn + + # test for missing slots + if(any(sapply(s.list, is.null))) { + warning("some slots were missing, use reBuildSPC to fix", call. = FALSE) + } + + return(s.list) + +} +) + + setAs("SoilProfileCollection", "data.frame", function(from) { # horizons + site + coordinates diff --git a/R/checkSPC.R b/R/checkSPC.R new file mode 100644 index 000000000..a51da4625 --- /dev/null +++ b/R/checkSPC.R @@ -0,0 +1,23 @@ + +# test for valid SPC, based on presence / absense of slots as compared to +# class prototype +# likely only used between major versions of aqp where internal structure of SPC has changed +checkSPC <- function(x) { + + # get slot names from prototype + sn <- slotNames(x) + + # test for all slots in the prototype + s.test <- sapply(sn, function(i) .hasSlot(x, name=i)) + + # a valid object will have all slots present + if(all(s.test)) { + res <- TRUE + } else { + res <- FALSE + } + + return(res) +} + + diff --git a/R/rebuildSPC.R b/R/rebuildSPC.R new file mode 100644 index 000000000..7d1614fbe --- /dev/null +++ b/R/rebuildSPC.R @@ -0,0 +1,24 @@ +# repair an SPC by breaking into pieces and re-assembling +# likely only used to fix outdated SPC objects that are missing slots +rebuildSPC <- function(x) { + + # break into pieces as list + x.list <- suppressWarnings(as(x, 'list')) + + # seed object for new SPC + res <- x.list$horizons + + # init SPC from pieces + # note: using depths<- because it will generate a horizon ID + fm <- as.formula(sprintf("%s ~ %s + %s", x.list$idcol, x.list$depthcols[1], x.list$depthcols[2])) + depths(res) <- fm + + # add additional pieces + metadata(res) <- x.list$metadata + site(res) <- x.list$site + res@sp <- x.list$sp + diagnostic_hz(res) <- x.list$diagnostic + + return(res) +} + diff --git a/man/isValidSPC.Rd b/man/checkSPC.Rd similarity index 79% rename from man/isValidSPC.Rd rename to man/checkSPC.Rd index ec4b4a91f..5b8583ea6 100644 --- a/man/isValidSPC.Rd +++ b/man/checkSPC.Rd @@ -1,11 +1,11 @@ -\name{isValidSPC} +\name{checkSPC} \alias{isValidSPC} \title{Test for a valid SoilProfileCollection} \description{Test for a valid SoilProfileCollection} \usage{ -isValidSPC(x) +checkSPC(x) } \arguments{ @@ -14,10 +14,10 @@ isValidSPC(x) \details{Test for valid \code{SoilProfileCollection} by checking for slots defined in the class prototype. Likely only used between major versions of `aqp` where internal structure of \code{SoilProfileCollection} has changed.} -\value{TRUE or FALSE. Consider using \code{repairSPC()} if FALSE.} +\value{TRUE or FALSE. Consider using \code{rebuildSPC()} if FALSE.} \author{D.E. Beaudette} \seealso{ -\code{\link{repairSPC}} +\code{\link{rebuildSPC}} } diff --git a/man/rebuildSPC.Rd b/man/rebuildSPC.Rd new file mode 100644 index 000000000..74eaf9eda --- /dev/null +++ b/man/rebuildSPC.Rd @@ -0,0 +1,23 @@ +\name{rebuildSPC} +\alias{rebuildSPC} + +\title{Rebuild a SoilProfileCollection object} +\description{Rebuild a SoilProfileCollection object} + +\usage{ +rebuildSPC(x) +} + +\arguments{ + \item{x}{a \code{SoilProfileCollection} object} +} + +\details{Attempt rebuidling a \code{SoilProfileCollection} object by splitting into components and re-assembling. Likely only used to fix outdated \code{SoilProfileCollection} objects that are missing slots.} + +\value{A valid \code{SoilProfileCollection} object.} + +\author{D.E. Beaudette} + +\seealso{ +\code{\link{checkSPC}} +} diff --git a/man/repairSPC.Rd b/man/repairSPC.Rd deleted file mode 100644 index 909512d84..000000000 --- a/man/repairSPC.Rd +++ /dev/null @@ -1,23 +0,0 @@ -\name{repairSPC} -\alias{repairSPC} - -\title{Repair a SoilProfileCollection object} -\description{Repair a SoilProfileCollection object} - -\usage{ -repairSPC(x) -} - -\arguments{ - \item{x}{a \code{SoilProfileCollection} object} -} - -\details{Attempt repair of a \code{SoilProfileCollection} object by splitting into components and re-assembling. Likely only used to fix outdated \code{SoilProfileCollection} objects that are missing slots.} - -\value{A valid \code{SoilProfileCollection} object.} - -\author{D.E. Beaudette} - -\seealso{ -\code{\link{isValidSPC}} -} From cc25c7aa415c6a49309be4c2041e776c78ad64ce Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Fri, 28 Dec 2018 11:08:45 -0800 Subject: [PATCH 16/19] new tests, replacing all references to rbind --- man/SPC-unique-methods.Rd | 30 +++++++++++++---- man/subsetProfiles-methods.Rd | 2 +- tests/testthat/test-SPC-objects.R | 55 ++++++++++++++----------------- tests/testthat/test-SPC-union.R | 49 +++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 37 deletions(-) create mode 100644 tests/testthat/test-SPC-union.R diff --git a/man/SPC-unique-methods.Rd b/man/SPC-unique-methods.Rd index 925c6ebb0..3810c6c89 100644 --- a/man/SPC-unique-methods.Rd +++ b/man/SPC-unique-methods.Rd @@ -32,15 +32,27 @@ uniqueSPC(x, vars) \examples{ -## use the digest library to detect duplicate data +# use the digest library to detect duplicate data data(sp1) +sp1$soil_color <- with(sp1, munsell2rgb(hue, value, chroma)) -# make a copy, make new IDs, and stack -s.1 <- sp1 +# upgrade to SoilProfileCollection +depths(sp1) <- id ~ top + bottom +site(sp1) <- ~ group + + +# make a copies +s.1 <- sp1 s.2 <- sp1 -s.2$id <- paste(s.2$id, '-copy', sep='') -s <- rbind(s.1, s.2) -depths(s) <- id ~ top + bottom + +# update IDs in second copy +profile_id(s.2) <- sprintf('\%s-copy', profile_id(s.2)) + +# union SPCs +s <- union(list(s.1, s.2)) + +# check +plot(s) # digests are computed from horizon-level data only # horizon boundaries and 'prop' @@ -51,6 +63,12 @@ u <- unique(s, vars=c('top', 'bottom', 'prop')) # compare with and without dupes: # note subsetting of SoilProfileCollection cbind(dupes=length(s), no.dupes=length(s[u, ])) + +# get unique profile by index +s.unique <- s[u, ] + +# unique data +plot(s.unique) } \keyword{methods} diff --git a/man/subsetProfiles-methods.Rd b/man/subsetProfiles-methods.Rd index 54fd2f4b8..cd89a0148 100644 --- a/man/subsetProfiles-methods.Rd +++ b/man/subsetProfiles-methods.Rd @@ -34,7 +34,7 @@ plot(group.1 <- subsetProfiles(sp1, s="group == '1'")) plot(coarse.soils <- subsetProfiles(sp1, h="texture == 'LS'")) # re-combine subsets, note that duplicates are removed -g <- rbind(group.1, coarse.soils) +g <- union(list(group.1, coarse.soils)) plot(g) # reset plot area diff --git a/tests/testthat/test-SPC-objects.R b/tests/testthat/test-SPC-objects.R index 91492e086..336ec90a7 100644 --- a/tests/testthat/test-SPC-objects.R +++ b/tests/testthat/test-SPC-objects.R @@ -64,6 +64,31 @@ test_that("SPC deconstruction into a data.frame", { }) +test_that("SPC deconstruction into a list", { + + # do it here + l <- as(sp1, 'list') + + # result should be a list + expect_match(class(l), 'list') + + # there should be no NULL data, e.g. missing slots + res <- sapply(l, is.null) + expect_false(any(res)) + + # check internals + expect_equivalent(l$idcol, idname(sp1)) + expect_equivalent(l$hzidcol, hzidname(sp1)) + expect_equivalent(l$depthcols, horizonDepths(sp1)) + expect_equivalent(l$metadata, metadata(sp1)) + expect_equivalent(l$horizons, horizons(sp1)) + expect_equivalent(l$site, site(sp1)) + expect_equivalent(l$sp, sp1@sp) + expect_equivalent(l$diagnostic, diagnostic_hz(sp1)) + +}) + + test_that("SPC subsetting ", { # profile subsets @@ -290,36 +315,6 @@ test_that("SPC horizon ID init conflicts", { }) -test_that("SPC union ", { - - # test data - x <- sp1 - y <- sp1 - - # alter horizon and site data in copy - y$random <- runif(length(y)) - y$chroma <- NULL - # add diagnostic hz - diagnostic_hz(y) <- data.frame(id='P001', type='pizza') - - # this should not work, IDs aren't unqiue - expect_error(union(list(x, y))) - - # fix IDs manually - profile_id(y) <- sprintf("%s-copy", profile_id(y)) - - # this should work - z <- union(list(x,y)) - expect_match(class(z), 'SoilProfileCollection') - expect_equal(length(z), length(x) + length(y)) - - # full site/hz names - expect_equal(siteNames(z), unique(c(siteNames(x), siteNames(y)))) - expect_equal(horizonNames(z), unique(c(horizonNames(x), horizonNames(y)))) - - # diagnostic features - expect_equal(diagnostic_hz(z)[[idname(z)]], 'P001-copy') -}) diff --git a/tests/testthat/test-SPC-union.R b/tests/testthat/test-SPC-union.R new file mode 100644 index 000000000..59c689a35 --- /dev/null +++ b/tests/testthat/test-SPC-union.R @@ -0,0 +1,49 @@ +context("SoilProfileCollection union method") + +## make sample data +data(sp1, package = 'aqp') +depths(sp1) <- id ~ top + bottom +site(sp1) <- ~ group + +sp1$x <- seq(-119, -120, length.out = length(sp1)) +sp1$y <- seq(38, 39, length.out = length(sp1)) + +coordinates(sp1) <- ~ x + y + + +test_that("basic union tests", { + + # test data + x <- sp1 + y <- sp1 + + # alter horizon and site data in copy + y$random <- runif(length(y)) + y$chroma <- NULL + + # add diagnostic hz + diagnostic_hz(y) <- data.frame(id='P001', type='pizza') + + # this should not work, IDs aren't unqiue + expect_error(union(list(x, y))) + + # fix IDs manually + profile_id(y) <- sprintf("%s-copy", profile_id(y)) + + # this should work + z <- union(list(x,y)) + + expect_match(class(z), 'SoilProfileCollection') + expect_equal(length(z), length(x) + length(y)) + + # full site/hz names + expect_equal(siteNames(z), unique(c(siteNames(x), siteNames(y)))) + expect_equal(horizonNames(z), unique(c(horizonNames(x), horizonNames(y)))) + + # diagnostic features + expect_equal(diagnostic_hz(z)[[idname(z)]], 'P001-copy') + + # TODO: spatial data checks +}) + + From 19718c82b6024a23b7454399e889eec9ce714d1d Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Fri, 28 Dec 2018 11:21:25 -0800 Subject: [PATCH 17/19] fixing references to rbind, converting to union(list(...)), #71 --- man/SoilProfileCollection-class.Rd | 10 +--------- man/profileApply-methods.Rd | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/man/SoilProfileCollection-class.Rd b/man/SoilProfileCollection-class.Rd index 0b84b61dd..8da6f6eef 100644 --- a/man/SoilProfileCollection-class.Rd +++ b/man/SoilProfileCollection-class.Rd @@ -96,16 +96,8 @@ d.2 <- d[2, ] d.345 <- d[3:5, ] # recombine, note that profiles are sorted according to ID -d.new <- rbind(d.345, d.1, d.2) +d.new <- union(list(d.345, d.1, d.2)) plot(d.new) } - -\dontrun{ -# these next examples should throw an error -# insert a missing horizon boundary -data(sp1) -sp1$top[1] <- NA -depths(sp1) <- id ~ top + bottom -} } \keyword{classes} diff --git a/man/profileApply-methods.Rd b/man/profileApply-methods.Rd index 764947bcc..797ef0186 100644 --- a/man/profileApply-methods.Rd +++ b/man/profileApply-methods.Rd @@ -90,7 +90,7 @@ fun <- function(i) { l <- profileApply(sp1, fun, simplify=FALSE) # re-combine list of SoilProfileCollection objects into a single SoilProfileCollection -sp1.sub <- do.call(rbind, l) +sp1.sub <- union(l) # graphically check par(mfrow=c(2,1), mar=c(0,0,1,0)) From 5d5ba10a8100c00d12558900781a0f92abf048ca Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Fri, 28 Dec 2018 12:03:33 -0800 Subject: [PATCH 18/19] basic documentation for union --- NAMESPACE | 4 +++- R/union.R | 6 +++--- man/checkSPC.Rd | 2 +- man/union.Rd | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 man/union.Rd diff --git a/NAMESPACE b/NAMESPACE index ef8035234..8672aaece 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -25,7 +25,9 @@ importFrom(methods, setMethod, as, show, - slot + slot, + .hasSlot, + slotNames ) diff --git a/R/union.R b/R/union.R index f90981127..172049652 100644 --- a/R/union.R +++ b/R/union.R @@ -22,12 +22,14 @@ rbind.SoilProfileCollection <- function(...) { + # TODO: https://github.com/ncss-tech/aqp/issues/71 # # TODO: concatenation of data with duplicated IDs in @site, but unique data in other @site fields, will result in corrupt SPC # TODO: duplicates in @sp will cause errors # TODO: duplicates are removed in all other slots... does this make sense? -union <- function(spc=list(), method='all', ...) { +# NOTE: union is defined in base, do we need a better name? +union <- function(spc=list(), method='all') { # setup some defaults options(stringsAsFactors=FALSE) @@ -115,5 +117,3 @@ union <- function(spc=list(), method='all', ...) { return(res) } - - diff --git a/man/checkSPC.Rd b/man/checkSPC.Rd index 5b8583ea6..5c92f5e8f 100644 --- a/man/checkSPC.Rd +++ b/man/checkSPC.Rd @@ -1,5 +1,5 @@ \name{checkSPC} -\alias{isValidSPC} +\alias{checkSPC} \title{Test for a valid SoilProfileCollection} \description{Test for a valid SoilProfileCollection} diff --git a/man/union.Rd b/man/union.Rd new file mode 100644 index 000000000..162891466 --- /dev/null +++ b/man/union.Rd @@ -0,0 +1,46 @@ +\name{union} +\alias{union} + +\title{Combine Multiple SoilProfileCollection Objects} +\description{Safely combine multiple SoilProfileCollection objects that may not share the same internal structure.} + +\usage{ +union(spc = list(), method = "all") +} + +\arguments{ + \item{spc}{a \code{list} of \code{SoilProfileCollection} objects} + \item{method}{method ("all" or "intersection" [not yet implemented]) used to collect site and horizon level attributes, see details} +} + +\details{Method "all" returns all site and horizon level attributes, padded as needed with NA. Method "intersection" (not yet implemented) returns only those site and horizon level attributes that exist in all objects.} + +\note{Duplicates are removed.} + +\value{a new \code{SoilProfileCollection} object} + +\author{D.E. Beaudette and A.G. Brown} + + +\examples{ +# example data +data(sp2, package = 'aqp') +depths(sp2) <- id ~ top + bottom +site(sp2) <- ~ surface + +# copy pieces +x <- sp2[1:5, ] +y <- sp2[6:10, ] + +# reset IDs and combine +profile_id(y) <- sprintf("%s-copy", profile_id(y)) + +# this should work +z <- union(list(x,y)) + +# check +plot(z) +} + +\keyword{ manip }% use one of RShowDoc("KEYWORDS") + From be2011dd02d8f58edd58aa6a1e9418987136222e Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Fri, 28 Dec 2018 12:09:16 -0800 Subject: [PATCH 19/19] documentation for union, #71, ready to merge --- man/union.Rd | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/man/union.Rd b/man/union.Rd index 162891466..9b9357229 100644 --- a/man/union.Rd +++ b/man/union.Rd @@ -33,13 +33,38 @@ x <- sp2[1:5, ] y <- sp2[6:10, ] # reset IDs and combine -profile_id(y) <- sprintf("%s-copy", profile_id(y)) +profile_id(y) <- sprintf("\%s-copy", profile_id(y)) # this should work z <- union(list(x,y)) # check plot(z) + +\dontrun{ +library(plyr) + +ids <- sprintf("\%02d", 1:5) +x <- ldply(ids, random_profile, n=c(6, 7, 8), n_prop=1, method='LPP', + lpp.a=5, lpp.b=15, lpp.d=5, lpp.e=5, lpp.u=25) + +# promote to SPC and plot +depths(x ) <- id ~ top + bottom +plot(x, color='p1') + +# slice and update IDs +y <- slice(x, 0:150 ~ .) +profile_id(y) <- sprintf("\%s-sliced", profile_id(x)) + +# stack, note that @horizons is not the same in x and y +z <- union(list(x, y)) + +# lable groups +z$g <- substr(profile_id(z), 1, 2) + +par(mar=c(0,0,3,0)) +groupedProfilePlot(z, groups = 'g', color='p1', group.name.offset = -10, divide.hz=FALSE, name='') +} } \keyword{ manip }% use one of RShowDoc("KEYWORDS")