diff --git a/hyperSpec/R/Arith.R b/hyperSpec/R/Arith.R index 4e5eae7f9..754625776 100644 --- a/hyperSpec/R/Arith.R +++ b/hyperSpec/R/Arith.R @@ -76,74 +76,78 @@ ##' flu / flu$c -setMethod ("Arith", signature (e1 = "hyperSpec", e2 = "hyperSpec"), - function (e1, e2){ - validObject (e1) - validObject (e2) +setMethod( + "Arith", signature(e1 = "hyperSpec", e2 = "hyperSpec"), + function(e1, e2) { + validObject(e1) + validObject(e2) - e1 <- .expand (e1, dim (e2) [c (1, 3)]) - e2 <- .expand (e2, dim (e1) [c (1, 3)]) + e1 <- .expand(e1, dim(e2) [c(1, 3)]) + e2 <- .expand(e2, dim(e1) [c(1, 3)]) - e1 [[]] <- callGeneric (e1[[]], e2[[]]) - e1 - } - ) + e1 [[]] <- callGeneric(e1[[]], e2[[]]) + e1 + } +) -.arithx <- function (e1, e2){ - validObject (e1) +.arithx <- function(e1, e2) { + validObject(e1) - if (missing (e2)){ - e1 [[]] <- callGeneric (e1 [[]]) + if (missing(e2)) { + e1 [[]] <- callGeneric(e1 [[]]) e1 } else { - e2 <- as.matrix (e2) + e2 <- as.matrix(e2) ## called /only/ with e1 hyperSpec but e2 matrix-like - e1 <- .expand (e1, dim (e2)) - e2 <- .expand (e2, dim (e1) [c (1, 3)]) + e1 <- .expand(e1, dim(e2)) + e2 <- .expand(e2, dim(e1) [c(1, 3)]) - e1 [[]] <- callGeneric (e1 [[]], e2) + e1 [[]] <- callGeneric(e1 [[]], e2) e1 } } ##' @rdname Arith -setMethod ("Arith", signature (e1 = "hyperSpec", e2 = "numeric"), .arithx) +setMethod("Arith", signature(e1 = "hyperSpec", e2 = "numeric"), .arithx) ##' @rdname Arith -setMethod ("Arith", signature (e1 = "hyperSpec", e2 = "matrix"), .arithx) +setMethod("Arith", signature(e1 = "hyperSpec", e2 = "matrix"), .arithx) ##' @rdname Arith -setMethod ("Arith", signature (e1 = "hyperSpec", e2 = "missing"), .arithx) +setMethod("Arith", signature(e1 = "hyperSpec", e2 = "missing"), .arithx) -.arithy <- function (e1, e2){ - e1 <- as.matrix (e1) - validObject (e2) +.arithy <- function(e1, e2) { + e1 <- as.matrix(e1) + validObject(e2) ## called /only/ with e2 hyperSpec but e1 matrix-like - e1 <- .expand (e1, dim (e2) [c (1, 3)]) - e2 <- .expand (e2, dim (e1)) + e1 <- .expand(e1, dim(e2) [c(1, 3)]) + e2 <- .expand(e2, dim(e1)) - e2 [[]] <- callGeneric (e1, e2 [[]]) + e2 [[]] <- callGeneric(e1, e2 [[]]) e2 } ##' @rdname Arith -setMethod ("Arith", signature (e1 = "numeric", e2 = "hyperSpec"), .arithy) +setMethod("Arith", signature(e1 = "numeric", e2 = "hyperSpec"), .arithy) ##' @rdname Arith -setMethod ("Arith", signature (e1 = "matrix", e2 = "hyperSpec"), .arithy) +setMethod("Arith", signature(e1 = "matrix", e2 = "hyperSpec"), .arithy) ##' @param m matrix ##' @param target.dim target size to expand the vector to for the sweep-shortcuts ##' @noRd -.expand <- function (m, target.dim) { - m.dim = dim (m) +.expand <- function(m, target.dim) { + m.dim <- dim(m) - if (m.dim [1] == 1L & target.dim [1] > 1L) - m <- m [rep (1, target.dim [1]),, drop = FALSE] + if (m.dim [1] == 1L & target.dim [1] > 1L) { + m <- m [rep(1, target.dim [1]), , drop = FALSE] + } - if (is (m, "hyperSpec")) { - if (m.dim [3] == 1L & target.dim [2] > 1L) - m <- m [,, rep (1, target.dim [2]), wl.index = TRUE] + if (is(m, "hyperSpec")) { + if (m.dim [3] == 1L & target.dim [2] > 1L) { + m <- m [, , rep(1, target.dim [2]), wl.index = TRUE] + } } else { - if (m.dim [2] == 1L & target.dim [2] > 1L) - m <- m [, rep (1, target.dim [2]), drop = FALSE] + if (m.dim [2] == 1L & target.dim [2] > 1L) { + m <- m [, rep(1, target.dim [2]), drop = FALSE] + } } m @@ -156,79 +160,90 @@ setMethod ("Arith", signature (e1 = "matrix", e2 = "hyperSpec"), .arithy) ##' %*%,hyperSpec,matrix-method ##' @export ##' @seealso \code{\link[base]{matmult}} for matrix multiplications with \code{\%*\%}. -setMethod ("%*%", signature (x = "hyperSpec", y = "hyperSpec"), - function (x, y){ - validObject (x) - validObject (y) - - if (ncol(y) > 1) - warning(paste("Dropping column(s) of y:", paste(colnames(y$..), - collapse = ", "))) - - x@data$spc <- x@data$spc %*% y@data$spc - .wl (x) <- y@wavelength - x@label$.wavelength = y@label$.wavelength - - x - } - ) +setMethod( + "%*%", signature(x = "hyperSpec", y = "hyperSpec"), + function(x, y) { + validObject(x) + validObject(y) + + if (ncol(y) > 1) { + warning(paste("Dropping column(s) of y:", paste(colnames(y$..), + collapse = ", " + ))) + } + + x@data$spc <- x@data$spc %*% y@data$spc + .wl(x) <- y@wavelength + x@label$.wavelength <- y@label$.wavelength + + x + } +) ##' @rdname Arith -setMethod ("%*%", signature (x = "hyperSpec", y = "matrix"), - function (x, y){ - validObject (x) - x@data$spc <- x@data$spc %*% y - .wl (x) <- seq_len (ncol (y)) - x@label$.wavelength = NA - x - } - ) +setMethod( + "%*%", signature(x = "hyperSpec", y = "matrix"), + function(x, y) { + validObject(x) + x@data$spc <- x@data$spc %*% y + .wl(x) <- seq_len(ncol(y)) + x@label$.wavelength <- NA + x + } +) ##' @rdname Arith -setMethod ("%*%", signature (x = "matrix", y = "hyperSpec"), - function (x, y){ - validObject (y) - - if (ncol(y) > 1) - warning(paste("Dropping column(s) of y:", paste(colnames(y$..), - collapse = ", "))) - y <- new ("hyperSpec", - wavelength = y@wavelength, - spc = x %*% y@data$spc, - log = y@log - ) - - y - } - ) - -.test (.arithx) <- function (){ - context ("Arith") +setMethod( + "%*%", signature(x = "matrix", y = "hyperSpec"), + function(x, y) { + validObject(y) + + if (ncol(y) > 1) { + warning(paste("Dropping column(s) of y:", paste(colnames(y$..), + collapse = ", " + ))) + } + y <- new("hyperSpec", + wavelength = y@wavelength, + spc = x %*% y@data$spc, + log = y@log + ) + + y + } +) + +.test(.arithx) <- function() { + context("Arith") test_that("binary -", { - expect_equal (as.matrix (flu - flu), - matrix (0, nrow = nrow (flu), ncol = nwl (flu), dimnames = dimnames (flu [[]]))) - - expect_equal (as.matrix (flu - flu [1]), as.matrix (sweep (flu, 2, flu [1], `-`))) - - expect_equal (as.matrix (flu - flu [,, 450]), as.matrix (sweep (flu, 1, flu [,, 450], `-`))) + expect_equal( + as.matrix(flu - flu), + matrix(0, nrow = nrow(flu), ncol = nwl(flu), dimnames = dimnames(flu [[]])) + ) + + expect_equal(as.matrix(flu - flu [1]), as.matrix(sweep(flu, 2, flu [1], `-`))) + + expect_equal(as.matrix(flu - flu [, , 450]), as.matrix(sweep(flu, 1, flu [, , 450], `-`))) }) test_that("binary /", { - expect_equal (as.matrix (flu / flu), - matrix (1, nrow = nrow (flu), ncol = nwl (flu), dimnames = dimnames (flu [[]]))) - - expect_equal (as.matrix (flu / flu [1]), as.matrix (sweep (flu, 2, flu [1], `/`))) - - expect_equal (as.matrix (flu / flu [,, 450]), as.matrix (sweep (flu, 1, flu [,, 450], `/`))) + expect_equal( + as.matrix(flu / flu), + matrix(1, nrow = nrow(flu), ncol = nwl(flu), dimnames = dimnames(flu [[]])) + ) + + expect_equal(as.matrix(flu / flu [1]), as.matrix(sweep(flu, 2, flu [1], `/`))) + + expect_equal(as.matrix(flu / flu [, , 450]), as.matrix(sweep(flu, 1, flu [, , 450], `/`))) }) test_that("binary + with scalar", { - expect_equal (as.matrix (flu + 1), as.matrix (flu) + 1) - expect_equal (as.matrix (1 + flu), as.matrix (flu) + 1) + expect_equal(as.matrix(flu + 1), as.matrix(flu) + 1) + expect_equal(as.matrix(1 + flu), as.matrix(flu) + 1) }) test_that("unary -", { - expect_equal (as.matrix (-flu), - as.matrix (flu)) + expect_equal(as.matrix(-flu), -as.matrix(flu)) }) } diff --git a/hyperSpec/R/Compare.R b/hyperSpec/R/Compare.R index eb1b9acf7..796bf4220 100644 --- a/hyperSpec/R/Compare.R +++ b/hyperSpec/R/Compare.R @@ -1,18 +1,18 @@ ##' The comparison operators \code{>}, \code{<}, \code{>=}, \code{<=}, ##' \code{==}, and \code{!=} for \code{hyperSpec} objects. -##' +##' ##' \code{all.equal} checks the equality of two hyperSpec objects. -##' +##' ##' The comparison operators \code{>}, \code{<}, \code{>=}, \code{<=}, ##' \code{==}, and \code{!=} work on the spectra matrix of the \code{hyperSpec} ##' object. They have their usual meaning (see \code{\link[base]{Comparison}}). ##' The operators work also with one \code{hyperSpec} object and a numeric ##' (scalar) object or a matrices of the same size as the spectra matrix of the ##' \code{hyperSpec} object. -##' +##' ##' With numeric vectors \code{\link[hyperSpec]{sweep}} might be more ##' appropriate. -##' +##' ##' If you want to calculate on the \code{data.frame} \code{hyperSpec@@data}, ##' you have to do this directly on \code{hyperSpec@@data}. ##' @@ -29,56 +29,55 @@ ##' @param e1,e2 Either two \code{hyperSpec} objects or one \code{hyperSpec} ##' object and matrix of same size as \code{hyperSpec[[]]} or a scalar ##' (numeric of length 1). -##' +##' ##' As \code{hyperSpec} objects must have numeric spectra matrices, the ##' resulting matrix of the comparison is returned directly. ##' @return a logical matrix for the comparison operators. ##' @seealso \code{\link[hyperSpec]{sweep-methods}} for calculations involving ##' a vector and the spectral matrix. -##' +##' ##' \code{\link[methods]{S4groupGeneric}} for group generic methods. -##' +##' ##' \code{\link[base]{Comparison}} for the base comparison functions. -##' +##' ##' \code{\link[hyperSpec]{Arith}} for arithmetic operators, ##' \code{\link[hyperSpec]{Math}} for mathematical group generic functions ##' (groups Math and Math2) working on \code{hyperSpec} objects. ##' @keywords methods arith ##' @export ##' @examples -##' +##' ##' flu [,,445 ~ 450] > 300 -##' +##' ##' all (flu == flu[[]]) -##' +##' -setMethod ("Compare", signature (e1 = "hyperSpec", e2 = "hyperSpec"), - function (e1, e2){ - validObject (e1) - validObject (e2) +setMethod( + "Compare", signature(e1 = "hyperSpec", e2 = "hyperSpec"), + function(e1, e2) { + validObject(e1) + validObject(e2) - callGeneric (e1[[]], e2[[]]) - } - ) + callGeneric(e1[[]], e2[[]]) + } +) -.compx <- function (e1, e2){ - validObject (e1) - callGeneric (e1 [[]], e2) +.compx <- function(e1, e2) { + validObject(e1) + callGeneric(e1 [[]], e2) } -.compy <- function (e1, e2){ - validObject (e2) - callGeneric (e1, e2 [[]]) +.compy <- function(e1, e2) { + validObject(e2) + callGeneric(e1, e2 [[]]) } ##' @rdname Comparison -setMethod ("Compare", signature (e1 = "hyperSpec", e2 = "numeric"), .compx) +setMethod("Compare", signature(e1 = "hyperSpec", e2 = "numeric"), .compx) ##' @rdname Comparison -setMethod ("Compare", signature (e1 = "hyperSpec", e2 = "matrix"), .compx) +setMethod("Compare", signature(e1 = "hyperSpec", e2 = "matrix"), .compx) ##' @rdname Comparison -setMethod ("Compare", signature (e1 = "numeric", e2 = "hyperSpec"), .compy) +setMethod("Compare", signature(e1 = "numeric", e2 = "hyperSpec"), .compy) ##' @rdname Comparison -setMethod ("Compare", signature (e1 = "matrix", e2 = "hyperSpec"), .compy) - - +setMethod("Compare", signature(e1 = "matrix", e2 = "hyperSpec"), .compy) diff --git a/hyperSpec/R/DollarNames.R b/hyperSpec/R/DollarNames.R index fe1ba1d1e..e96fb75cc 100644 --- a/hyperSpec/R/DollarNames.R +++ b/hyperSpec/R/DollarNames.R @@ -11,19 +11,19 @@ ##' @param pattern pattern to look for ##' @return the name of the extra data slot ##' @importFrom utils .DollarNames -.DollarNames.hyperSpec <- function (x, pattern = "") - grep (pattern, colnames (x@data), value = TRUE) +.DollarNames.hyperSpec <- function(x, pattern = "") { + grep(pattern, colnames(x@data), value = TRUE) +} -.test (.DollarNames.hyperSpec) <- function(){ - context (".DollarNames") +.test(.DollarNames.hyperSpec) <- function() { + context(".DollarNames") test_that("expansion on missing pattern", { - expect_equal(.DollarNames (flu), colnames (flu)) + expect_equal(.DollarNames(flu), colnames(flu)) }) test_that("expansion on missing pattern", { - expect_equal(.DollarNames (flu, "f"), "filename") - expect_equal(.DollarNames (flu, "c"), c ("spc", "c")) + expect_equal(.DollarNames(flu, "f"), "filename") + expect_equal(.DollarNames(flu, "c"), c("spc", "c")) }) - } diff --git a/hyperSpec/R/Math.R b/hyperSpec/R/Math.R index 4ba13717c..624470771 100644 --- a/hyperSpec/R/Math.R +++ b/hyperSpec/R/Math.R @@ -40,42 +40,44 @@ ##' log (flu) ##' -setMethod ("Math2", signature (x = "hyperSpec"), - function (x, digits){ - validObject (x) +setMethod( + "Math2", signature(x = "hyperSpec"), + function(x, digits) { + validObject(x) - x [[]] <- callGeneric (x[[]], digits) + x [[]] <- callGeneric(x[[]], digits) - x - } - ) + x + } +) ##' @rdname math ##' @param ... ignored ##' @param base base of logarithm ##' @export ##' @aliases log log,hyperSpec-method -setMethod ("log", signature (x = "hyperSpec"), - function (x, base = exp (1), ...){ - validObject (x) +setMethod( + "log", signature(x = "hyperSpec"), + function(x, base = exp(1), ...) { + validObject(x) - x [[]] <- log (x[[]], base = base) - x - } + x [[]] <- log(x[[]], base = base) + x + } ) ##' @rdname math ##' @export -setMethod ("Math", signature (x = "hyperSpec"), - function (x){ - validObject (x) +setMethod( + "Math", signature(x = "hyperSpec"), + function(x) { + validObject(x) - if (grepl ("^cum", .Generic) || grepl ("gamma$", .Generic)) - warning (paste ("Do you really want to use", .Generic, "on a hyperSpec object?")) + if (grepl("^cum", .Generic) || grepl("gamma$", .Generic)) { + warning(paste("Do you really want to use", .Generic, "on a hyperSpec object?")) + } - x [[]] <- callGeneric (x[[]]) - x - } + x [[]] <- callGeneric(x[[]]) + x + } ) - - diff --git a/hyperSpec/R/Summary.R b/hyperSpec/R/Summary.R index bc1847834..7394c52e9 100644 --- a/hyperSpec/R/Summary.R +++ b/hyperSpec/R/Summary.R @@ -1,17 +1,17 @@ ##' The functions -##' +##' ##' \code{all}, \code{any}, -##' +##' ##' \code{sum}, \code{prod}, -##' -##' \code{min}, \code{max}, -##' +##' +##' \code{min}, \code{max}, +##' ##' \code{range}, and ##' ##' \code{is.na} -##' +##' ##' for \code{hyperSpec} objects. -##' +##' ##' All these functions work on the spectra matrix. ##' @name Summary ##' @docType methods @@ -27,132 +27,146 @@ ##' @seealso \code{\link[base]{Summary}} for the base summary functions. ##' @export ##' @examples -##' -##' range (flu) -##' -setMethod ("Summary", signature (x = "hyperSpec"), - function (x, ..., na.rm = FALSE){ - validObject (x) +##' +##' range (flu) +##' +setMethod( + "Summary", signature(x = "hyperSpec"), + function(x, ..., na.rm = FALSE) { + validObject(x) - if ((.Generic == "prod") || (.Generic == "sum")) - warning (paste ("Do you really want to use", .Generic, "on a hyperSpec object?")) + if ((.Generic == "prod") || (.Generic == "sum")) { + warning(paste("Do you really want to use", .Generic, "on a hyperSpec object?")) + } - ## dispatch also on the objects in ... - x <- sapply (list (x[[]], ...), .Generic, na.rm = na.rm) + ## dispatch also on the objects in ... + x <- sapply(list(x[[]], ...), .Generic, na.rm = na.rm) - callGeneric (x, na.rm = na.rm) - } - ) + callGeneric(x, na.rm = na.rm) + } +) ##' @rdname summary ##' @aliases is.na,hyperSpec-method ##' @seealso \code{\link[base]{all.equal}} and \code{\link[base]{isTRUE}} ##' @export ##' @examples -##' +##' ##' is.na (flu [,, 405 ~ 410]); -setMethod ("is.na", signature (x = "hyperSpec"), - function (x) { - is.na (x@data$spc) - }) - -##' \code{all_wl} and \code{any_wl} are shortcut function to check whether -##' any or all intensities fulfill the condition per spectrum. +setMethod( + "is.na", signature(x = "hyperSpec"), + function(x) { + is.na(x@data$spc) + } +) + +##' \code{all_wl} and \code{any_wl} are shortcut function to check whether +##' any or all intensities fulfill the condition per spectrum. ##' \code{na.rm} behaviour is like \code{\link[base]{all}} and \code{\link[base]{any}}. -##' +##' ##' @param expression expression that evaluates to a logical matrix of the same size as the spectra matrix -##' +##' ##' @rdname summary ##' @export ##' @examples -##' +##' ##' all_wl (flu > 100) all_wl <- function(expression, na.rm = FALSE) { res <- rowSums(!expression, na.rm = TRUE) == 0 - - if (! na.rm) - res [res] <- rowSums(expression [res,,drop = FALSE], na.rm = FALSE) == ncol (expression) - + + if (!na.rm) { + res [res] <- rowSums(expression [res, , drop = FALSE], na.rm = FALSE) == ncol(expression) + } + res } -.test (all_wl) <- function() { - context ("all_wl") - - test_that ("checking minimum intensity", - expect_equal(all_wl (flu > 100), - apply (flu > 100, 1, all)) +.test(all_wl) <- function() { + context("all_wl") + + test_that( + "checking minimum intensity", + expect_equal( + all_wl(flu > 100), + apply(flu > 100, 1, all) + ) ) - - test_that ("na.rm behaviour of base::all", { - expect_true(is.na (all (TRUE, NA))) - expect_true(!is.na (all (FALSE, NA))) - - expect_true(all (TRUE, NA, na.rm = TRUE)) + + test_that("na.rm behaviour of base::all", { + expect_true(is.na(all(TRUE, NA))) + expect_true(!is.na(all(FALSE, NA))) + + expect_true(all(TRUE, NA, na.rm = TRUE)) }) - - test_that ("na.rm", { + + test_that("na.rm", { tmp <- flu - tmp [[3:4,,450 ~ 460]] <- NA - - expect_equal (all_wl (tmp > 100), - apply (tmp > 100, 1, all) + tmp [[3:4, , 450 ~ 460]] <- NA + + expect_equal( + all_wl(tmp > 100), + apply(tmp > 100, 1, all) ) - expect_equal (all_wl (tmp > 100, na.rm = TRUE), - apply (tmp > 100, 1, all, na.rm = TRUE) + expect_equal( + all_wl(tmp > 100, na.rm = TRUE), + apply(tmp > 100, 1, all, na.rm = TRUE) ) - expect_equal (all_wl (tmp > 100, na.rm = FALSE), - apply (tmp > 100, 1, all, na.rm = FALSE) + expect_equal( + all_wl(tmp > 100, na.rm = FALSE), + apply(tmp > 100, 1, all, na.rm = FALSE) ) - }) - } ##' @rdname summary ##' @export ##' @examples -##' +##' ##' any_wl (flu > 300) ##' ! any_wl (is.na (flu)) any_wl <- function(expression, na.rm = FALSE) { - res <- rowSums(expression, na.rm = TRUE) > 0 - - if (! na.rm) - res [!res] <- !rowSums(expression [!res,,drop = FALSE], na.rm = FALSE) == 0 - + + if (!na.rm) { + res [!res] <- !rowSums(expression [!res, , drop = FALSE], na.rm = FALSE) == 0 + } + res } -.test (any_wl) <- function (){ - context ("any_wl") - - test_that ("checking maximum intensity", - expect_equal(any_wl (flu > 400), - apply (flu > 400, 1, any)) +.test(any_wl) <- function() { + context("any_wl") + + test_that( + "checking maximum intensity", + expect_equal( + any_wl(flu > 400), + apply(flu > 400, 1, any) + ) ) - - test_that ("na.rm behaviour of base::any", { - expect_true(!is.na (any (TRUE, NA))) - expect_true(is.na (any (FALSE, NA))) - - expect_true(!any (FALSE, NA, na.rm = TRUE)) + + test_that("na.rm behaviour of base::any", { + expect_true(!is.na(any(TRUE, NA))) + expect_true(is.na(any(FALSE, NA))) + + expect_true(!any(FALSE, NA, na.rm = TRUE)) }) - - test_that ("na.rm", { + + test_that("na.rm", { tmp <- flu - tmp [[3:4,,450 ~ 460]] <- NA - - expect_equal (any_wl (tmp > 400), - apply (tmp > 400, 1, any) + tmp [[3:4, , 450 ~ 460]] <- NA + + expect_equal( + any_wl(tmp > 400), + apply(tmp > 400, 1, any) ) - expect_equal (any_wl (tmp > 400, na.rm = TRUE), - apply (tmp > 400, 1, any, na.rm = TRUE) + expect_equal( + any_wl(tmp > 400, na.rm = TRUE), + apply(tmp > 400, 1, any, na.rm = TRUE) ) - expect_equal (any_wl (tmp > 400, na.rm = FALSE), - apply (tmp > 400, 1, any, na.rm = FALSE) + expect_equal( + any_wl(tmp > 400, na.rm = FALSE), + apply(tmp > 400, 1, any, na.rm = FALSE) ) - }) } diff --git a/hyperSpec/R/aggregate.R b/hyperSpec/R/aggregate.R index fcfa36685..f449d51d5 100644 --- a/hyperSpec/R/aggregate.R +++ b/hyperSpec/R/aggregate.R @@ -1,56 +1,61 @@ -.aggregate <- function (x, by = stop ("by is needed"), FUN = stop ("FUN is needed."), - ..., out.rows = NULL, append.rows = NULL, - by.isindex = FALSE){ - validObject (x) +.aggregate <- function(x, by = stop("by is needed"), FUN = stop("FUN is needed."), + ..., out.rows = NULL, append.rows = NULL, + by.isindex = FALSE) { + validObject(x) - if (!is.list (by) || ! by.isindex) - by <- split (seq (x, index = TRUE), by, drop = TRUE) + if (!is.list(by) || !by.isindex) { + by <- split(seq(x, index = TRUE), by, drop = TRUE) + } ## main work here is to avoid calling stats::aggregate as there splitting and ## rearranging is involved. That is slow with the spectra. # try a guess how many rows the result will have - if (is.null (out.rows)){ - tmp <- .apply (data = x@data[by [[1]], , drop = FALSE], MARGIN = 2, FUN = FUN, ...) + if (is.null(out.rows)) { + tmp <- .apply(data = x@data[by [[1]], , drop = FALSE], MARGIN = 2, FUN = FUN, ...) - out.rows <- nrow (tmp) * length (by) + out.rows <- nrow(tmp) * length(by) } - data <- x@data[rep (1, out.rows), , drop = FALSE] # preallocate memory - data <- cbind (data, .aggregate = NA) - col.aggregate <- ncol (data) + data <- x@data[rep(1, out.rows), , drop = FALSE] # preallocate memory + data <- cbind(data, .aggregate = NA) + col.aggregate <- ncol(data) r <- 1 # keeping track of the actually filled rows - for (i in seq (along = by)){ - tmp <- .apply (data = x@data[by [[i]], , drop = FALSE], MARGIN = 2, FUN = FUN, ...) + for (i in seq(along = by)) { + tmp <- .apply(data = x@data[by [[i]], , drop = FALSE], MARGIN = 2, FUN = FUN, ...) - prows <- nrow (tmp) - 1 + prows <- nrow(tmp) - 1 ## TODO: try out whether this really helps if (r + prows > out.rows) { - if (is.null (append.rows)) - append.rows <- max (100, ceiling (1 - (i / length (by)) * out.rows)) - out.rows <- max (append.rows + out.rows, r + prows) - data <- rbind (data, data [rep (1, out.rows - nrow (data)), , drop = FALSE]) - warning ("At", i, "of", length (by), - "levels: Output data.frame too small. Consider using an", - "appropriate value for out.rows to speed up calculations.") + if (is.null(append.rows)) { + append.rows <- max(100, ceiling(1 - (i / length(by)) * out.rows)) + } + out.rows <- max(append.rows + out.rows, r + prows) + data <- rbind(data, data [rep(1, out.rows - nrow(data)), , drop = FALSE]) + warning( + "At", i, "of", length(by), + "levels: Output data.frame too small. Consider using an", + "appropriate value for out.rows to speed up calculations." + ) } - if (prows >= 0){ - data[r : (r + prows), -col.aggregate] <- tmp - data[r : (r + prows), col.aggregate] <- i + if (prows >= 0) { + data[r:(r + prows), -col.aggregate] <- tmp + data[r:(r + prows), col.aggregate] <- i r <- r + prows + 1 } } - x@data <- data[seq_len (r - 1), , drop = FALSE] - x@data[, col.aggregate] <- factor (x@data[, col.aggregate], levels = seq_along (by)) + x@data <- data[seq_len(r - 1), , drop = FALSE] + x@data[, col.aggregate] <- factor(x@data[, col.aggregate], levels = seq_along(by)) - if (!is.null (names (by)) && !any (is.na (names (by)))) - levels (x@data[, col.aggregate]) <- names (by) + if (!is.null(names(by)) && !any(is.na(names(by)))) { + levels(x@data[, col.aggregate]) <- names(by) + } x } @@ -144,43 +149,51 @@ ##' plot (agg, "spc", add = TRUE, col = color[agg$.aggregate], ##' lines.args = list (lwd = 3, lty = 2)) ##' -setMethod ("aggregate", signature = signature (x = "hyperSpec"), .aggregate) +setMethod("aggregate", signature = signature(x = "hyperSpec"), .aggregate) -.test (.aggregate) <- function (){ - context ("aggregate") +.test(.aggregate) <- function() { + context("aggregate") test_that("chondro cluster means", { - cluster.means <- aggregate (chondro, chondro$clusters, mean_pm_sd) - expect_true(all (is.na (cluster.means$y))) - expect_true(all (is.na (cluster.means$x))) + cluster.means <- aggregate(chondro, chondro$clusters, mean_pm_sd) + expect_true(all(is.na(cluster.means$y))) + expect_true(all(is.na(cluster.means$x))) - expect_equal (cluster.means$clusters, cluster.means$.aggregate) + expect_equal(cluster.means$clusters, cluster.means$.aggregate) - for (cluster in levels (chondro$clusters)) - expect_equivalent (cluster.means [[cluster.means$clusters == cluster,]], - apply (chondro [[chondro$clusters == cluster,]],2, mean_pm_sd)) + for (cluster in levels(chondro$clusters)) { + expect_equivalent( + cluster.means [[cluster.means$clusters == cluster, ]], + apply(chondro [[chondro$clusters == cluster, ]], 2, mean_pm_sd) + ) + } }) - test_that ("FUN returning different numbers of values for different groups", { - spc <- new ("hyperSpec", spc = sweep (matrix (rnorm (10*20), ncol = 20), 1, (1:10)*5 - , "+")) - by <- as.factor (c (1, 1, 1, 1, 1, 1, 5, 1, 2, 2)) - - weird.function <- function (x){ - if (length (x) == 1) - x + 1 : 10 - else if (length (x) == 2) + test_that("FUN returning different numbers of values for different groups", { + spc <- new("hyperSpec", spc = sweep( + matrix(rnorm(10 * 20), ncol = 20), 1, (1:10) * 5, + "+" + )) + by <- as.factor(c(1, 1, 1, 1, 1, 1, 5, 1, 2, 2)) + + weird.function <- function(x) { + if (length(x) == 1) { + x + 1:10 + } else if (length(x) == 2) { NULL - else + } else { x [1] + } } - expect_warning(agg <- aggregate (spc, by, weird.function)) - agg <- aggregate (spc, by, weird.function, out.rows = 20L) + expect_warning(agg <- aggregate(spc, by, weird.function)) + agg <- aggregate(spc, by, weird.function, out.rows = 20L) - expect_equal (agg$.aggregate, - structure(c(1L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), - .Label = c("1", "2", "5"), class = "factor")) + expect_equal( + agg$.aggregate, + structure(c(1L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), + .Label = c("1", "2", "5"), class = "factor" + ) + ) }) - } diff --git a/hyperSpec/R/all.equal.R b/hyperSpec/R/all.equal.R index 9e8135866..654fbf115 100644 --- a/hyperSpec/R/all.equal.R +++ b/hyperSpec/R/all.equal.R @@ -1,74 +1,84 @@ -.all.equal <- function (target, current, ..., check.attributes = FALSE, check.names = FALSE, - check.column.order = FALSE, check.label = FALSE, - tolerance = hy.getOption ("tolerance"), wl.tolerance = hy.getOption ("wl.tolerance")){ - validObject (target) - validObject (current) - tolerance <- .checkpos ( tolerance, "tolerance") - wl.tolerance <- .checkpos (wl.tolerance, "wl.tolerance") +.all.equal <- function(target, current, ..., check.attributes = FALSE, check.names = FALSE, + check.column.order = FALSE, check.label = FALSE, + tolerance = hy.getOption("tolerance"), wl.tolerance = hy.getOption("wl.tolerance")) { + validObject(target) + validObject(current) + tolerance <- .checkpos(tolerance, "tolerance") + wl.tolerance <- .checkpos(wl.tolerance, "wl.tolerance") - result <- character (0) + result <- character(0) - cmp <- all.equal (target = target@wavelength, current = current@wavelength, ..., - tolerance = wl.tolerance, - check.attributes = check.attributes, check.names = check.names) - if (! isTRUE (cmp)) result <- c("@wavelength:", cmp) + cmp <- all.equal( + target = target@wavelength, current = current@wavelength, ..., + tolerance = wl.tolerance, + check.attributes = check.attributes, check.names = check.names + ) + if (!isTRUE(cmp)) result <- c("@wavelength:", cmp) - if (check.column.order) - cmp <- all.equal (target = target@data, current = current@data, ..., - tolerance = tolerance, - check.attributes = check.attributes) - else - cmp <- all.equal (target = target@data [order (colnames ( target@data))], - current = current@data [order (colnames (current@data))], - ..., - tolerance = tolerance, - check.attributes = check.attributes, check.names = check.names) - if (! isTRUE (cmp)) result <- c (result, "@data:", cmp) + if (check.column.order) { + cmp <- all.equal( + target = target@data, current = current@data, ..., + tolerance = tolerance, + check.attributes = check.attributes + ) + } else { + cmp <- all.equal( + target = target@data [order(colnames(target@data))], + current = current@data [order(colnames(current@data))], + ..., + tolerance = tolerance, + check.attributes = check.attributes, check.names = check.names + ) + } + if (!isTRUE(cmp)) result <- c(result, "@data:", cmp) - if (check.label){ - cmp <- all.equal (target = target@label [order (names (target@label))], - current = current@label [order (names (current@label))], - ..., - check.attributes = check.attributes, check.names = check.names) - if (! isTRUE (cmp)) result <- c (result, "@label:", cmp) + if (check.label) { + cmp <- all.equal( + target = target@label [order(names(target@label))], + current = current@label [order(names(current@label))], + ..., + check.attributes = check.attributes, check.names = check.names + ) + if (!isTRUE(cmp)) result <- c(result, "@label:", cmp) } - if (length (result) == 0) + if (length(result) == 0) { TRUE - else + } else { result + } } ##' @include unittest.R -.test (.all.equal) <- function () { - context (".all.equal") +.test(.all.equal) <- function() { + context(".all.equal") test_that("basic equalities", { - expect_true (all.equal (flu, --flu)) - expect_true (all.equal (flu, --flu, check.attributes = TRUE)) - expect_true (all.equal (flu, --flu, check.names = TRUE)) + expect_true(all.equal(flu, --flu)) + expect_true(all.equal(flu, --flu, check.attributes = TRUE)) + expect_true(all.equal(flu, --flu, check.names = TRUE)) }) test_that("labels", { - expect_true (all.equal (flu, --flu, check.label = TRUE)) + expect_true(all.equal(flu, --flu, check.label = TRUE)) }) test_that("labels: order of labels does *not* matter", { tmp <- flu - tmp@label <- rev (tmp@label) - expect_true (all.equal (flu, tmp, check.label = TRUE)) + tmp@label <- rev(tmp@label) + expect_true(all.equal(flu, tmp, check.label = TRUE)) }) test_that("labels: character vs. expression does matter:", { tmp <- flu - tmp@label <- lapply (tmp@label, as.expression) - expect_true (! isTRUE (all.equal (flu, tmp, check.label = TRUE))) + tmp@label <- lapply(tmp@label, as.expression) + expect_true(!isTRUE(all.equal(flu, tmp, check.label = TRUE))) }) test_that("column order", { - expect_true ( all.equal (flu, --flu, check.column.order = TRUE)) - expect_true (! isTRUE (all.equal (flu, flu [, rev (colnames (flu))], check.column.order = TRUE))) - expect_true ( all.equal (flu, flu [, rev (colnames (flu))], check.column.order = FALSE)) + expect_true(all.equal(flu, --flu, check.column.order = TRUE)) + expect_true(!isTRUE(all.equal(flu, flu [, rev(colnames(flu))], check.column.order = TRUE))) + expect_true(all.equal(flu, flu [, rev(colnames(flu))], check.column.order = FALSE)) }) } @@ -92,4 +102,4 @@ ##' \code{\link[base]{isTRUE}}. ##' @seealso \code{\link[base]{all.equal}} and \code{\link[base]{isTRUE}} ##' @export -setMethod ("all.equal", signature (target = "hyperSpec", current = "hyperSpec"), .all.equal) +setMethod("all.equal", signature(target = "hyperSpec", current = "hyperSpec"), .all.equal) diff --git a/hyperSpec/R/apply.R b/hyperSpec/R/apply.R index 923bb7265..4433a3737 100644 --- a/hyperSpec/R/apply.R +++ b/hyperSpec/R/apply.R @@ -1,49 +1,52 @@ -.na.if.different <- function (x) { - if (length (unique (x)) > 1) NA else x[1] +.na.if.different <- function(x) { + if (length(unique(x)) > 1) NA else x[1] } -.apply <- function (data, MARGIN, FUN, ...){ - - if (length (data$spc) == 0) - stop ("empty spectra matrix.") +.apply <- function(data, MARGIN, FUN, ...) { + if (length(data$spc) == 0) { + stop("empty spectra matrix.") + } - spc <- apply (data [, "spc", drop = FALSE], MARGIN, FUN, ...) + spc <- apply(data [, "spc", drop = FALSE], MARGIN, FUN, ...) - if (MARGIN == 1){ - if (is.null (spc)) - spc <- matrix (ncol = 0, nrow = nrow (data)) - else if (is.vector (spc)) - dim (spc) <- c(length (spc), 1) - else if (is.matrix (spc)) - spc <- t (spc) + if (MARGIN == 1) { + if (is.null(spc)) { + spc <- matrix(ncol = 0, nrow = nrow(data)) + } else if (is.vector(spc)) { + dim(spc) <- c(length(spc), 1) + } else if (is.matrix(spc)) { + spc <- t(spc) + } data$spc <- I(spc) - } else if (MARGIN == 2){ - if (is.null (spc)) - return (data [0, ]) - if (is.null (dim (spc))) - dim (spc) <- c(1, ncol (data$spc)) + } else if (MARGIN == 2) { + if (is.null(spc)) { + return(data [0, ]) + } + if (is.null(dim(spc))) { + dim(spc) <- c(1, ncol(data$spc)) + } - if (all(dim (spc) == dim (data$spc))){ + if (all(dim(spc) == dim(data$spc))) { data$spc <- spc - } else { - nrow <- nrow (spc) + } else { + nrow <- nrow(spc) - cols <- colnames (data) - cols <- which (cols != "spc") - if (length (cols) > 0) { - data [1,cols] <- lapply (data [,cols,drop = FALSE], .na.if.different) + cols <- colnames(data) + cols <- which(cols != "spc") + if (length(cols) > 0) { + data [1, cols] <- lapply(data [, cols, drop = FALSE], .na.if.different) } - data <- data [rep (1, nrow), , drop = FALSE] + data <- data [rep(1, nrow), , drop = FALSE] - data$spc <- I (spc) - rownames (data) <- rownames (spc) + data$spc <- I(spc) + rownames(data) <- rownames(spc) } } - data$spc <- unclass (data$spc) + data$spc <- unclass(data$spc) data } @@ -116,97 +119,102 @@ ##' ## whereas MARGIN = 1 : 2 leads to FUN being called for each element separately ##' apply (flu [,,405:407], 1 : 2, print) [[]] ##' -setMethod ("apply", signature = signature (X = "hyperSpec"), - function (X, MARGIN, FUN, ..., - label.wl = NULL, label.spc = NULL, new.wavelength = NULL){ - validObject (X) +setMethod("apply", + signature = signature(X = "hyperSpec"), + function(X, MARGIN, FUN, ..., + label.wl = NULL, label.spc = NULL, new.wavelength = NULL) { + validObject(X) - if (missing (MARGIN)){ # apply for functions that the complete spectra matrix - ## is easier: tmp <- apply (x, , FUN, ...) - ## does: - ## tmp <- x - ## tmp [[]] <- FUN (x [[]], ...) + if (missing(MARGIN)) { # apply for functions that the complete spectra matrix + ## is easier: tmp <- apply (x, , FUN, ...) + ## does: + ## tmp <- x + ## tmp [[]] <- FUN (x [[]], ...) - X@data$spc <- do.call (FUN, list (X@data$spc, ...)) + X@data$spc <- do.call(FUN, list(X@data$spc, ...)) + } else if (all(MARGIN == 1:2)) { # apply for functions that take scalar arguments. - } else if (all (MARGIN == 1 : 2)){ # apply for functions that take scalar arguments. + tmp <- apply(X@data$spc, MARGIN = MARGIN, FUN, ...) + tmp <- as.numeric(tmp) # otherwise surprises will be waiting - tmp <- apply (X@data$spc, MARGIN = MARGIN, FUN, ...) - tmp <- as.numeric (tmp) # otherwise surprises will be waiting + dim(tmp) <- dim(X@data$spc) - dim (tmp) <- dim (X@data$spc) + X@data$spc <- tmp + } else { + ## the usual: for each row / for each column - X@data$spc <- tmp + X@data <- .apply(X@data, MARGIN = MARGIN, FUN = FUN, ...) - } else { - ## the usual: for each row / for each column + if (all(MARGIN == 1)) { - X@data <- .apply (X@data, MARGIN = MARGIN, FUN = FUN, ...) + ## if the number of data points per spectrum is changed, the wavelength vector needs to be + ## adapted, too - if (all (MARGIN == 1)) { + if (ncol(X@data$spc) != length(X@wavelength)) { - ## if the number of data points per spectrum is changed, the wavelength vector needs to be - ## adapted, too + ## only internal functions here: the validation will fail until the wavelength axis is + ## adjusted - if (ncol (X@data$spc) != length (X@wavelength)) { + if (!is.null(new.wavelength)) { # vector with new wavelength is given + if (is.numeric(new.wavelength)) { # either directly, + .wl(X) <- new.wavelength + } else { + dots <- list(...) + .wl(X) <- dots [[new.wavelength]] # or as name of the argument that becomes the new + # wavelength vector + } + } else if (ncol(X@data$spc) != length(X@wavelength)) { + wl <- as.numeric(colnames(X@data$spc)) # if not given, try to make from colnames of the + # spectra matrix - ## only internal functions here: the validation will fail until the wavelength axis is - ## adjusted + if (length(wl) != ncol(X@data$spc) || any(is.na(wl))) { + wl <- seq_len(ncol(X@data$spc)) + } # or just number sequentially - if (!is.null (new.wavelength)){ # vector with new wavelength is given - if (is.numeric (new.wavelength)) # either directly, - .wl (X) <- new.wavelength - else { - dots <- list (...) - .wl (X) <- dots [[new.wavelength]] # or as name of the argument that becomes the new - # wavelength vector + .wl(X) <- wl } - } else if (ncol (X@data$spc) != length (X@wavelength)){ - wl <- as.numeric (colnames (X@data$spc)) # if not given, try to make from colnames of the - # spectra matrix - - if (length (wl) != ncol (X@data$spc) || any (is.na (wl))) - wl <- seq_len (ncol (X@data$spc)) # or just number sequentially - - .wl (X) <- wl } } } - } - if (!is.null (label.wl)) - X@label$.wavelength <- label.wl + if (!is.null(label.wl)) { + X@label$.wavelength <- label.wl + } - if (!is.null (label.spc)) - X@label$spc <- label.spc + if (!is.null(label.spc)) { + X@label$spc <- label.spc + } - validObject (X) + validObject(X) - X -}) + X + } +) ##' @include unittest.R -.test (.apply) <- function (){ - context ("apply") +.test(.apply) <- function() { + context("apply") - test_that ("check whether .na.if.different is working correctly", { + test_that("check whether .na.if.different is working correctly", { flu$equal <- 1 - tmp <- apply (flu, 2, mean)$.. - expect_equal (is.na (tmp), - structure(c (TRUE, TRUE, FALSE), - .Dim = c(1L, 3L), - .Dimnames = list (NULL, c("filename", "c", "equal"))) + tmp <- apply(flu, 2, mean)$.. + expect_equal( + is.na(tmp), + structure(c(TRUE, TRUE, FALSE), + .Dim = c(1L, 3L), + .Dimnames = list(NULL, c("filename", "c", "equal")) + ) ) - expect_equal (tmp$equal, 1) + expect_equal(tmp$equal, 1) }) - test_that ("POSIXct", { + test_that("POSIXct", { flu$ct <- as.POSIXct(Sys.time()) - expect_equal (apply (flu, 2, mean)$ct, flu$ct [1]) + expect_equal(apply(flu, 2, mean)$ct, flu$ct [1]) }) - test_that ("POSIXlt", { + test_that("POSIXlt", { flu$lt <- as.POSIXlt(Sys.time()) - expect_equal (apply (flu, 2, mean)$lt, flu$lt [1]) + expect_equal(apply(flu, 2, mean)$lt, flu$lt [1]) }) } diff --git a/hyperSpec/R/as.data.frame.R b/hyperSpec/R/as.data.frame.R index 4a967d628..6b17e249d 100644 --- a/hyperSpec/R/as.data.frame.R +++ b/hyperSpec/R/as.data.frame.R @@ -14,125 +14,135 @@ ##' @author C. Beleites ##' @method as.data.frame hyperSpec ##' @export -##' @seealso \code{\link[base]{as.data.frame}} +##' @seealso \code{\link[base]{as.data.frame}} ##' @keywords methods ##' @examples -##' +##' ##' as.data.frame (chondro [1:3,, 600 ~ 620]) ##' as.matrix (chondro [1:3,, 600 ~ 620]) ##' lm (c ~ spc, data = flu [,,450]) -as.data.frame.hyperSpec <- function (x, row.names = TRUE, optional = NULL, ...){ - validObject (x) +as.data.frame.hyperSpec <- function(x, row.names = TRUE, optional = NULL, ...) { + validObject(x) x <- x@data - - if (!is.null (row.names)) - if (isTRUE (row.names)){ - if (is.null (rownames (x))) - x$.row <- seq_len (nrow (x)) - else - x$.row <- rownames (x) - } else - rownames (x) <- row.names - + + if (!is.null(row.names)) { + if (isTRUE(row.names)) { + if (is.null(rownames(x))) { + x$.row <- seq_len(nrow(x)) + } else { + x$.row <- rownames(x) + } + } else { + rownames(x) <- row.names + } + } + x } ##' @method as.matrix hyperSpec ##' @rdname asdataframe -##' @param ... ignored +##' @param ... ignored ##' @aliases as.matrix as.matrix,hyperSpec-method ##' @export ##' @md ##' @seealso and [base::as.matrix()] -##' +##' ##' [`[[`()] (`[[]]`) for a shortcut to `as.matrix` -as.matrix.hyperSpec <- function (x, ...){ - validObject (x) +as.matrix.hyperSpec <- function(x, ...) { + validObject(x) - unclass (x@data$spc) # remove the AsIs + unclass(x@data$spc) # remove the AsIs } ##' `as.wide.df` converts the spectra matrix to a data.frame. The extra ##' data together with this data is returned. The column names of the spectra ##' matrix are retained (if they are numbers, without preceeding letters). -##' +##' ##' @param wl.prefix prefix to prepend wavelength column names ##' @rdname asdataframe ##' @aliases as.wide.df ##' @export ##' @md -##' @return -##' +##' @return +##' ##' `as.wide.df` returns a data.frame that consists of the extra data and ##' the spectra matrix converted to a data.frame. The spectra matrix is ##' expanded *in place*. ##' @examples -##' +##' ##' as.wide.df (chondro [1:5,, 600 ~ 610]) ##' summary (as.wide.df (chondro [1:5,, 600 ~ 610])) -as.wide.df <- function (x, wl.prefix = "") { - chk.hy (x) - validObject (x) +as.wide.df <- function(x, wl.prefix = "") { + chk.hy(x) + validObject(x) - ispc <- match ("spc", colnames (x@data)) + ispc <- match("spc", colnames(x@data)) ## logical indexing creates n by 0 data.frame that can be cbound, thus ## avoiding trouble with empty or 0 x 0 data.frames: - before <- seq_len (ncol (x@data)) < ispc - after <- seq_len (ncol (x@data)) > ispc + before <- seq_len(ncol(x@data)) < ispc + after <- seq_len(ncol(x@data)) > ispc ## colnames should be preserved - cols <- c (colnames (x@data) [before], - paste0 (wl.prefix, colnames (x@data$spc)), - colnames (x@data) [after]) - - x <- cbind (x@data [, before], - as.data.frame (unclass (x@data [, ispc])), - x@data [, after]) - colnames (x) <- cols + cols <- c( + colnames(x@data) [before], + paste0(wl.prefix, colnames(x@data$spc)), + colnames(x@data) [after] + ) + + x <- cbind( + x@data [, before], + as.data.frame(unclass(x@data [, ispc])), + x@data [, after] + ) + colnames(x) <- cols x } -.test (as.wide.df) <- function() { - context ("as.wide.df") - +.test(as.wide.df) <- function() { + context("as.wide.df") + test_that("chondro", { - expect_equal (as.wide.df (chondro [1:5,, 600 ~ 610]), - cbind (chondro [1:5]$.., chondro [[1:5,, 600 ~ 610]]) + expect_equal( + as.wide.df(chondro [1:5, , 600 ~ 610]), + cbind(chondro [1:5]$.., chondro [[1:5, , 600 ~ 610]]) ) }) - - test_that ("column names", { - expect_equal(colnames(as.wide.df (chondro)), - c (grep ("spc", colnames (chondro), value = TRUE, invert = TRUE), colnames (chondro$spc)) + + test_that("column names", { + expect_equal( + colnames(as.wide.df(chondro)), + c(grep("spc", colnames(chondro), value = TRUE, invert = TRUE), colnames(chondro$spc)) ) - - expect_equal(colnames(as.wide.df (chondro)), - c (grep ("spc", colnames (chondro), value = TRUE, invert = TRUE), wl (chondro)) + + expect_equal( + colnames(as.wide.df(chondro)), + c(grep("spc", colnames(chondro), value = TRUE, invert = TRUE), wl(chondro)) ) - - expect_true(! any (is.na (colnames(as.wide.df (barbiturates [[1]]))))) + + expect_true(!any(is.na(colnames(as.wide.df(barbiturates [[1]]))))) }) - - test_that ("column names with wl.prefix", { - expect_equal(colnames (as.wide.df (chondro, wl.prefix = "wl")), - c (grep ("spc", colnames (chondro), value = TRUE, invert = TRUE), paste0 ("wl", colnames (chondro$spc))) + + test_that("column names with wl.prefix", { + expect_equal( + colnames(as.wide.df(chondro, wl.prefix = "wl")), + c(grep("spc", colnames(chondro), value = TRUE, invert = TRUE), paste0("wl", colnames(chondro$spc))) ) }) - } ##' \code{as.long.df} returns a long-format data.frame. -##' +##' ##' The data.frame returned by \code{as.long.df} is guaranteed to have columns ##' \code{spc} and \code{.wavelength}. If \code{nwl (x) == 0} these columns ##' will be \code{NA}. -##' +##' ##' @rdname asdataframe -##' @aliases as.long.df +##' @aliases as.long.df ##' @param rownames should the rownames be in column \code{.rownames} of the ##' long-format data.frame? ##' @param wl.factor should the wavelengths be returned as a factor (instead of @@ -142,55 +152,69 @@ as.wide.df <- function (x, wl.prefix = "") { ##' @return \code{as.long.df} returns the stacked or molten version of \code{x@@data}. The ##' wavelengths are in column \code{.wavelength}. ##' @seealso -##' +##' ##' \code{\link[utils]{stack}} and \code{\link[reshape]{melt}} or \code{\link[reshape2]{melt}} for ##' other functions producing long-format data.frames. ##' @examples -##' +##' ##' as.long.df (flu [,, 405 ~ 410]) ##' summary (as.long.df (flu [,, 405 ~ 410])) ##' summary (as.long.df (flu [,, 405 ~ 410], rownames = TRUE)) ##' summary (as.long.df (flu [,, 405 ~ 410], wl.factor = TRUE)) -##' -as.long.df <- function (x, rownames = FALSE, wl.factor = FALSE, na.rm = TRUE) { - chk.hy (x) - validObject (x) - - ispc <- match ("spc", colnames (x@data)) - - if (nwl (x) == 0) { - tmp <- cbind (data.frame (.wavelength = rep (NA, nrow (x)), - spc = rep (NA, nrow (x))), - x@data [, -ispc, drop = FALSE]) +##' +as.long.df <- function(x, rownames = FALSE, wl.factor = FALSE, na.rm = TRUE) { + chk.hy(x) + validObject(x) + + ispc <- match("spc", colnames(x@data)) + + if (nwl(x) == 0) { + tmp <- cbind( + data.frame( + .wavelength = rep(NA, nrow(x)), + spc = rep(NA, nrow(x)) + ), + x@data [, -ispc, drop = FALSE] + ) } else { - tmp <- x@data [rep (row.seq (x), nwl (x)), -ispc, drop = FALSE] - - tmp <- cbind (data.frame (.wavelength = rep (x@wavelength, each = nrow (x)), - spc = as.numeric (x [[]])), - tmp) - if (wl.factor){ - tmp$.wavelength <- as.factor (tmp$.wavelength) - wl <- colnames (x@data$spc) # there may be a fancily formatted version in the column - # names - if (is.null (wl)) - wl <- x@wavelength # if not, use the wavelength vector - - levels (tmp$.wavelength) <- wl + tmp <- x@data [rep(row.seq(x), nwl(x)), -ispc, drop = FALSE] + + tmp <- cbind( + data.frame( + .wavelength = rep(x@wavelength, each = nrow(x)), + spc = as.numeric(x [[]]) + ), + tmp + ) + if (wl.factor) { + tmp$.wavelength <- as.factor(tmp$.wavelength) + wl <- colnames(x@data$spc) # there may be a fancily formatted version in the column + # names + if (is.null(wl)) { + wl <- x@wavelength + } # if not, use the wavelength vector + + levels(tmp$.wavelength) <- wl } } - if (rownames) - tmp <- data.frame (.rownames = as.factor (rep (rownames (x), - length.out = nrow (tmp))), - tmp) + if (rownames) { + tmp <- data.frame( + .rownames = as.factor(rep(rownames(x), + length.out = nrow(tmp) + )), + tmp + ) + } + + if (na.rm) { + tmp <- tmp [!is.na(tmp$spc), ] + } - if (na.rm) - tmp <- tmp [!is.na (tmp$spc), ] - tmp } -##' +##' ##' \code{as.t.df} produces a 'transposed' data.frame with columns containing the spectra. ##' @rdname asdataframe ##' @aliases as.t.df @@ -201,19 +225,19 @@ as.long.df <- function (x, rownames = FALSE, wl.factor = FALSE, na.rm = TRUE) { ##' @examples ##' df <- as.t.df (apply (chondro, 2, mean_pm_sd)) ##' head (df) -##' +##' ##' if (require (ggplot2)){ ##' ggplot (df, aes (x = .wavelength)) + ##' geom_ribbon (aes (ymin = mean.minus.sd, ymax = mean.plus.sd), ##' fill = "#00000040") + ##' geom_line (aes (y = mean)) ##' } -as.t.df <- function (x) { - chk.hy (x) - validObject (x) - - df <- as.data.frame (t (unclass (x@data$spc))) - colnames (df) <- rownames (x@data) - - cbind (.wavelength = x@wavelength, df) +as.t.df <- function(x) { + chk.hy(x) + validObject(x) + + df <- as.data.frame(t(unclass(x@data$spc))) + colnames(df) <- rownames(x@data) + + cbind(.wavelength = x@wavelength, df) } diff --git a/hyperSpec/R/barbiturates.R b/hyperSpec/R/barbiturates.R index 6b90216ac..64352145a 100644 --- a/hyperSpec/R/barbiturates.R +++ b/hyperSpec/R/barbiturates.R @@ -1,7 +1,7 @@ ##' Barbiturates Spectra from .spc example files ##' A time series of mass spectra in a list of hyperSpec objects. -##' -##' +##' +##' ##' @name barbiturates ##' @docType data ##' @format The data sets consists of 286 spectra. They are the result of importing the @@ -10,23 +10,23 @@ ##' @references The raw data is available at \url{http://hyperspec.r-forge.r-project.org/blob/fileio.zip} ##' @keywords datasets ##' @examples -##' +##' ##' barbiturates [1:3] ##' length (barbiturates) -##' +##' ##' barb <- collapse (barbiturates, collapse.equal = FALSE) ##' barb <- orderwl (barb) -##' +##' ##' plot (barb [1:3], lines.args = list (type = "h"), ##' col = matlab.dark.palette (3), stacked = TRUE, ##' stacked.args = list (add.factor = .2)) -##' +##' ##' if (require (latticeExtra)){ ##' levelplot (spc ~ .wavelength * z, log (barb), panel = panel.levelplot.points, ##' cex = 0.3, col = "#00000000", col.regions = matlab.palette (20)) ##' } -##' +##' ##' plotc (apply (barb [,, 42.9~43.2], 1, sum, na.rm = TRUE), spc ~ z, ##' panel = panel.lines, ylab = expression (I[m/z == 43] / "a.u.")) -##' +##' NULL diff --git a/hyperSpec/R/bind.R b/hyperSpec/R/bind.R index 14242e895..0df4f7262 100644 --- a/hyperSpec/R/bind.R +++ b/hyperSpec/R/bind.R @@ -60,31 +60,33 @@ ##' lhy <- list (flu, flu) ##' do.call ("rbind", lhy) ##' bind ("r", lhy) -bind <- function (direction = stop ("direction ('c' or 'r') required"), ..., - wl.tolerance = hy.getOption ("wl.tolerance")){ +bind <- function(direction = stop("direction ('c' or 'r') required"), ..., + wl.tolerance = hy.getOption("wl.tolerance")) { + wl.tolerance <- .checkpos(wl.tolerance, "wl.tolerance") + dots <- list(...) - wl.tolerance <- .checkpos (wl.tolerance, "wl.tolerance") - dots <- list (...) - - if ((length (dots) == 1) & is.list (dots [[1]])) + if ((length(dots) == 1) & is.list(dots [[1]])) { dots <- dots[[1]] + } - if (length (dots) == 0) + if (length(dots) == 0) { NULL - else if (length (dots) == 1){ - validObject (dots[[1]]) + } else if (length(dots) == 1) { + validObject(dots[[1]]) dots[[1]] - } else { # binding is actually needed. - lapply (dots, chk.hy) - lapply (dots, validObject) - - for (i in seq_along (dots) [-1]){ - dots[[1]] <- switch (direction, - c = cbind2 (dots[[1]], dots[[i]]), - r = rbind2 (dots[[1]], dots[[i]], wl.tolerance = wl.tolerance), - stop ("direction must be either 'c' or 'r' for cbind", - "and rbind, respectively.") - ) + } else { # binding is actually needed. + lapply(dots, chk.hy) + lapply(dots, validObject) + + for (i in seq_along(dots) [-1]) { + dots[[1]] <- switch(direction, + c = cbind2(dots[[1]], dots[[i]]), + r = rbind2(dots[[1]], dots[[i]], wl.tolerance = wl.tolerance), + stop( + "direction must be either 'c' or 'r' for cbind", + "and rbind, respectively." + ) + ) } dots [[1]] @@ -92,26 +94,28 @@ bind <- function (direction = stop ("direction ('c' or 'r') required"), ..., } ##' @include unittest.R -.test (bind) <- function () { - context ("bind") +.test(bind) <- function() { + context("bind") test_that("wl.tolerance for rbind", { tmp <- flu - wl (tmp) <- wl (tmp) + 0.01 - expect_error (bind ("r", tmp, flu)) - expect_equivalent (nwl (bind ("r", tmp, flu, tmp, flu, wl.tolerance = 0.1)), nwl (flu)) + wl(tmp) <- wl(tmp) + 0.01 + expect_error(bind("r", tmp, flu)) + expect_equivalent(nwl(bind("r", tmp, flu, tmp, flu, wl.tolerance = 0.1)), nwl(flu)) - tmp.list <- list (flu, tmp, flu) + tmp.list <- list(flu, tmp, flu) - expect_error (bind ("r", tmp.list)) - expect_true (all.equal (bind ("r", tmp.list, wl.tolerance = 0.1), - flu [rep (row.seq (flu), 3)], - check.label = TRUE)) + expect_error(bind("r", tmp.list)) + expect_true(all.equal(bind("r", tmp.list, wl.tolerance = 0.1), + flu [rep(row.seq(flu), 3)], + check.label = TRUE + )) - expect_true (all.equal (do.call ("bind", list ("r", tmp.list, wl.tolerance = 0.1)), - flu [rep (row.seq (flu), 3)], - check.label = TRUE)) + expect_true(all.equal(do.call("bind", list("r", tmp.list, wl.tolerance = 0.1)), + flu [rep(row.seq(flu), 3)], + check.label = TRUE + )) }) } @@ -128,7 +132,7 @@ bind <- function (direction = stop ("direction ('c' or 'r') required"), ..., ##' @aliases cbind.hyperSpec ##' -cbind.hyperSpec <- function (...) bind ("c", ...) +cbind.hyperSpec <- function(...) bind("c", ...) ##' ##' \code{rbind2} binds two \code{hyperSpec} objects by row. They need to have @@ -138,124 +142,130 @@ cbind.hyperSpec <- function (...) bind ("c", ...) ##' @rdname bind ##' @export ##' @aliases rbind.hyperSpec -rbind.hyperSpec <- function (...) bind ("r", ...) +rbind.hyperSpec <- function(...) bind("r", ...) -.test (rbind.hyperSpec) <- function () { - context ("rbind.hyperSpec") +.test(rbind.hyperSpec) <- function() { + context("rbind.hyperSpec") - test_that("wl.tolerance",{ + test_that("wl.tolerance", { tmp <- flu - wl (tmp) <- wl (tmp) + 0.01 - expect_error (rbind (tmp, flu)) - expect_equivalent (nwl (rbind (tmp, flu, flu, wl.tolerance = 0.1)), nwl (flu)) - - tmp.list <- list (flu, tmp, flu) - expect_true (all.equal (do.call ("rbind", c (tmp.list, wl.tolerance = 0.1)), - flu [rep (row.seq (flu), 3)], - check.label = TRUE)) + wl(tmp) <- wl(tmp) + 0.01 + expect_error(rbind(tmp, flu)) + expect_equivalent(nwl(rbind(tmp, flu, flu, wl.tolerance = 0.1)), nwl(flu)) + + tmp.list <- list(flu, tmp, flu) + expect_true(all.equal(do.call("rbind", c(tmp.list, wl.tolerance = 0.1)), + flu [rep(row.seq(flu), 3)], + check.label = TRUE + )) }) - test_that ("correct rbinding", { - expect_equal(nrow (rbind (flu, flu)), 2 * nrow (flu)) - expect_error(rbind (flu, flu [,, min ~ min + 3i])) + test_that("correct rbinding", { + expect_equal(nrow(rbind(flu, flu)), 2 * nrow(flu)) + expect_error(rbind(flu, flu [, , min ~ min + 3i])) }) - test_that ("list of hyperSpec objects", { - - expect_equal(nrow (rbind (flu, flu)), 2 * nrow (flu)) - expect_error(rbind (flu, flu [,, min ~ min + 3i])) + test_that("list of hyperSpec objects", { + expect_equal(nrow(rbind(flu, flu)), 2 * nrow(flu)) + expect_error(rbind(flu, flu [, , min ~ min + 3i])) }) - } -.cbind2 <- function (x, y){ - validObject (x) - validObject (y) +.cbind2 <- function(x, y) { + validObject(x) + validObject(y) - cols <- match (colnames (x@data), colnames (y@data)) - cols <- colnames (y@data) [cols] - cols <- cols [! is.na (cols)] - cols <- cols [- match ("spc", cols)] + cols <- match(colnames(x@data), colnames(y@data)) + cols <- colnames(y@data) [cols] + cols <- cols [!is.na(cols)] + cols <- cols [-match("spc", cols)] - if (length (cols) < 0){ - ord <- do.call (order, x@data[, cols, drop = FALSE]) - x@data <- x@data[ord, , drop = FALSE] + if (length(cols) < 0) { + ord <- do.call(order, x@data[, cols, drop = FALSE]) + x@data <- x@data[ord, , drop = FALSE] - ord <- do.call (order, y@data[, cols, drop = FALSE]) - y@data <- y@data[ord, , drop = FALSE] + ord <- do.call(order, y@data[, cols, drop = FALSE]) + y@data <- y@data[ord, , drop = FALSE] - if (any (x@data[, cols, drop = FALSE] != y@data[, cols, drop = FALSE])) - stop ("hyperSpec objects must have the same data in columns", - "of the same name (except data$spc)") - } + if (any(x@data[, cols, drop = FALSE] != y@data[, cols, drop = FALSE])) { + stop( + "hyperSpec objects must have the same data in columns", + "of the same name (except data$spc)" + ) + } + } - ## for the spectra, multiple occurences of the same wavelength are O.K. - x@data$spc <- cbind(x@data$spc, y@data$spc) - .wl (x) <- c (x@wavelength, y@wavelength) + ## for the spectra, multiple occurences of the same wavelength are O.K. + x@data$spc <- cbind(x@data$spc, y@data$spc) + .wl(x) <- c(x@wavelength, y@wavelength) - ## cbind columns in y that are not in x - cols <- is.na (match (colnames (y@data), colnames (x@data))) - x@data <- cbind (x@data, - y@data[, cols, drop = FALSE]) + ## cbind columns in y that are not in x + cols <- is.na(match(colnames(y@data), colnames(x@data))) + x@data <- cbind( + x@data, + y@data[, cols, drop = FALSE] + ) - x + x } ##' @rdname bind ##' @export ##' @aliases cbind2,hyperSpec,hyperSpec-method -setMethod ("cbind2", signature = signature (x = "hyperSpec", y = "hyperSpec"), .cbind2) +setMethod("cbind2", signature = signature(x = "hyperSpec", y = "hyperSpec"), .cbind2) ##' @rdname bind ##' @export ##' @aliases cbind2,hyperSpec,missing-method -setMethod("cbind2", signature = signature (x = "hyperSpec", y = "missing"), function (x, y) x) - -.rbind2 <- function (x, y, wl.tolerance = hy.getOption ("wl.tolerance")) { - validObject (x) - validObject (y) - wl.tolerance <- .checkpos (wl.tolerance, "wl.tolerance") - - if (! isTRUE (all.equal (x@wavelength, y@wavelength, tolerance = wl.tolerance))) - stop ("The wavelengths of the objects differ (with respect to tolerance ", wl.tolerance, ").\n", - "If they are not ordered, try 'orderwl'.") +setMethod("cbind2", signature = signature(x = "hyperSpec", y = "missing"), function(x, y) x) + +.rbind2 <- function(x, y, wl.tolerance = hy.getOption("wl.tolerance")) { + validObject(x) + validObject(y) + wl.tolerance <- .checkpos(wl.tolerance, "wl.tolerance") + + if (!isTRUE(all.equal(x@wavelength, y@wavelength, tolerance = wl.tolerance))) { + stop( + "The wavelengths of the objects differ (with respect to tolerance ", wl.tolerance, ").\n", + "If they are not ordered, try 'orderwl'." + ) + } - x@data <- rbind (x@data, y@data) + x@data <- rbind(x@data, y@data) - x + x } -.test (.rbind2) <- function () { - context (".rbind2") +.test(.rbind2) <- function() { + context(".rbind2") test_that("flu", { - expect_equal (rbind (flu [ 1], flu [-1]), flu, check.attributes = FALSE) - expect_equal (rbind (flu [-1], flu [ 1]), flu [c (2:6, 1)], check.attributes = FALSE) - expect_equal (rbind (flu [1:2], flu [3:6]), flu, check.attributes = FALSE) + expect_equal(rbind(flu [1], flu [-1]), flu, check.attributes = FALSE) + expect_equal(rbind(flu [-1], flu [1]), flu [c(2:6, 1)], check.attributes = FALSE) + expect_equal(rbind(flu [1:2], flu [3:6]), flu, check.attributes = FALSE) }) test_that("empty objects", { - expect_equal (rbind (flu [0], flu [0]), flu [0], check.attributes = FALSE) - expect_equal (rbind (flu [1], flu [0]), flu [1], check.attributes = FALSE) - expect_equal (rbind (flu [0], flu [1]), flu [1], check.attributes = FALSE) + expect_equal(rbind(flu [0], flu [0]), flu [0], check.attributes = FALSE) + expect_equal(rbind(flu [1], flu [0]), flu [1], check.attributes = FALSE) + expect_equal(rbind(flu [0], flu [1]), flu [1], check.attributes = FALSE) }) - test_that("wl.tolerance", { - tmp <- flu - wl (tmp) <- wl (tmp) + 0.01 - expect_error (rbind2 (tmp, flu)) - expect_equivalent (nwl (rbind2 (tmp, flu, wl.tolerance = 0.1)), nwl (flu)) - }) + test_that("wl.tolerance", { + tmp <- flu + wl(tmp) <- wl(tmp) + 0.01 + expect_error(rbind2(tmp, flu)) + expect_equivalent(nwl(rbind2(tmp, flu, wl.tolerance = 0.1)), nwl(flu)) + }) } ##' @rdname bind ##' @export ##' @aliases rbind2,hyperSpec,hyperSpec-method -setMethod("rbind2", signature = signature (x = "hyperSpec", y = "hyperSpec"), .rbind2) +setMethod("rbind2", signature = signature(x = "hyperSpec", y = "hyperSpec"), .rbind2) ##' @rdname bind ##' @export ##' @aliases rbind2,hyperSpec,missing-method -setMethod ("rbind2", signature = signature (x = "hyperSpec", y = "missing"), function (x, y, wl.tolerance) x) - +setMethod("rbind2", signature = signature(x = "hyperSpec", y = "missing"), function(x, y, wl.tolerance) x) diff --git a/hyperSpec/R/call.list.R b/hyperSpec/R/call.list.R index 06aa7066a..4ea9415a9 100644 --- a/hyperSpec/R/call.list.R +++ b/hyperSpec/R/call.list.R @@ -1,16 +1,17 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### generate a list of function arguments for the calling function ### -##'@noRd -.call.list <- function (x = NULL) { - if (is.null (x)) - x <- sys.call (-1) +##' @noRd +.call.list <- function(x = NULL) { + if (is.null(x)) { + x <- sys.call(-1) + } - if (length (x) < 3L) - I (list ()) - else { - x <- as.list (x [- (1 : 2)]) - I (x) + if (length(x) < 3L) { + I(list()) + } else { + x <- as.list(x [-(1:2)]) + I(x) } } diff --git a/hyperSpec/R/chk.hy.R b/hyperSpec/R/chk.hy.R index c9de075cb..1dade3fad 100644 --- a/hyperSpec/R/chk.hy.R +++ b/hyperSpec/R/chk.hy.R @@ -9,12 +9,13 @@ ##' error. ##' @keywords methods ##' @export -##' @examples +##' @examples ##' chk.hy (chondro) ##' validObject (chondro) -chk.hy <- function (object){ - if (! is (object, "hyperSpec")) - stop ("no hyperSpec object") +chk.hy <- function(object) { + if (!is(object, "hyperSpec")) { + stop("no hyperSpec object") + } TRUE } diff --git a/hyperSpec/R/chondro.R b/hyperSpec/R/chondro.R index a9d595a37..adb88ddc6 100644 --- a/hyperSpec/R/chondro.R +++ b/hyperSpec/R/chondro.R @@ -1,17 +1,18 @@ -.make.chondro <- function (){ - new ("hyperSpec", - spc = (tcrossprod (.chondro.scores, .chondro.loadings) + - rep (.chondro.center, each = nrow (.chondro.scores))), - wavelength = .chondro.wl, - data = .chondro.extra, labels = .chondro.labels) +.make.chondro <- function() { + new("hyperSpec", + spc = (tcrossprod(.chondro.scores, .chondro.loadings) + + rep(.chondro.center, each = nrow(.chondro.scores))), + wavelength = .chondro.wl, + data = .chondro.extra, labels = .chondro.labels + ) } ##' Raman spectra of 2 Chondrocytes in Cartilage ##' A Raman-map (laterally resolved Raman spectra) of chondrocytes in ##' cartilage. -##' +##' ##' See the vignette \code{vignette ("chondro", package = "hyperSpec")}. -##' +##' ##' @name chondro ##' @docType data ##' @format The data set has 875 Raman spectra measured on a 25 \eqn{\times}{x} @@ -23,29 +24,28 @@ ##' @references The raw data is available at \url{http://hyperspec.r-forge.r-project.org/blob/chondro.zip} ##' @export chondro ##' @examples -##' -##' +##' +##' ##' chondro -##' +##' ##' ## do baseline correction ##' baselines <- spc.fit.poly.below (chondro) ##' chondro <- chondro - baselines -##' +##' ##' ## area normalization ##' chondro <- chondro / colMeans (chondro) -##' +##' ##' ## substact common composition ##' chondro <- chondro - quantile (chondro, 0.05) -##' +##' ##' cols <- c ("dark blue", "orange", "#C02020") ##' plotmap (chondro, clusters ~ x * y, col.regions = cols) -##' +##' ##' cluster.means <- aggregate (chondro, chondro$clusters, mean_pm_sd) ##' plot (cluster.means, stacked = ".aggregate", fill = ".aggregate", col = cols) -##' +##' ##' ## plot nucleic acid bands ##' plotmap (chondro[, , c( 728, 782, 1098, 1240, 1482, 1577)], ##' col.regions = colorRampPalette (c ("white", "gold", "dark green"), space = "Lab") (20)) -##' -delayedAssign ("chondro", .make.chondro ()) - +##' +delayedAssign("chondro", .make.chondro()) diff --git a/hyperSpec/R/colMeans.R b/hyperSpec/R/colMeans.R index 2ca61d955..2a193417f 100644 --- a/hyperSpec/R/colMeans.R +++ b/hyperSpec/R/colMeans.R @@ -15,81 +15,82 @@ NULL ##' @noRd -setGeneric ('colMeans')#, package = 'matrixStats') +setGeneric("colMeans") # , package = 'matrixStats') ##' @rdname colSums ##' @export ##' @examples ##' colMeans (flu) - setMethod ("colMeans", signature = signature (x = "hyperSpec"), function (x, na.rm = TRUE, ..., label.spc){ - result <- colMeans (x@data$spc, na.rm = na.rm, ...) - if (is.matrix (result) && ncol (result) != nwl (x) && nrow (result) == nwl (x)) - result <- t (result) +setMethod("colMeans", signature = signature(x = "hyperSpec"), function(x, na.rm = TRUE, ..., label.spc) { + result <- colMeans(x@data$spc, na.rm = na.rm, ...) + if (is.matrix(result) && ncol(result) != nwl(x) && nrow(result) == nwl(x)) { + result <- t(result) + } - decomposition (x, result, scores = FALSE, label.spc = label.spc) + decomposition(x, result, scores = FALSE, label.spc = label.spc) }) ##' @noRd -setGeneric ('colSums') #, package = 'matrixStats') +setGeneric("colSums") # , package = 'matrixStats') ##' @rdname colSums ##' @export ##' @examples ##' colSums (flu) -setMethod ("colSums", signature = signature (x = "hyperSpec"), function (x, na.rm = TRUE, ..., label.spc){ - result <- colSums (x@data$spc, na.rm = na.rm, ...) - if (is.matrix (result) && ncol (result) != nwl (x) && nrow (result) == nwl (x)) - result <- t (result) +setMethod("colSums", signature = signature(x = "hyperSpec"), function(x, na.rm = TRUE, ..., label.spc) { + result <- colSums(x@data$spc, na.rm = na.rm, ...) + if (is.matrix(result) && ncol(result) != nwl(x) && nrow(result) == nwl(x)) { + result <- t(result) + } - decomposition (x, result, scores = FALSE, label.spc = label.spc) + decomposition(x, result, scores = FALSE, label.spc = label.spc) }) ##' @noRd -setGeneric ('rowMeans') #, package = 'matrixStats') +setGeneric("rowMeans") # , package = 'matrixStats') ##' @rdname colSums ##' @export ##' @examples ##' colSums (flu) -setMethod ("rowMeans", signature = signature (x = "hyperSpec"), function (x, na.rm = TRUE, ..., label.wavelength){ - result <- rowMeans (x@data$spc, na.rm = na.rm, ...) - if (is.matrix (result) && nrow (result) != nrow (x) && ncol (result) == nrow (x)) - result <- t (result) +setMethod("rowMeans", signature = signature(x = "hyperSpec"), function(x, na.rm = TRUE, ..., label.wavelength) { + result <- rowMeans(x@data$spc, na.rm = na.rm, ...) + if (is.matrix(result) && nrow(result) != nrow(x) && ncol(result) == nrow(x)) { + result <- t(result) + } - decomposition (x, result, scores = TRUE, label.wavelength = label.wavelength) + decomposition(x, result, scores = TRUE, label.wavelength = label.wavelength) }) ##' @noRd -setGeneric ('rowSums') #, package = 'matrixStats') +setGeneric("rowSums") # , package = 'matrixStats') ##' @rdname colSums ##' @export ##' @examples ##' rowSums (flu) -setMethod ("rowSums", signature = signature (x = "hyperSpec"), function (x, na.rm = TRUE, ..., label.wavelength){ - result <- rowSums (x@data$spc, na.rm = na.rm, ...) - if (is.matrix (result) && nrow (result) != nrow (x) && ncol (result) == nrow (x)) - result <- t (result) +setMethod("rowSums", signature = signature(x = "hyperSpec"), function(x, na.rm = TRUE, ..., label.wavelength) { + result <- rowSums(x@data$spc, na.rm = na.rm, ...) + if (is.matrix(result) && nrow(result) != nrow(x) && ncol(result) == nrow(x)) { + result <- t(result) + } - decomposition (x, result, scores = TRUE, label.wavelength = label.wavelength) + decomposition(x, result, scores = TRUE, label.wavelength = label.wavelength) }) ##' @include unittest.R -.test (colMeans) <- function (){ - - for (fun in c ("colMeans", "colSums", "rowMeans", "rowSums")){ - context (fun) - f <- get (fun, mode = "function") +.test(colMeans) <- function() { + for (fun in c("colMeans", "colSums", "rowMeans", "rowSums")) { + context(fun) + f <- get(fun, mode = "function") test_that("basic operation", { - expect_equal (as.numeric (f (flu) [[]]), as.numeric (f (flu [[]], na.rm = TRUE )), label = fun) + expect_equal(as.numeric(f(flu) [[]]), as.numeric(f(flu [[]], na.rm = TRUE)), label = fun) }) test_that("behaviour with NAs", { - expect_equal (as.numeric (f (fluNA) [[]]), as.numeric (f (fluNA [[]], na.rm = TRUE )), label = fun) - expect_equal (as.numeric (f (fluNA, na.rm = FALSE)[[]]), as.numeric (f (fluNA [[]], na.rm = FALSE)), label = fun) + expect_equal(as.numeric(f(fluNA) [[]]), as.numeric(f(fluNA [[]], na.rm = TRUE)), label = fun) + expect_equal(as.numeric(f(fluNA, na.rm = FALSE)[[]]), as.numeric(f(fluNA [[]], na.rm = FALSE)), label = fun) }) - } } - diff --git a/hyperSpec/R/collapse.R b/hyperSpec/R/collapse.R index d2055eceb..c1f90387f 100644 --- a/hyperSpec/R/collapse.R +++ b/hyperSpec/R/collapse.R @@ -3,23 +3,23 @@ ##' The spectra from all objects will be put into one object. ##' The resulting object has all wavelengths that occur in any of the input objects, ##' `wl.tolerance` is used to determine which difference in the wavelengths is -##' tolerated as equal: clusters of approximately equal wavelengths will span at most `2 * wl.tolerance`. +##' tolerated as equal: clusters of approximately equal wavelengths will span at most `2 * wl.tolerance`. ##' Differences up to +/- `wl.tolerance` are considered equal. -##' -##' The returned object has wavelengths that are the weighted average -##' (by number of spectra) of the wavelengths within any such cluster of approximately +##' +##' The returned object has wavelengths that are the weighted average +##' (by number of spectra) of the wavelengths within any such cluster of approximately ##' equal wavelengths. -##' -##' Labels will be taken from the first object where they are encountered. However, +##' +##' Labels will be taken from the first object where they are encountered. However, ##' the order of processing objects is not necessarily the same as the order of objects -##' in the input: `collapse` first processes groups of input objects that share all -##' wavelengths (within `wl.tolerance`). +##' in the input: `collapse` first processes groups of input objects that share all +##' wavelengths (within `wl.tolerance`). ##' ##' Data points corresponding to wavelengths not in the original spectrum will be set to NA. ##' Extra data is combined in the same manner. ##' ##' If the objects are named, the names will be preserved in extra data column `$.name`. -##' If the wavelengths are names, names are preserved and taken from the first object where they were encountered, +##' If the wavelengths are names, names are preserved and taken from the first object where they were encountered, ##' the same applies to possible column names of the spectra matrix. ##' ##' @author C. Beleites @@ -29,8 +29,8 @@ ##' @param ... hyperSpec objects to be collapsed into one object. Instead of giving several ##' arguments, a list with all objects to be collapsed may be given. ##' @param wl.tolerance tolerance to decide which wavelengths are considered equal. -##' @param collapse.equal logical indicating whether to try first finding groups of spectra -##' with (approximately) equal wavelength axes. If the data is known to contain few or no +##' @param collapse.equal logical indicating whether to try first finding groups of spectra +##' with (approximately) equal wavelength axes. If the data is known to contain few or no ##' such groups, `collapse()` will be faster with this first pass being turned off. ##' @aliases collapse collapse.hyperSpec ##' @seealso [merge()], [rbind()], and [plyr::rbind.fill()] @@ -50,327 +50,347 @@ ##' b ##' c ##' collapse (a, b, c) -##' +##' ##' collapse (barbiturates [1:3], collapse.equal = FALSE) ##' -collapse <- function (..., wl.tolerance = hy.getOption ("wl.tolerance"), collapse.equal = TRUE){ - wl.tolerance <- .checkpos (wl.tolerance, "wl.tolerance") - dots <- list (...) +collapse <- function(..., wl.tolerance = hy.getOption("wl.tolerance"), collapse.equal = TRUE) { + wl.tolerance <- .checkpos(wl.tolerance, "wl.tolerance") + dots <- list(...) ## accept also a list of hyperSpec objects - if (length (dots) == 1 && is.list (dots [[1]])) + if (length(dots) == 1 && is.list(dots [[1]])) { dots <- dots [[1]] + } ## check the arguments - lapply (dots, chk.hy) - lapply (dots, validObject) + lapply(dots, chk.hy) + lapply(dots, validObject) + + dots <- lapply(dots, orderwl) - dots <- lapply (dots, orderwl) - ## check: wl.tolerance should be smaller than *half* of the smallest wavelength difference within each object ## half because we later check for distance <= wl.tolerance, so ± => window size is 2 wl.tolerance - .assert.suitable.tolerance (dots, wl.tolerance) + .assert.suitable.tolerance(dots, wl.tolerance) ## make sure there aren't any NAs in wavelength - dots <- .assert.noNA.wl (dots) - + dots <- .assert.noNA.wl(dots) + ## names cause problems with unlisting labels. ## preserve them in column .name - if (! is.null (names (dots))){ - dots <- mapply (function (object, name) {object$.name <- name; object}, dots, names (dots)) - names (dots) <- NULL + if (!is.null(names(dots))) { + dots <- mapply(function(object, name) { + object$.name <- name + object + }, dots, names(dots)) + names(dots) <- NULL } ## shall we do a first round collapsing objects that have their whole wavelength axes approximately equal? - if (collapse.equal){ + if (collapse.equal) { dots <- .collapse.equal(dots, wl.tolerance) - - if (length (dots) == 1L) - return (dots [[1]]) + + if (length(dots) == 1L) { + return(dots [[1]]) + } } - - ## Now cluster approximately equal wavelengths together - + + ## Now cluster approximately equal wavelengths together + ## prepare new labels - labels <- unlist (lapply (dots, slot, "label")) - labels <- labels [unique (names (labels))] - labels <- lapply (labels, function (l) if (is.language(l)) l <- as.expression (l) else l) - + labels <- unlist(lapply(dots, slot, "label")) + labels <- labels [unique(names(labels))] + labels <- lapply(labels, function(l) if (is.language(l)) l <- as.expression(l) else l) + ## cluster wavelengths into groups of ± wl.tolerance from center - wl.df <- .cluster.wavelengths (dots, wl.tolerance) - + wl.df <- .cluster.wavelengths(dots, wl.tolerance) + ## assign cluster number to columns # wl.df is ordered by wavelength, each object in dots is ordered by wavelength, so - for (i in seq_along (dots)) - colnames (dots [[i]]@data$spc) <- wl.df$wlcluster [wl.df$iobj == i] + for (i in seq_along(dots)) { + colnames(dots [[i]]@data$spc) <- wl.df$wlcluster [wl.df$iobj == i] + } ## now we're ready for the actual work of collapsing the objects - dots <- rbind.fill (lapply (dots, slot, "data")) + dots <- rbind.fill(lapply(dots, slot, "data")) ## careful with constructing the wavelength vector: the columns in $spc are in no particular order, ## but the colnames indicate wavelength rank. ## so reorder $spc accor - dots$spc <- dots$spc [, order (as.numeric (colnames (dots$spc)))] - + dots$spc <- dots$spc [, order(as.numeric(colnames(dots$spc)))] + ## we now need summarized wl.df data: - wl.df <- group_by (wl.df, .data$wlcluster) - wl.df <- summarise (wl.df, - wl = sum (.data$wl*.data$nspc) / sum (.data$nspc), # weighted average - old.wlnames = .data$old.wlnames [1L]) - + wl.df <- group_by(wl.df, .data$wlcluster) + wl.df <- summarise(wl.df, + wl = sum(.data$wl * .data$nspc) / sum(.data$nspc), # weighted average + old.wlnames = .data$old.wlnames [1L] + ) + ## prepare wavelength vector & restore old names (as far as possible) wl <- wl.df$wl - if (any (!is.na (wl.df$old.wlnames))) + if (any(!is.na(wl.df$old.wlnames))) { names(wl) <- wl.df$old.wlnames + } ## make a new hyperSpec object - new ("hyperSpec", wavelength = wl, data = dots, labels = labels) + new("hyperSpec", wavelength = wl, data = dots, labels = labels) } ##' @include unittest.R -.test (collapse) <- function () { - context ("collapse") - - test_that ("correctly assembled", { - new <- do.call (collapse, barbiturates [1 : 3]) - wl <- unlist (lapply (barbiturates [1 : 3], slot, "wavelength")) - expect_equal (wl (new), - sort (wl [! duplicated (wl)])) - - for (s in 1 : 3){ - expect_equal (as.numeric (new [[s,, wl (barbiturates [[s]])]]), - as.numeric (barbiturates [[s]][[]]), - label = paste0 ("barbiturates [[", s, "]]")) +.test(collapse) <- function() { + context("collapse") + + test_that("correctly assembled", { + new <- do.call(collapse, barbiturates [1:3]) + wl <- unlist(lapply(barbiturates [1:3], slot, "wavelength")) + expect_equal( + wl(new), + sort(wl [!duplicated(wl)]) + ) + + for (s in 1:3) { + expect_equal(as.numeric(new [[s, , wl(barbiturates [[s]])]]), + as.numeric(barbiturates [[s]][[]]), + label = paste0("barbiturates [[", s, "]]") + ) } }) - tmp <- collapse (a = flu, b = flu) - - test_that ("wavelength label is not lost", { - tmp <- collapse (flu, flu) - expect_equal(labels (tmp, ".wavelength"), labels (flu, ".wavelength")) + tmp <- collapse(a = flu, b = flu) - tmp <- collapse (flu [,, min ~ 410], flu [,,414~ 420]) - expect_equal(labels (tmp, ".wavelength"), labels (flu, ".wavelength")) + test_that("wavelength label is not lost", { + tmp <- collapse(flu, flu) + expect_equal(labels(tmp, ".wavelength"), labels(flu, ".wavelength")) + + tmp <- collapse(flu [, , min ~ 410], flu [, , 414 ~ 420]) + expect_equal(labels(tmp, ".wavelength"), labels(flu, ".wavelength")) }) - - test_that ("labels that are expressions stay expressions", { - tmp <- collapse (flu, flu) - expect_true (is.expression (labels (tmp)$.wavelength)) - expect_true (is.expression (labels (tmp)$spc)) - - tmp <- collapse (flu [,, min ~ 405], flu [,,414~ 420]) - expect_true (is.expression (labels (tmp)$.wavelength)) - expect_true (is.expression (labels (tmp)$spc)) + + test_that("labels that are expressions stay expressions", { + tmp <- collapse(flu, flu) + expect_true(is.expression(labels(tmp)$.wavelength)) + expect_true(is.expression(labels(tmp)$spc)) + + tmp <- collapse(flu [, , min ~ 405], flu [, , 414 ~ 420]) + expect_true(is.expression(labels(tmp)$.wavelength)) + expect_true(is.expression(labels(tmp)$spc)) }) - test_that ("collapse does not mess up labels if a named list is collapsed", { - expect_equal (labels (tmp) [names (labels (flu))], - labels (flu)) + test_that("collapse does not mess up labels if a named list is collapsed", { + expect_equal( + labels(tmp) [names(labels(flu))], + labels(flu) + ) }) - test_that ("named lists should return .name column", { - expect_equal (tmp$.name, rep (c ("a", "b"), each = nrow (flu))) + test_that("named lists should return .name column", { + expect_equal(tmp$.name, rep(c("a", "b"), each = nrow(flu))) }) - test_that ("no difference whether list or single arguments are given", { - tmp2 <- list (a = flu, b = flu) - tmp2 <- collapse (a = flu, b = flu) - expect_equal (tmp, tmp2, - check.attributes = TRUE, check.names = TRUE, check.column.order = FALSE, check.label = TRUE) + test_that("no difference whether list or single arguments are given", { + tmp2 <- list(a = flu, b = flu) + tmp2 <- collapse(a = flu, b = flu) + expect_equal(tmp, tmp2, + check.attributes = TRUE, check.names = TRUE, check.column.order = FALSE, check.label = TRUE + ) }) - test_that ("wl.tolerance", { + test_that("wl.tolerance", { tmp <- flu - wl (tmp) <- wl (tmp) + 0.01 - expect_equal (nwl (collapse (tmp, flu )), 2 * nwl (flu)) - expect_equal (nwl (collapse (tmp, flu, wl.tolerance = 0.1)), nwl (flu)) + wl(tmp) <- wl(tmp) + 0.01 + expect_equal(nwl(collapse(tmp, flu)), 2 * nwl(flu)) + expect_equal(nwl(collapse(tmp, flu, wl.tolerance = 0.1)), nwl(flu)) }) - test_that ("check warning occurs for too large tolerance", { - expect_warning (collapse (flu, wl.tolerance = 0.25 + .Machine$double.eps)) + test_that("check warning occurs for too large tolerance", { + expect_warning(collapse(flu, wl.tolerance = 0.25 + .Machine$double.eps)) }) - test_that ("bugfix: wl.tolerance generated warning for negative diff (wl (spc))", { + test_that("bugfix: wl.tolerance generated warning for negative diff (wl (spc))", { tmp <- flu - wl (tmp) <- rev (wl (tmp)) - expect_silent (collapse (tmp, tmp)) + wl(tmp) <- rev(wl(tmp)) + expect_silent(collapse(tmp, tmp)) }) - test_that ("result has orded wavelengths",{ - tmp <- collapse (barbiturates [1:3]) + test_that("result has orded wavelengths", { + tmp <- collapse(barbiturates [1:3]) - expect_true (all (diff (wl (tmp)) >= 0)) + expect_true(all(diff(wl(tmp)) >= 0)) }) - test_that ("collapsing objects with equal wavelength axes",{ - expect_equivalent (collapse (barbiturates [[1]], barbiturates [[1]]), - barbiturates [[1]][c (1,1)], - check.label = TRUE + test_that("collapsing objects with equal wavelength axes", { + expect_equivalent(collapse(barbiturates [[1]], barbiturates [[1]]), + barbiturates [[1]][c(1, 1)], + check.label = TRUE ) }) - test_that ("new wavelengths are weighted mean of wavelength bin: shortcut for equal wavelength axes", { + test_that("new wavelengths are weighted mean of wavelength bin: shortcut for equal wavelength axes", { tmp <- flu - wl (tmp) <- wl (flu) + 0.03 - tmp <- collapse (flu, flu, tmp, wl.tolerance = 0.05) - expect_equal(wl (tmp), wl (flu) + 0.01) + wl(tmp) <- wl(flu) + 0.03 + tmp <- collapse(flu, flu, tmp, wl.tolerance = 0.05) + expect_equal(wl(tmp), wl(flu) + 0.01) tmp <- flu - wl (tmp) <- wl (flu) + 0.03 - tmp <- collapse (flu[rep (1, 12)], tmp, wl.tolerance = 0.05) - expect_equal(wl (tmp), wl (flu) + 0.01) + wl(tmp) <- wl(flu) + 0.03 + tmp <- collapse(flu[rep(1, 12)], tmp, wl.tolerance = 0.05) + expect_equal(wl(tmp), wl(flu) + 0.01) }) - test_that ("names of wavelength kept", { + test_that("names of wavelength kept", { a <- barbiturates[[1]] b <- barbiturates[[2]] - names (wl (a)) <- paste ("Mass A", seq_len (nwl (a))) - names (wl (b)) <- paste ("Mass B", seq_len (nwl (b))) + names(wl(a)) <- paste("Mass A", seq_len(nwl(a))) + names(wl(b)) <- paste("Mass B", seq_len(nwl(b))) - tmp <- collapse (a, b) + tmp <- collapse(a, b) - expect_true (all (names (wl (a)) %in% names (wl (tmp)))) - expect_true ( - all ( - grep ("B", names (wl (tmp)), value = TRUE) %in% names (wl (b)) - ) + expect_true(all(names(wl(a)) %in% names(wl(tmp)))) + expect_true( + all( + grep("B", names(wl(tmp)), value = TRUE) %in% names(wl(b)) ) - expect_true (all (grepl ("Mass [AB]", names (wl (tmp))))) + ) + expect_true(all(grepl("Mass [AB]", names(wl(tmp))))) }) - test_that ("factor behaviour of collapse", { + test_that("factor behaviour of collapse", { a <- chondro [chondro$clusters == "lacuna"] a$clusters <- droplevels(a$clusters) b <- chondro [chondro$clusters != "lacuna"] b$clusters <- droplevels(b$clusters) - - tmp <- collapse (a, b) - tmp$clusters - - expect_equal(sort (levels (tmp$clusters)), - sort (levels (chondro$clusters)) + + tmp <- collapse(a, b) + tmp$clusters + + expect_equal( + sort(levels(tmp$clusters)), + sort(levels(chondro$clusters)) ) }) - - test_that ("hyperSpec objects with 1 wavelength", { - expect_equivalent (collapse (flu [,,450], flu [,,450]), - flu [rep (1: nrow (flu), 2),,450], - check.labels = TRUE) - tmp <- flu [rep (1: nrow (flu), 2)] + test_that("hyperSpec objects with 1 wavelength", { + expect_equivalent(collapse(flu [, , 450], flu [, , 450]), + flu [rep(1:nrow(flu), 2), , 450], + check.labels = TRUE + ) + + tmp <- flu [rep(1:nrow(flu), 2)] tmp [[7:12]] <- NA - tmp [[7:12,,450]] <- flu [[,,450]] - expect_equivalent (collapse (flu [,,450], flu), - tmp, - check.labels = TRUE) + tmp [[7:12, , 450]] <- flu [[, , 450]] + expect_equivalent(collapse(flu [, , 450], flu), + tmp, + check.labels = TRUE + ) }) - test_that ("hyperSpec objects with 0 wavelengths", { - expect_equivalent (collapse (flu [,,FALSE], flu [,,FALSE]), - flu [rep (1: nrow (flu), 2),,FALSE], - check.labels = TRUE) - - tmp <- collapse (flu [,,FALSE], flu [,"spc", 405 ~ 406]) - expect_equal (tmp$c, c(flu$c, rep (NA, nrow (flu)))) - expect_equal (tmp$spc, rbind(flu[[,, 405 ~ 406]] + NA, flu[[,, 405 ~ 406]])) - expect_equal (labels (tmp), lapply (labels (flu), as.expression)) - }) - - test_that ("hyperSpec objects with wavelength being/containing NA", { - - expect_warning(collapse (flu [,, 0])) - - - expect_equal (suppressWarnings (collapse (flu [,, 0], flu)), - collapse (flu [,, FALSE], flu)) - - expect_equal (suppressWarnings (collapse (flu [,, c(0, 405)], flu)), - collapse (flu [,, 405], flu) + test_that("hyperSpec objects with 0 wavelengths", { + expect_equivalent(collapse(flu [, , FALSE], flu [, , FALSE]), + flu [rep(1:nrow(flu), 2), , FALSE], + check.labels = TRUE ) - + + tmp <- collapse(flu [, , FALSE], flu [, "spc", 405 ~ 406]) + expect_equal(tmp$c, c(flu$c, rep(NA, nrow(flu)))) + expect_equal(tmp$spc, rbind(flu[[, , 405 ~ 406]] + NA, flu[[, , 405 ~ 406]])) + expect_equal(labels(tmp), lapply(labels(flu), as.expression)) }) + test_that("hyperSpec objects with wavelength being/containing NA", { + expect_warning(collapse(flu [, , 0])) + + + expect_equal( + suppressWarnings(collapse(flu [, , 0], flu)), + collapse(flu [, , FALSE], flu) + ) + + expect_equal( + suppressWarnings(collapse(flu [, , c(0, 405)], flu)), + collapse(flu [, , 405], flu) + ) + }) } ## warn if wl.tolerance is too large, i.e. it would lead to cluster multiple wavelengths of the same object together. -.assert.suitable.tolerance <- function (dots, wl.tolerance){ - - wl.diff <- sapply (dots, function (x) if (nwl (x) < 2L) NA else min (diff (wl (x)))) # wavelengths are ordered => no abs needed +.assert.suitable.tolerance <- function(dots, wl.tolerance) { + wl.diff <- sapply(dots, function(x) if (nwl(x) < 2L) NA else min(diff(wl(x)))) # wavelengths are ordered => no abs needed i.warn <- wl.diff < 2 * wl.tolerance - if (any (isTRUE (i.warn))) - warning (sprintf ("object %i: wl.tolerance (%g) too large compared to smallest wavelength difference within object (%f). Columns will be lost.", - which (i.warn) , wl.tolerance, wl.diff [i.warn])) + if (any(isTRUE(i.warn))) { + warning(sprintf( + "object %i: wl.tolerance (%g) too large compared to smallest wavelength difference within object (%f). Columns will be lost.", + which(i.warn), wl.tolerance, wl.diff [i.warn] + )) + } } -.assert.noNA.wl <- function (dots){ +.assert.noNA.wl <- function(dots) { + i.NA <- sapply(dots, function(x) any(is.na(wl(x)))) - i.NA <- sapply (dots, function (x) any (is.na (wl (x)))) - - if (any (i.NA)){ - warning (sprintf ("object %i: wavelength vector contains NAs: these columns will be dropped", - which (i.NA))) - dots [i.NA] <- lapply (dots [i.NA], function (x) x [,, !is.na (wl (x))]) + if (any(i.NA)) { + warning(sprintf( + "object %i: wavelength vector contains NAs: these columns will be dropped", + which(i.NA) + )) + dots [i.NA] <- lapply(dots [i.NA], function(x) x [, , !is.na(wl(x))]) } - dots + dots } -#' Try finding groups of hyperSpec objects with (approximately) equal wavelength axes -#' +#' Try finding groups of hyperSpec objects with (approximately) equal wavelength axes +#' #' ... and directly rbind.fill them. #' #' @param dots list with hyperSpec object to collapse #' @param wl.tolerance wavelength difference tolerance #' #' @return possible shorter list of dots -.collapse.equal <- function (dots, wl.tolerance){ - ## bind groups of objects that have *all* wavelengths equal +.collapse.equal <- function(dots, wl.tolerance) { + ## bind groups of objects that have *all* wavelengths equal ## within wl.tolerance from 1st object of potential group - + i <- 1 - - while (i < length (dots)){ - bind_directly <- sapply (tail (dots, -i), function (x){ - (nwl (x) == nwl (dots [[i]])) && all (abs (wl (x) - wl (dots [[i]])) < wl.tolerance) + + while (i < length(dots)) { + bind_directly <- sapply(tail(dots, -i), function(x) { + (nwl(x) == nwl(dots [[i]])) && all(abs(wl(x) - wl(dots [[i]])) < wl.tolerance) }) - bind_directly <- which (bind_directly) - - if (length (bind_directly) > 0L) { - - n <- 0 - wl <- rep (0, nwl (dots [[i]])) - - for (j in c (i, i + bind_directly)){ - wl <- wl + nrow (dots [[j]]) * wl (dots [[j]]) - n <- n + nrow (dots [[j]]) - + bind_directly <- which(bind_directly) + + if (length(bind_directly) > 0L) { + n <- 0 + wl <- rep(0, nwl(dots [[i]])) + + for (j in c(i, i + bind_directly)) { + wl <- wl + nrow(dots [[j]]) * wl(dots [[j]]) + n <- n + nrow(dots [[j]]) + # also ensure same column names within spc. colnames(dots [[j]]@data$spc) <- colnames(dots [[i]]@data$spc) } wl <- wl / n - - dots [[i]]@data <- rbind.fill (lapply (dots [c (i, i + bind_directly)], slot, "data")) - .wl (dots [[i]]) <- structure(wl, names = names (wl (dots [[i]]))) - - labels <- unlist (lapply (dots [c (i, i + bind_directly)], labels)) - labels <- lapply (labels, function (l) if (is.language(l)) l <- as.expression (l) else l) - - labels (dots [[i]]) <- labels [! duplicated(names (labels))] - - dots <- dots [- (i + bind_directly)] + + dots [[i]]@data <- rbind.fill(lapply(dots [c(i, i + bind_directly)], slot, "data")) + .wl(dots [[i]]) <- structure(wl, names = names(wl(dots [[i]]))) + + labels <- unlist(lapply(dots [c(i, i + bind_directly)], labels)) + labels <- lapply(labels, function(l) if (is.language(l)) l <- as.expression(l) else l) + + labels(dots [[i]]) <- labels [!duplicated(names(labels))] + + dots <- dots [-(i + bind_directly)] } - + i <- i + 1 } - + dots } @@ -381,104 +401,109 @@ collapse <- function (..., wl.tolerance = hy.getOption ("wl.tolerance"), collaps #' @param wl.tolerance wavelength difference tolerance #' #' @return data.frame with information about suitable wavelength bins -.cluster.wavelengths <- function (dots, wl.tolerance){ - +.cluster.wavelengths <- function(dots, wl.tolerance) { + # set up data.frame to hold relevant information - wl.df <- lapply (seq_along (dots), function (i){ - if (nwl (dots [[i]]) == 0L) - return (data.frame ()) - - data.frame (wl = wl (dots [[i]]), - iobj = i, - nspc = nrow (dots [[i]]), - wlcol = seq_len (nwl (dots [[i]])), - wlcluster = NA + wl.df <- lapply(seq_along(dots), function(i) { + if (nwl(dots [[i]]) == 0L) { + return(data.frame()) + } + + data.frame( + wl = wl(dots [[i]]), + iobj = i, + nspc = nrow(dots [[i]]), + wlcol = seq_len(nwl(dots [[i]])), + wlcluster = NA ) }) - wl.df <- do.call ("rbind", wl.df) - - ## save old wavelength names + wl.df <- do.call("rbind", wl.df) + + ## save old wavelength names wl.df$old.wlnames <- NA - - for (i in seq_along (dots)){ - wln <- names (dots [[i]]@wavelength) - if (! is.null (wln)) wl.df$old.wlnames [wl.df$iobj == i] <- wln + + for (i in seq_along(dots)) { + wln <- names(dots [[i]]@wavelength) + if (!is.null(wln)) wl.df$old.wlnames [wl.df$iobj == i] <- wln } - - wl.df <- wl.df [order (wl.df$wl),] - - ## computational shortcut: + + wl.df <- wl.df [order(wl.df$wl), ] + + ## computational shortcut: ## wavelengths that are > 2 * wl.tolerance apart must be in different clusters, ## so cluster analysis can be split there - - wl.diff <- diff (wl.df$wl) > 2 * wl.tolerance - - ## assign preliminary clusters - wl.df$wlcluster <- c (1, 1 + cumsum (wl.diff)) - - maxcluster <- tail (wl.df$wlcluster, 1) - + + wl.diff <- diff(wl.df$wl) > 2 * wl.tolerance + + ## assign preliminary clusters + wl.df$wlcluster <- c(1, 1 + cumsum(wl.diff)) + + maxcluster <- tail(wl.df$wlcluster, 1) + ## preliminary clusters may need to be split further - for (i in seq_len (tail (wl.df$wlcluster, 1))){ - tmp <- wl.df [wl.df$wlcluster == i,] - + for (i in seq_len(tail(wl.df$wlcluster, 1))) { + tmp <- wl.df [wl.df$wlcluster == i, ] + ## only 1 wavelength in cluster => nothing to do - if (length (tmp) <= 1L) + if (length(tmp) <= 1L) { next - + } + ## all wavelengths within 2 * wl.tolerance => nothing to do - if (tail (tmp$wl, 1) - tmp$wl [1] <= 2 * wl.tolerance) + if (tail(tmp$wl, 1) - tmp$wl [1] <= 2 * wl.tolerance) { next - + } + ## clustering needs to be done on actually unique wavelengths only - unique.wl <- unique (tmp$wl) - - # make clusters that span at most 2 * wl.tolerance - dist <- dist (unique.wl) - dend <- hclust (dist, method = "complete") - - u <- data.frame (wl = unique.wl, - wlcluster = cutree (dend, h = 2 * wl.tolerance) + maxcluster + unique.wl <- unique(tmp$wl) + + # make clusters that span at most 2 * wl.tolerance + dist <- dist(unique.wl) + dend <- hclust(dist, method = "complete") + + u <- data.frame( + wl = unique.wl, + wlcluster = cutree(dend, h = 2 * wl.tolerance) + maxcluster ) - maxcluster <- tail (u$wlcluster, 1) + maxcluster <- tail(u$wlcluster, 1) - ## "expand" unique wavelengths => wavelengths per object - tmp <- merge (tmp, u, by = "wl", suffixes = c (".prelim", "")) + ## "expand" unique wavelengths => wavelengths per object + tmp <- merge(tmp, u, by = "wl", suffixes = c(".prelim", "")) tmp$wlcluster.prelim <- NULL - + wl.df$wlcluster [wl.df$wlcluster == i] <- tmp$wlcluster } ## cluster numbers so far are in no particular order => rename them so they correspond to increasing wavelengths ## this saves one call to orderwl () later on. - wl.df$wlcluster <- as.numeric (factor (wl.df$wlcluster, levels = unique (wl.df$wlcluster))) + wl.df$wlcluster <- as.numeric(factor(wl.df$wlcluster, levels = unique(wl.df$wlcluster))) - wl.df + wl.df } -.test (.cluster.wavelengths) <- function() { - context (".cluster.wavelengths") - - test_that ("clustering with last window being long", { - - a <- as.hyperSpec (matrix(1:6, ncol = 3), wl = c(0, 2, 4)) - b <- as.hyperSpec (matrix(1:6, ncol = 3), wl = c(0, 2, 5)) - - expect_equal (wl (collapse (a, b, wl.tolerance = 0.25)), c (0, 2, 4, 5)) - expect_equal (wl (collapse (a, b, wl.tolerance = 0.5 )), c (0, 2, 4.5)) +.test(.cluster.wavelengths) <- function() { + context(".cluster.wavelengths") + + test_that("clustering with last window being long", { + a <- as.hyperSpec(matrix(1:6, ncol = 3), wl = c(0, 2, 4)) + b <- as.hyperSpec(matrix(1:6, ncol = 3), wl = c(0, 2, 5)) + + expect_equal(wl(collapse(a, b, wl.tolerance = 0.25)), c(0, 2, 4, 5)) + expect_equal(wl(collapse(a, b, wl.tolerance = 0.5)), c(0, 2, 4.5)) }) - test_that ("new wavelengths are weighted mean of wavelength bin", { - a <- barbiturates [[1]][,,min ~ 30] - b <- barbiturates [[2]][,,min ~ 30] - wl (b) <- wl (b) + 0.03/2 - - expect_equal (wl (collapse (a, b, a, wl.tolerance = 0.03)), - sort (c(27.0499992370605, 28.1499996185303, 30.0499992370605, - 27.1649996185303, 28.0649992370605, 30.1649996185303, - mean (c (29.0499992370605, 29.0499992370605, 29.0649992370605)) - )) + test_that("new wavelengths are weighted mean of wavelength bin", { + a <- barbiturates [[1]][, , min ~ 30] + b <- barbiturates [[2]][, , min ~ 30] + wl(b) <- wl(b) + 0.03 / 2 + + expect_equal( + wl(collapse(a, b, a, wl.tolerance = 0.03)), + sort(c( + 27.0499992370605, 28.1499996185303, 30.0499992370605, + 27.1649996185303, 28.0649992370605, 30.1649996185303, + mean(c(29.0499992370605, 29.0499992370605, 29.0649992370605)) + )) ) }) - } diff --git a/hyperSpec/R/count_lines.R b/hyperSpec/R/count_lines.R index 9da86ad12..773f18611 100644 --- a/hyperSpec/R/count_lines.R +++ b/hyperSpec/R/count_lines.R @@ -1,37 +1,39 @@ ##' count lines (of an ASCII file) ##' ##' @param file the file name or connection -##' @param chunksize `file` is read in chunks of `chunksize` lines. +##' @param chunksize `file` is read in chunks of `chunksize` lines. ##' @return number of lines in file ##' @export ##' @md ##' @author C. Beleites count_lines <- function(file, chunksize = 1e4) { nlines <- 0 - + con <- file(file, open = "r") - on.exit(close (con)) - - while ((n <- length (readLines(con, n = chunksize))) > 0L) + on.exit(close(con)) + + while ((n <- length(readLines(con, n = chunksize))) > 0L) { nlines <- nlines + n - + } + nlines } -.test (count_lines) <- function (){ - context ("count_lines") - +.test(count_lines) <- function() { + context("count_lines") + tmpfile <- tempfile() - on.exit (unlink (tmpfile)) - + on.exit(unlink(tmpfile)) + writeLines("blabla\nblubb", con = tmpfile) - - test_that("file read in one chunk", - expect_equal (count_lines (tmpfile), 2) + + test_that( + "file read in one chunk", + expect_equal(count_lines(tmpfile), 2) ) - - test_that("file read in more chunks", - expect_equal (count_lines (tmpfile, chunksize = 1L), 2) + + test_that( + "file read in more chunks", + expect_equal(count_lines(tmpfile, chunksize = 1L), 2) ) - -} \ No newline at end of file +} diff --git a/hyperSpec/R/cov.R b/hyperSpec/R/cov.R index 525c42a42..ac390f720 100644 --- a/hyperSpec/R/cov.R +++ b/hyperSpec/R/cov.R @@ -11,10 +11,10 @@ ##' @export ##' @examples ##' image (cov (chondro)) -setMethod ("cov", signature = signature (x = "hyperSpec", y = "missing"), function (x, y, use, method){ - validObject (x) - - cov (x@data$spc, use = use, method = method) +setMethod("cov", signature = signature(x = "hyperSpec", y = "missing"), function(x, y, use, method) { + validObject(x) + + cov(x@data$spc, use = use, method = method) }) @@ -30,24 +30,26 @@ setMethod ("cov", signature = signature (x = "hyperSpec", y = "missing"), functi ##' plot (pcov$means) ##' image (pcov$COV) ##' -pooled.cov <- function (x, groups, ..., regularize = 1e-5 * max (abs (COV))){ - chk.hy (x) - validObject (x) +pooled.cov <- function(x, groups, ..., regularize = 1e-5 * max(abs(COV))) { + chk.hy(x) + validObject(x) + + if (!is.factor(groups)) { + stop("groups must be a factor") + } - if (! is.factor (groups)) - stop ("groups must be a factor") + x <- x [!is.na(groups)] + groups <- groups [!is.na(groups)] - x <- x [! is.na (groups)] - groups <- groups [! is.na (groups)] - - means <- aggregate (x, groups, "mean") # TODO: speed up? + means <- aggregate(x, groups, "mean") # TODO: speed up? - COV <- cov (x@data$spc - means@data$spc [as.numeric (groups),, drop = FALSE]) + COV <- cov(x@data$spc - means@data$spc [as.numeric(groups), , drop = FALSE]) ## regularization - COV <- COV + diag (regularize, nrow (COV)) + COV <- COV + diag(regularize, nrow(COV)) - list (COV = COV, - means = means) + list( + COV = COV, + means = means + ) } - diff --git a/hyperSpec/R/decomposition.R b/hyperSpec/R/decomposition.R index 087fc2bbd..60bb12582 100644 --- a/hyperSpec/R/decomposition.R +++ b/hyperSpec/R/decomposition.R @@ -73,126 +73,127 @@ ##' plot (pca.loadings, col = c ("red", "gray50")) ##' plotc (pca.scores, groups = .wavelength) ##' @export -decomposition <- function (object, x, wavelength = seq_len (ncol (x)), - label.wavelength, label.spc, - scores = TRUE, retain.columns = FALSE, - ...){ -# message ("decomposition will be deprecated: please change your code to use `loadings` or `scores` instead.") - - validObject (object) - - if (is.vector (x)) - if (nrow (object) == length (x)) - dim (x) <- c(length (x), 1) - else - dim (x) <- c(1, length (x)) +decomposition <- function(object, x, wavelength = seq_len(ncol(x)), + label.wavelength, label.spc, + scores = TRUE, retain.columns = FALSE, + ...) { + # message ("decomposition will be deprecated: please change your code to use `loadings` or `scores` instead.") + + validObject(object) + + if (is.vector(x)) { + if (nrow(object) == length(x)) { + dim(x) <- c(length(x), 1) + } else { + dim(x) <- c(1, length(x)) + } + } - if ((nrow (x) == nrow (object)) && scores){ + if ((nrow(x) == nrow(object)) && scores) { ## scores-like object? object@data$spc <- x - .wl (object) <- wavelength + .wl(object) <- wavelength - if (!missing (label.wavelength)) + if (!missing(label.wavelength)) { object@label$.wavelength <- label.wavelength - - } else if (ncol (x) == nwl (object)){ + } + } else if (ncol(x) == nwl(object)) { ## loadings-like object - spc <- match ("spc", colnames(object@data)) + spc <- match("spc", colnames(object@data)) ## apply changes type of retained columns to character!!! ## must be done in a loop one column after the other otherwise a matrix or a list in a column ## (e.g. for the independent variate of PLS, POSIXlt) will cause an error - cols <- rep (TRUE, ncol (object@data)) # columns to keep + cols <- rep(TRUE, ncol(object@data)) # columns to keep - for (i in seq_len (ncol (object@data)) [-spc]) { - tmp <- as.data.frame (lapply (object@data[, i, drop = FALSE], .na.if.different)) + for (i in seq_len(ncol(object@data)) [-spc]) { + tmp <- as.data.frame(lapply(object@data[, i, drop = FALSE], .na.if.different)) object@data [1, i] <- tmp - if (all (is.na (tmp))) + if (all(is.na(tmp))) { cols [i] <- FALSE + } } if (!retain.columns) { - object@label [colnames (object@data) [!cols]] <- NULL + object@label [colnames(object@data) [!cols]] <- NULL object@data <- object@data[, cols, drop = FALSE] } object@data <- object@data[rep(1, nrow(x)), , drop = FALSE] - colnames (x) <- colnames (object@data$spc) + colnames(x) <- colnames(object@data$spc) object@data$spc <- x - } else { - stop ("Either rows (if scores == TRUE) or columns (if scores == FALSE) of", - " x and object must correspond") + stop( + "Either rows (if scores == TRUE) or columns (if scores == FALSE) of", + " x and object must correspond" + ) } - rownames (object@data) <- rownames (x) + rownames(object@data) <- rownames(x) - if (!missing (label.spc)) object@label$spc <- label.spc + if (!missing(label.spc)) object@label$spc <- label.spc - object@data$spc <- unclass (object@data$spc) # remove AsIs + object@data$spc <- unclass(object@data$spc) # remove AsIs object <- .fix_spc_colnames(object) - - validObject (object) + + validObject(object) object } ##' @include unittest.R -.test (decomposition) <- function (){ -context ("decomposition") +.test(decomposition) <- function() { + context("decomposition") - test_that ("scores-like", { - flu$matrix <- cbind (flu$c, flu$c) - expect_true (is.matrix (flu$matrix)) + test_that("scores-like", { + flu$matrix <- cbind(flu$c, flu$c) + expect_true(is.matrix(flu$matrix)) - tmp <- flu [,, 405 ~ 410] - tmp@wavelength <- seq_len (nwl (tmp)) - colnames (tmp@data$spc) <- seq_len (nwl (tmp)) + tmp <- flu [, , 405 ~ 410] + tmp@wavelength <- seq_len(nwl(tmp)) + colnames(tmp@data$spc) <- seq_len(nwl(tmp)) - scores <- decomposition (flu, flu [[,, 405 ~ 410]]) - expect_equal (scores, tmp) + scores <- decomposition(flu, flu [[, , 405 ~ 410]]) + expect_equal(scores, tmp) }) - test_that ("spc labels", { - scores <- decomposition (flu, flu [[,, 405 ~ 410]], label.spc = "bla") - expect_equal (labels (scores, "spc"), "bla") + test_that("spc labels", { + scores <- decomposition(flu, flu [[, , 405 ~ 410]], label.spc = "bla") + expect_equal(labels(scores, "spc"), "bla") }) - test_that ("wl labels", { - scores <- decomposition (flu, flu [[,, 405 ~ 410]], label.wavelength = "bla") - expect_equal (labels (scores, ".wavelength"), "bla") + test_that("wl labels", { + scores <- decomposition(flu, flu [[, , 405 ~ 410]], label.wavelength = "bla") + expect_equal(labels(scores, ".wavelength"), "bla") }) - test_that ("check loadings-like", { - - tmp <- flu [1, c ("spc"),] - loadings <- decomposition (flu, flu [[1,,]]) - expect_equal (loadings, tmp) + test_that("check loadings-like", { + tmp <- flu [1, c("spc"), ] + loadings <- decomposition(flu, flu [[1, , ]]) + expect_equal(loadings, tmp) }) - test_that ("POSIXct", { + test_that("POSIXct", { flu$ct <- as.POSIXct(Sys.time()) - expect_equal (decomposition (flu, flu [[]], scores = FALSE)$ct, flu$ct) + expect_equal(decomposition(flu, flu [[]], scores = FALSE)$ct, flu$ct) }) - test_that ("POSIXlt", { + test_that("POSIXlt", { flu$lt <- as.POSIXlt(Sys.time()) - expect_equal (decomposition (flu, flu [[]], scores = FALSE)$lt, flu$lt) + expect_equal(decomposition(flu, flu [[]], scores = FALSE)$lt, flu$lt) }) - test_that ("spc labels", { - tmp <- decomposition (flu, flu [[]], scores = FALSE, label.spc = "bla") - expect_equal (labels (tmp, "spc"), "bla") + test_that("spc labels", { + tmp <- decomposition(flu, flu [[]], scores = FALSE, label.spc = "bla") + expect_equal(labels(tmp, "spc"), "bla") }) - test_that ("wl labels: should *not* be changed for loadings-like decomposition", { - tmp <- decomposition (flu, flu [[]], scores = FALSE, label.wavelength = "bla") - expect_equal (labels (tmp, ".wavelength"), labels (flu, ".wavelength")) + test_that("wl labels: should *not* be changed for loadings-like decomposition", { + tmp <- decomposition(flu, flu [[]], scores = FALSE, label.wavelength = "bla") + expect_equal(labels(tmp, ".wavelength"), labels(flu, ".wavelength")) }) - } - diff --git a/hyperSpec/R/deprecated.R b/hyperSpec/R/deprecated.R index 628f46ddd..7711f58cd 100644 --- a/hyperSpec/R/deprecated.R +++ b/hyperSpec/R/deprecated.R @@ -3,41 +3,59 @@ ##' @rdname read.asc.Andor ##' @export ##' @keywords internal -scan.asc.Andor <- function (...) {.Deprecated("read.asc.Andor"); read.asc.Andor(...)} +scan.asc.Andor <- function(...) { + .Deprecated("read.asc.Andor") + read.asc.Andor(...) +} ##' @rdname read.txt.Renishaw ##' @export ##' @keywords internal -scan.txt.Renishaw <- function (...) {.Deprecated("read.txt.Renishaw()"); read.txt.Renishaw(...)} +scan.txt.Renishaw <- function(...) { + .Deprecated("read.txt.Renishaw()") + read.txt.Renishaw(...) +} ##' @rdname read.txt.Renishaw ##' @export ##' @keywords internal -scan.zip.Renishaw <- function (...) {.Deprecated("read.(zip.Renishaw)"); read.zip.Renishaw(...)} +scan.zip.Renishaw <- function(...) { + .Deprecated("read.(zip.Renishaw)") + read.zip.Renishaw(...) +} ##' @rdname read.txt.Witec ##' @export ##' @keywords internal -scan.txt.Witec <- function (...) {.Deprecated("read.txt.Witec()"); read.txt.Witec(...)} +scan.txt.Witec <- function(...) { + .Deprecated("read.txt.Witec()") + read.txt.Witec(...) +} ##' @rdname read.txt.Witec ##' @export ##' @keywords internal -scan.dat.Witec <- function (...) {.Deprecated("read.(dat.Witec)"); read.dat.Witec(...)} +scan.dat.Witec <- function(...) { + .Deprecated("read.(dat.Witec)") + read.dat.Witec(...) +} ##' @rdname read.txt.Witec ##' @export ##' @keywords internal -scan.txt.Witec.Graph <- function (...) {.Deprecated("read.txt.Witec.Graph()"); read.txt.Witec.Graph(...)} +scan.txt.Witec.Graph <- function(...) { + .Deprecated("read.txt.Witec.Graph()") + read.txt.Witec.Graph(...) +} #### DEFUNCT ################################################################################################## ##' @export ##' @rdname read.mat.Cytospec -read.cytomat <- function (...){ - .Defunct ("read.mat.Cytospec", - package = "hyperSpec", - msg = "read.mat.Cytospec is now defunct.\nPlease use read.mat.Cytospec instead.") +read.cytomat <- function(...) { + .Defunct("read.mat.Cytospec", + package = "hyperSpec", + msg = "read.mat.Cytospec is now defunct.\nPlease use read.mat.Cytospec instead." + ) } - diff --git a/hyperSpec/R/dim.R b/hyperSpec/R/dim.R index 708ea030d..592a800c0 100644 --- a/hyperSpec/R/dim.R +++ b/hyperSpec/R/dim.R @@ -9,82 +9,80 @@ ##' @param x a \code{hyperSpec} object ##' @author C. Beleites ##' @seealso \code{\link[base]{ncol}} -##' +##' ##' @return \code{nrow}, \code{ncol}, \code{nwl}, and \code{length}, return an ##' \code{integer}. -##' @export +##' @export ##' @examples -##' +##' ##' ncol (chondro) -setMethod ("ncol", signature = signature ("hyperSpec"), function (x){ - validObject (x) +setMethod("ncol", signature = signature("hyperSpec"), function(x) { + validObject(x) - ncol (x@data) + ncol(x@data) }) ##' ##' \code{nrow} yields the number of rows in \code{x@@data}, i.e. the number of ##' spectra in the \code{hyperSpec} object. -##' +##' ##' @rdname dim ##' @seealso \code{\link[base]{nrow}} ##' @export ##' @examples ##' nrow (chondro) -setMethod ("nrow", signature = signature ("hyperSpec"), function (x){ - validObject (x) +setMethod("nrow", signature = signature("hyperSpec"), function(x) { + validObject(x) - nrow (x@data) + nrow(x@data) }) ##' ##' \code{nwl} returns the number of columns in \code{x@@data$spc}, i.e. the ##' length of each spectrum. -##' +##' ##' @rdname dim ##' @aliases nwl ##' @export ##' @examples -##' +##' ##' nwl (chondro) -nwl <- function (x){ - chk.hy (x) - validObject (x) - - ncol (x@data$spc) +nwl <- function(x) { + chk.hy(x) + validObject(x) + + ncol(x@data$spc) } ##' ##' \code{dim} returns all three values in a vector. -##' -##' +##' +##' ##' @rdname dim ##' @return -##' +##' ##' \code{dim} returns a vector of length 3. ##' @seealso \code{\link[base]{dim}} ##' @keywords methods -##' @export +##' @export ##' @examples ##' dim (chondro) -setMethod ("dim", signature = signature ("hyperSpec"), function (x){ - validObject (x) - c (nrow = nrow (x@data), ncol = ncol (x@data), nwl = ncol (x@data$spc)) +setMethod("dim", signature = signature("hyperSpec"), function(x) { + validObject(x) + c(nrow = nrow(x@data), ncol = ncol(x@data), nwl = ncol(x@data$spc)) }) -##' +##' ##' \code{length} is a synonym for \code{nrow}. It is supplied so that ##' \code{seq_along (x)} returns a sequence to index each spectrum. ##' @rdname dim ##' @seealso \code{\link[base]{length}} -##' @export +##' @export ##' @examples ##' length (chondro) -setMethod ("length", signature = signature ("hyperSpec"), function (x) { - validObject (x) - nrow (x@data) +setMethod("length", signature = signature("hyperSpec"), function(x) { + validObject(x) + nrow(x@data) }) - - diff --git a/hyperSpec/R/dimnames.R b/hyperSpec/R/dimnames.R index f66fe6a02..b398dbd7d 100644 --- a/hyperSpec/R/dimnames.R +++ b/hyperSpec/R/dimnames.R @@ -2,7 +2,7 @@ ##' ##' hyperSpec objects can have row- and column names like data.frames. The "names" of the wavelengths ##' are treated separately: see \code{\link{wl}} -##' +##' ##' @param x the hyperSpec object ##' @aliases dimnames ##' @keywords methods @@ -15,11 +15,13 @@ ##' @export ##' @examples ##' dimnames (flu) -setMethod ("dimnames", signature = signature (x = "hyperSpec"), function (x){ - validObject (x) +setMethod("dimnames", signature = signature(x = "hyperSpec"), function(x) { + validObject(x) - list (row = rownames (x@data), data = colnames (x@data), - wl = colnames (x@data$spc)) + list( + row = rownames(x@data), data = colnames(x@data), + wl = colnames(x@data$spc) + ) }) ##' @rdname dimnames @@ -31,10 +33,10 @@ setMethod ("dimnames", signature = signature (x = "hyperSpec"), function (x){ ##' @export ##' @examples ##' rownames (flu) -setMethod ("rownames", signature = signature (x = "hyperSpec"), function (x, do.NULL = TRUE, prefix = "row"){ - validObject (x) - - rownames (x@data, do.NULL = do.NULL, prefix = prefix) +setMethod("rownames", signature = signature(x = "hyperSpec"), function(x, do.NULL = TRUE, prefix = "row") { + validObject(x) + + rownames(x@data, do.NULL = do.NULL, prefix = prefix) }) ##' @param value the new names @@ -44,10 +46,10 @@ setMethod ("rownames", signature = signature (x = "hyperSpec"), function (x, do. ##' @rdname dimnames ##' @name rownames<- ##' @export "rownames<-" -setReplaceMethod ("rownames", signature = signature (x = "hyperSpec"), function (x, value){ - validObject (x) - - rownames (x@data) <- value +setReplaceMethod("rownames", signature = signature(x = "hyperSpec"), function(x, value) { + validObject(x) + + rownames(x@data) <- value x }) @@ -58,11 +60,13 @@ setReplaceMethod ("rownames", signature = signature (x = "hyperSpec"), function ##' @examples ##' colnames (chondro) -setMethod ("colnames", signature = signature (x = "hyperSpec"), - function (x, do.NULL = TRUE, prefix = "col"){ - validObject (x) - colnames (x@data, do.NULL = do.NULL, prefix = prefix) -}) +setMethod("colnames", + signature = signature(x = "hyperSpec"), + function(x, do.NULL = TRUE, prefix = "col") { + validObject(x) + colnames(x@data, do.NULL = do.NULL, prefix = prefix) + } +) ##' @rdname dimnames ##' @usage @@ -70,13 +74,15 @@ setMethod ("colnames", signature = signature (x = "hyperSpec"), ##' @aliases colnames<-,hyperSpec-method ##' @name colnames<- ##' @export "colnames<-" -setReplaceMethod ("colnames", signature = signature (x = "hyperSpec"), - function (x, value){ - validObject (x) +setReplaceMethod("colnames", + signature = signature(x = "hyperSpec"), + function(x, value) { + validObject(x) - names (x@label [colnames (x@data)]) <- value - colnames (x@data) <- value - - validObject (x) # necessary: $spc could be renamed! - x -}) + names(x@label [colnames(x@data)]) <- value + colnames(x@data) <- value + + validObject(x) # necessary: $spc could be renamed! + x + } +) diff --git a/hyperSpec/R/droplevels.R b/hyperSpec/R/droplevels.R index e92b8e802..d55baf25e 100644 --- a/hyperSpec/R/droplevels.R +++ b/hyperSpec/R/droplevels.R @@ -1,4 +1,4 @@ -.droplevels <- function (x, ...){ +.droplevels <- function(x, ...) { x@data <- droplevels(x@data, ...) x @@ -19,27 +19,29 @@ #' @examples #' #' chondro[1:3]$clusters -#' droplevels (chondro [1:3])$clusters +#' droplevels(chondro [1:3])$clusters setMethod("droplevels", signature = "hyperSpec", definition = .droplevels) .test(.droplevels) <- function() { - context ("droplevels") - - test_that ("no change on object without levels to drop",{ - expect_equal(droplevels (chondro), chondro) + context("droplevels") + + test_that("no change on object without levels to drop", { + expect_equal(droplevels(chondro), chondro) }) - test_that ("dropping levels",{ - tmp <- droplevels (chondro [1:3]) - expect_equal(tmp@data, droplevels (chondro@data [1:3,])) - - expect_equal (tmp [ , c ("x", "y", "filename", "spc")], - chondro [1:3, c ("x", "y", "filename", "spc")]) - - expect_equal (tmp$clusters, factor (rep ("matrix", 3))) + test_that("dropping levels", { + tmp <- droplevels(chondro [1:3]) + expect_equal(tmp@data, droplevels(chondro@data [1:3, ])) + + expect_equal( + tmp [, c("x", "y", "filename", "spc")], + chondro [1:3, c("x", "y", "filename", "spc")] + ) + + expect_equal(tmp$clusters, factor(rep("matrix", 3))) }) - test_that ("no change if factor is `except`ed",{ - expect_equal(droplevels (chondro, except = 4), chondro) + test_that("no change if factor is `except`ed", { + expect_equal(droplevels(chondro, except = 4), chondro) }) -} \ No newline at end of file +} diff --git a/hyperSpec/R/empty.R b/hyperSpec/R/empty.R index 61e6523c8..f93e53004 100644 --- a/hyperSpec/R/empty.R +++ b/hyperSpec/R/empty.R @@ -1,29 +1,29 @@ ##' Empty hyperSpec object -##' +##' ##' Empty produces an hyperSpec object with the same columns and wavelengths as \code{x}. The new ##' object will either contain no rows at all (default), or the given number of rows with all data ##' initialized to \code{spc} and \code{extra}, respectively. -##' +##' ##' @aliases empty ##' @author C. Beleites ##' @keywords manip ##' @export -##' @examples +##' @examples ##' empty (chondro, nrow = 2, spc = 0) ##' @param x hyperSpec object ##' @param nrow number of rows the new object should have ##' @param spc value to initialize the new spectra matrix with ##' @param extra value to initialize the new extra data with -empty <- function (x, nrow = 0, spc = NA, extra = NA) { - - if (nrow (x@data) == 0 && nrow > 0) - stop ("Empty is not implemented for empty (0 row) objects") +empty <- function(x, nrow = 0, spc = NA, extra = NA) { + if (nrow(x@data) == 0 && nrow > 0) { + stop("Empty is not implemented for empty (0 row) objects") + } - x@data <- x@data [rep (1L, nrow), ] + x@data <- x@data [rep(1L, nrow), ] - if (nrow > 0){ + if (nrow > 0) { x@data$spc [TRUE] <- spc - x@data[, ! grepl ("^spc$", colnames (x@data))] <- extra + x@data[, !grepl("^spc$", colnames(x@data))] <- extra } x diff --git a/hyperSpec/R/extract.R b/hyperSpec/R/extract.R index d21492088..a8a126304 100644 --- a/hyperSpec/R/extract.R +++ b/hyperSpec/R/extract.R @@ -1,31 +1,32 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### .extract - internal function doing the work for extracting with [] and [[]] ### ##' @include wl2i.R ##' @noRd -.extract <- function (x, i, j, l, - ..., - wl.index = FALSE -){ - if (! missing (i)) - x@data <- x@data[i,, drop = FALSE] +.extract <- function(x, i, j, l, + ..., + wl.index = FALSE) { + if (!missing(i)) { + x@data <- x@data[i, , drop = FALSE] + } - if (!missing (j)){ + if (!missing(j)) { x@data <- x@data[, j, drop = FALSE] - x@label <- x@label [c (".wavelength", colnames (x@data))] + x@label <- x@label [c(".wavelength", colnames(x@data))] } - if (!missing (l)) { - if (is.null (x@data$spc)) - warning ("Selected columns do not contain specta. l ignored.") - else { - if (!wl.index) - l <- wl2i (x, l) + if (!missing(l)) { + if (is.null(x@data$spc)) { + warning("Selected columns do not contain specta. l ignored.") + } else { + if (!wl.index) { + l <- wl2i(x, l) + } - x@data$spc <- x@data$spc[,l, drop = FALSE] - .wl (x) <- x@wavelength[l] + x@data$spc <- x@data$spc[, l, drop = FALSE] + .wl(x) <- x@wavelength[l] } } @@ -195,78 +196,91 @@ ##' ##' @include call.list.R ##' @export -setMethod ("[", signature = signature (x = "hyperSpec"), - function (x, i, j, l, ..., - wl.index = FALSE, - drop = FALSE # drop has to be at end - ){ - validObject (x) +setMethod("[", + signature = signature(x = "hyperSpec"), + function(x, i, j, l, ..., + wl.index = FALSE, + drop = FALSE # drop has to be at end + ) { + validObject(x) - if (drop) - warning ("Ignoring drop = TRUE.") + if (drop) { + warning("Ignoring drop = TRUE.") + } - dots <- list (...) - if (length (dots) > 0L) - warning ("Ignoring additional parameters: ", .pastenames (dots)) + dots <- list(...) + if (length(dots) > 0L) { + warning("Ignoring additional parameters: ", .pastenames(dots)) + } - x <- .extract (x, i, j, l, wl.index = wl.index) + x <- .extract(x, i, j, l, wl.index = wl.index) - if (is.null (x@data$spc)){ - x@data$spc <- matrix (NA, nrow (x@data), 0) - x@wavelength <- numeric (0) - } + if (is.null(x@data$spc)) { + x@data$spc <- matrix(NA, nrow(x@data), 0) + x@wavelength <- numeric(0) + } - x -}) + x + } +) ##' @rdname extractreplace ##' @export ##' @aliases [[ [[,hyperSpec-method ## ' @name [[ -setMethod ("[[", signature = signature (x = "hyperSpec"), - function (x, i, j, l, ..., - wl.index = FALSE, - drop = FALSE){ - validObject (x) - - dots <- list (...) - if (length (dots) > 0L) - warning ("Ignoring additional parameters: ", .pastenames (dots)) +setMethod("[[", + signature = signature(x = "hyperSpec"), + function(x, i, j, l, ..., + wl.index = FALSE, + drop = FALSE) { + validObject(x) - ## check wheter a index matrix is used - if (! missing (i) && is.matrix (i)){ - if (! is.logical (i) && ! (is.numeric (i) && ncol (i) == 2)) - stop ("Index matrix i must either be logical of the size of x$spc,", - "or a n by 2 matrix.") + dots <- list(...) + if (length(dots) > 0L) { + warning("Ignoring additional parameters: ", .pastenames(dots)) + } - if (is.numeric (i) && ! wl.index) - i [, 2] <- .getindex (x, i [, 2], extrapolate = FALSE) + ## check wheter a index matrix is used + if (!missing(i) && is.matrix(i)) { + if (!is.logical(i) && !(is.numeric(i) && ncol(i) == 2)) { + stop( + "Index matrix i must either be logical of the size of x$spc,", + "or a n by 2 matrix." + ) + } - x@data$spc [i] # return value + if (is.numeric(i) && !wl.index) { + i [, 2] <- .getindex(x, i [, 2], extrapolate = FALSE) + } - } else { # index by row and columns - x <- .extract (x, i, j, l, wl.index = wl.index) - if (missing (j)) - unclass (x@data$spc[,, drop = drop]) # retrun value; removes the "AsIs" - else { - x@data[,, drop = drop] # return value: data.frame + x@data$spc [i] # return value + } else { # index by row and columns + x <- .extract(x, i, j, l, wl.index = wl.index) + if (missing(j)) { + unclass(x@data$spc[, , drop = drop]) + } # retrun value; removes the "AsIs" + else { + x@data[, , drop = drop] # return value: data.frame + } } } -}) +) ##' @rdname extractreplace ##' @param name name of the data column to extract. \code{$spc} yields the spectra matrix. ##' @aliases $ $,hyperSpec-method ##' @export -setMethod ("$", signature = signature (x = "hyperSpec"), - function (x, name){ - validObject (x) - - if (name == ".") ## shortcut - x@data [, , drop = FALSE] - else if (name == "..") - x@data[, -match ("spc", colnames (x@data)), drop = FALSE] - else - x@data[[name]] -}) +setMethod("$", + signature = signature(x = "hyperSpec"), + function(x, name) { + validObject(x) + if (name == ".") { ## shortcut + x@data [, , drop = FALSE] + } else if (name == "..") { + x@data[, -match("spc", colnames(x@data)), drop = FALSE] + } else { + x@data[[name]] + } + } +) diff --git a/hyperSpec/R/factor2num.R b/hyperSpec/R/factor2num.R index 45fea7896..ae06734f4 100644 --- a/hyperSpec/R/factor2num.R +++ b/hyperSpec/R/factor2num.R @@ -1,10 +1,10 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### factor2num - conversion of a factor containing numerical levels ### ### -##TODO: export - -factor2num <- function (f) - as.numeric(levels (f)) [as.numeric (f)] +## TODO: export +factor2num <- function(f) { + as.numeric(levels(f)) [as.numeric(f)] +} diff --git a/hyperSpec/R/fileio.optional.R b/hyperSpec/R/fileio.optional.R index ae93ad401..7ceeec921 100644 --- a/hyperSpec/R/fileio.optional.R +++ b/hyperSpec/R/fileio.optional.R @@ -2,32 +2,32 @@ ## consistent optional treatment during file import -.fileio.optional <- function (spc, filename, ..., - file.remove.emptyspc = hy.getOption ("file.remove.emptyspc"), - file.keep.name = hy.getOption ("file.keep.name"), - tolerance = hy.getOption ("tolerance")){ - - tolerance <- .checkpos (tolerance, "tolerance") +.fileio.optional <- function(spc, filename, ..., + file.remove.emptyspc = hy.getOption("file.remove.emptyspc"), + file.keep.name = hy.getOption("file.keep.name"), + tolerance = hy.getOption("tolerance")) { + tolerance <- .checkpos(tolerance, "tolerance") if (file.remove.emptyspc) { ## number of NAs in each spectrum - nas <- rowSums (is.na (spc)) + nas <- rowSums(is.na(spc)) ## number of zero-values in each spectrum - zeros <- rowSums (abs (spc) < tolerance, na.rm = TRUE) + zeros <- rowSums(abs(spc) < tolerance, na.rm = TRUE) - spc <- spc [nas + zeros < nwl (spc)] + spc <- spc [nas + zeros < nwl(spc)] } - if (file.keep.name & nrow (spc) > 0L){ - if (is.null (spc@data$filename)){ - if (is (filename, "connection")) + if (file.keep.name & nrow(spc) > 0L) { + if (is.null(spc@data$filename)) { + if (is(filename, "connection")) { filename <- summary(filename)$description + } spc@data$filename <- filename spc@label$filename <- "filename" } else { - warning ("$filename already exists. => Skipping file.keep.name") + warning("$filename already exists. => Skipping file.keep.name") } } @@ -35,37 +35,40 @@ } ##' @include unittest.R -.test (.fileio.optional) <- function (){ - context (".fileio.optional") +.test(.fileio.optional) <- function() { + context(".fileio.optional") - test_that ("removing of zero/NA spectra", { + test_that("removing of zero/NA spectra", { tmp <- fluNA # spectrum 2 is all NA tmp [[3]] <- 0 - tmp [[5]] <- runif (nwl(tmp), min = - hy.getOption("tolerance") / 2, max = hy.getOption("tolerance") / 2) - tmp [[,, 450~455]] <- NA + tmp [[5]] <- runif(nwl(tmp), min = -hy.getOption("tolerance") / 2, max = hy.getOption("tolerance") / 2) + tmp [[, , 450 ~ 455]] <- NA - expect_equivalent (.fileio.optional (tmp, file.remove.emptyspc = TRUE, file.keep.name = FALSE), - tmp [- c(2, 3, 5)]) + expect_equivalent( + .fileio.optional(tmp, file.remove.emptyspc = TRUE, file.keep.name = FALSE), + tmp [-c(2, 3, 5)] + ) }) - test_that ("filenames", { + test_that("filenames", { flu$filename <- NULL - tmp <- .fileio.optional (flu, filename = "test", file.remove.emptyspc = FALSE, file.keep.name = TRUE) - expect_true (all (tmp$filename == "test")) - - expect_warning(tmp <- .fileio.optional (tmp, filename = "test2", - file.remove.emptyspc = FALSE, file.keep.name = TRUE) - ) - expect_true (all (tmp$filename == "test")) + tmp <- .fileio.optional(flu, filename = "test", file.remove.emptyspc = FALSE, file.keep.name = TRUE) + expect_true(all(tmp$filename == "test")) + + expect_warning(tmp <- .fileio.optional(tmp, + filename = "test2", + file.remove.emptyspc = FALSE, file.keep.name = TRUE + )) + expect_true(all(tmp$filename == "test")) }) options.state <- .options - on.exit(do.call (hy.setOptions, options.state)) + on.exit(do.call(hy.setOptions, options.state)) test_that("option treatment", { hy.setOptions(file.remove.emptyspc = FALSE) - skip ("TODO: implement") - do.call (hy.setOptions, options.state) + skip("TODO: implement") + do.call(hy.setOptions, options.state) }) } diff --git a/hyperSpec/R/fix_spc_colnames.R b/hyperSpec/R/fix_spc_colnames.R index 1a5ff3011..fca1618e4 100644 --- a/hyperSpec/R/fix_spc_colnames.R +++ b/hyperSpec/R/fix_spc_colnames.R @@ -5,20 +5,20 @@ #' @return hyperSpec object with wavelengths in column names of `$spc` #' @md #' @export -.fix_spc_colnames <- function(spc){ - colnames (spc@data$spc) <- signif (spc@wavelength, digits = 6) - +.fix_spc_colnames <- function(spc) { + colnames(spc@data$spc) <- signif(spc@wavelength, digits = 6) + spc } -.test (.fix_spc_colnames) <- function(){ +.test(.fix_spc_colnames) <- function() { context(".fix_spc_colnames") - + test_that("colnames get fixed", { tmp <- flu colnames(tmp@data$spc) <- NULL - - tmp <- .fix_spc_colnames(tmp) - expect_equal(colnames (tmp@data$spc), as.character (wl (tmp))) + + tmp <- .fix_spc_colnames(tmp) + expect_equal(colnames(tmp@data$spc), as.character(wl(tmp))) }) -} \ No newline at end of file +} diff --git a/hyperSpec/R/flu.R b/hyperSpec/R/flu.R index 2b9882c05..1fb6f4a51 100644 --- a/hyperSpec/R/flu.R +++ b/hyperSpec/R/flu.R @@ -1,9 +1,9 @@ ##' Quinine Fluorescence Spectra ##' Fluorescence spectra of different dilutions of quinine forming a ##' calibration set. -##' +##' ##' See the vignette: \code{vignette ("flu", package = "hyperSpec")} -##' +##' ##' @name flu ##' @docType data ##' @format The data set has 6 fluorescence emission spectra measured on @@ -12,22 +12,21 @@ ##' @author M. Kammer and C. Beleites ##' @keywords datasets ##' @examples -##' +##' ##' flu -##' +##' ##' plot (flu) -##' +##' ##' plotc (flu) -##' +##' NULL -.make.fluNA <- function (){ - - fluNA <- hyperSpec::flu - fluNA [[2,]] <- NA - fluNA [[,,406]] <- NA - - fluNA +.make.fluNA <- function() { + fluNA <- hyperSpec::flu + fluNA [[2, ]] <- NA + fluNA [[, , 406]] <- NA + + fluNA } -delayedAssign ("fluNA", .make.fluNA ()) +delayedAssign("fluNA", .make.fluNA()) diff --git a/hyperSpec/R/getbynames.R b/hyperSpec/R/getbynames.R index a7d7ff4b8..52e6e1714 100644 --- a/hyperSpec/R/getbynames.R +++ b/hyperSpec/R/getbynames.R @@ -1,17 +1,18 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### -### getbynames - get list elements by name and if no such element exists, NA +### getbynames - get list elements by name and if no such element exists, NA ### ### -getbynames <- function (x, e) { - x <- x [e] - if (length (x) > 0) { - if (is.character (e)) - names (x) <- e - x [sapply (x, is.null)] <- NA - x - } else { - list () - } +getbynames <- function(x, e) { + x <- x [e] + if (length(x) > 0) { + if (is.character(e)) { + names(x) <- e + } + x [sapply(x, is.null)] <- NA + x + } else { + list() + } } diff --git a/hyperSpec/R/guesswavelength.R b/hyperSpec/R/guesswavelength.R index 115fcef3f..c097d75e4 100644 --- a/hyperSpec/R/guesswavelength.R +++ b/hyperSpec/R/guesswavelength.R @@ -1,51 +1,52 @@ #' guess wavelengths from character vector -#' -#' character vectors used for names (e.g. colnames for matrices or data.frames) +#' +#' character vectors used for names (e.g. colnames for matrices or data.frames) #' are often treated by \code{\link[base]{make.names}} or similar functions that -#' produce suitable names (e.g. by prepending "X" to numbers.). Such names +#' produce suitable names (e.g. by prepending "X" to numbers.). Such names #' cannot be directly converted to numeric. -#' +#' #' \code{guess.wavlength} tries to extract numbers from X which may be #' surrounded by such "protecting" characters. -#' +#' #' @param X character with numbers hidden inside -#' +#' #' @return numeric #' @export -#' +#' #' @examples -#' tmp <- data.frame(flu [[,, 400 ~ 410]]) -#' (wl <- colnames (tmp)) -#' guess.wavelength (wl) -guess.wavelength <- function (X) { - wl <- regmatches (X, regexpr(.PATTERN.number, X)) - wl <- as.numeric (wl) - - if (is.null (wl) || length (wl) == 0L || any (is.na (wl))){ - if (hy.getOption("debuglevel") >= 1L) +#' tmp <- data.frame(flu [[, , 400 ~ 410]]) +#' (wl <- colnames(tmp)) +#' guess.wavelength(wl) +guess.wavelength <- function(X) { + wl <- regmatches(X, regexpr(.PATTERN.number, X)) + wl <- as.numeric(wl) + + if (is.null(wl) || length(wl) == 0L || any(is.na(wl))) { + if (hy.getOption("debuglevel") >= 1L) { message("could not guess wavelengths") + } wl <- NULL } - wl + wl } ##' @include regexps.R ##' @include options.R -.test (guess.wavelength) <- function (){ - context ("guess.wavelength") - - test_that("simple test", { - expect_equal (guess.wavelength(1:5), 1:5) - }) - - test_that("wavelengths containing characters", { - wl <- seq(600,602,length.out = 11) - expect_equal (guess.wavelength(make.names(wl)), wl) - }) - - test_that("return NULL if could not guess wavelenths", { - expect_equal (guess.wavelength(colnames(matrix(1:12,3))), NULL) - expect_equal (guess.wavelength(letters[1:4]), NULL) - }) -} \ No newline at end of file +.test(guess.wavelength) <- function() { + context("guess.wavelength") + + test_that("simple test", { + expect_equal(guess.wavelength(1:5), 1:5) + }) + + test_that("wavelengths containing characters", { + wl <- seq(600, 602, length.out = 11) + expect_equal(guess.wavelength(make.names(wl)), wl) + }) + + test_that("return NULL if could not guess wavelenths", { + expect_equal(guess.wavelength(colnames(matrix(1:12, 3))), NULL) + expect_equal(guess.wavelength(letters[1:4]), NULL) + }) +} diff --git a/hyperSpec/R/hyperspec-class.R b/hyperSpec/R/hyperspec-class.R index f8d93d727..5bd16c5bb 100644 --- a/hyperSpec/R/hyperspec-class.R +++ b/hyperSpec/R/hyperspec-class.R @@ -2,10 +2,10 @@ ##' This class handles hyperspectral data sets, i.e. spatially or time-resolved ##' spectra, or spectra with any other kind of information associated with the ##' spectra. -##' +##' ##' The spectra can be data as obtained in XRF, UV/VIS, Fluorescence, AES, NIR, ##' IR, Raman, NMR, MS, etc. -##' +##' ##' More generally, any data that is recorded over a discretized variable, e.g. ##' absorbance = f (wavelength), stored as a vector of absorbance values for ##' discrete wavelengths is suitable. @@ -21,7 +21,7 @@ ##' @slot label expressions for column labels (incl. units). The label of the wavelength axis is in ##' the special element \code{.wavelength}. ##' @slot log deprecated. -##' @note Please note that the logbook is now removed. +##' @note Please note that the logbook is now removed. ##' @author C. Beleites ##' @seealso See the vignette "hyperspec" for an introduction to hyperSpec ##' from a spectroscopic point of view. @@ -29,20 +29,20 @@ ##' @export ##' @include validate.R ##' @examples -##' +##' ##' showClass("hyperSpec") ##' \dontrun{vignette ("hyperspec")} -setClass ("hyperSpec", - representation = representation ( - wavelength = "numeric", # spectral abscissa - data = "data.frame", # data: spectra & information related to each spectrum - label = "list", # labels and units of the stored - log = "data.frame" # deprecated - ), - prototype = prototype ( - wavelength = numeric (0), - data = data.frame (spc = I (matrix (NA, 0, 0))), - label = list (.wavelength = NULL, "spc" = NULL)), - validity = .validate +setClass("hyperSpec", + representation = representation( + wavelength = "numeric", # spectral abscissa + data = "data.frame", # data: spectra & information related to each spectrum + label = "list", # labels and units of the stored + log = "data.frame" # deprecated + ), + prototype = prototype( + wavelength = numeric(0), + data = data.frame(spc = I(matrix(NA, 0, 0))), + label = list(.wavelength = NULL, "spc" = NULL) + ), + validity = .validate ) - diff --git a/hyperSpec/R/hyperspec-package.R b/hyperSpec/R/hyperspec-package.R index ca6e0f79d..d80a2ac3d 100644 --- a/hyperSpec/R/hyperspec-package.R +++ b/hyperSpec/R/hyperspec-package.R @@ -3,24 +3,24 @@ ##' Hyperspectral data are spatially or time-resolved spectra, or spectra with ##' any other kind of information associated with the spectra. E.g. spectral ##' maps or images, time series, calibration series, etc. -##' +##' ##' The spectra can be data as obtained in XRF, UV/VIS, Fluorescence, AES, NIR, ##' IR, Raman, NMR, MS, etc. -##' +##' ##' More generally, any data that is recorded over a discretized variable, e.g. ##' absorbance = f (wavelength), stored as a vector of absorbance values for ##' discrete wavelengths is suitable. -##' +##' ##' @name hyperSpec-package ##' @title Package hyperSpec ##' @docType package ##' @author C. Beleites -##' +##' ##' Maintainer: Claudia Beleites ##' @seealso \code{citation ("hyperSpec")} produces the correct citation. -##' +##' ##' \code{package?hyperSpec} for information about the package -##' +##' ##' \code{class?hyperSpec} for details on the S4 class provided by this ##' package. ##' @rdname hyperSpec-package diff --git a/hyperSpec/R/initialize.R b/hyperSpec/R/initialize.R index eb2226877..ae332f8d5 100644 --- a/hyperSpec/R/initialize.R +++ b/hyperSpec/R/initialize.R @@ -1,4 +1,4 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### initialize -- initialization, called by new ("hyperSpec", ...) ### @@ -7,127 +7,138 @@ ##' @include paste.row.R ##' @noRd -.initialize <- function (.Object, spc = NULL, data = NULL, wavelength = NULL, labels = NULL){ +.initialize <- function(.Object, spc = NULL, data = NULL, wavelength = NULL, labels = NULL) { ## do the small stuff first, so we need not be too careful about copies ## the wavelength axis - if (! is.null (wavelength) && ! is.numeric (wavelength)) - stop ("wavelength is not numeric but ", class (wavelength), ".") - - if (!is.null (spc)){ - if (is.null (dim (spc))){ - nwl <- length (spc) - if (.options$gc) gc () - dim (spc) <- c(1, nwl) - if (.options$gc) gc () + if (!is.null(wavelength) && !is.numeric(wavelength)) { + stop("wavelength is not numeric but ", class(wavelength), ".") + } + + if (!is.null(spc)) { + if (is.null(dim(spc))) { + nwl <- length(spc) + if (.options$gc) gc() + dim(spc) <- c(1, nwl) + if (.options$gc) gc() } else { - nwl <- ncol (spc) + nwl <- ncol(spc) } - } else if (!is.null (data$spc)) - nwl <- ncol (data$spc) - else + } else if (!is.null(data$spc)) { + nwl <- ncol(data$spc) + } else { nwl <- 0 + } - if (is.null (wavelength)){ + if (is.null(wavelength)) { ## guess from spc's colnames - if (!is.null (spc)) - wavelength <- as.numeric (colnames (spc)) + if (!is.null(spc)) { + wavelength <- as.numeric(colnames(spc)) + } - if (length (wavelength) == 0L || any (is.na (wavelength))) - wavelength <- as.numeric (colnames (data$spc)) + if (length(wavelength) == 0L || any(is.na(wavelength))) { + wavelength <- as.numeric(colnames(data$spc)) + } - if (length (wavelength) == 0L || any (is.na (wavelength))) - wavelength <- seq_len (nwl) # guessing didn't work - } else if (! is.numeric (wavelength)) { - stop ("wavelength must be numeric.") + if (length(wavelength) == 0L || any(is.na(wavelength))) { + wavelength <- seq_len(nwl) + } # guessing didn't work + } else if (!is.numeric(wavelength)) { + stop("wavelength must be numeric.") } .Object@wavelength <- wavelength ## column + wavelength axis labels - if (is.null (labels) || length (labels) == 0L){ - cln <- c (colnames (data), '.wavelength') - if (! any (grepl ("spc", cln))) - cln <- c (cln, "spc") - labels <- vector ("list", length (cln)) - names (labels) <- cln - rm (cln) + if (is.null(labels) || length(labels) == 0L) { + cln <- c(colnames(data), ".wavelength") + if (!any(grepl("spc", cln))) { + cln <- c(cln, "spc") + } + labels <- vector("list", length(cln)) + names(labels) <- cln + rm(cln) } ## transform labels into expressions - .make.expression <- function (x){ - if (is.language (x) && ! is.expression (x)) - class (x) <- "expression" - else if (is.character (x)) - x <- as.expression (x) + .make.expression <- function(x) { + if (is.language(x) && !is.expression(x)) { + class(x) <- "expression" + } else if (is.character(x)) { + x <- as.expression(x) + } x } - labels <- lapply (labels, .make.expression) + labels <- lapply(labels, .make.expression) .Object@label <- labels - rm (labels) - if (.options$gc) gc () + rm(labels) + if (.options$gc) gc() - if (! is.null (data$spc) && ! (is.null (spc))) - warning ("Spectra in data are overwritten by argument spc.") + if (!is.null(data$spc) && !(is.null(spc))) { + warning("Spectra in data are overwritten by argument spc.") + } ## deal with spectra - if (is.null (spc) && is.null (data$spc)){ - spc <- structure(numeric (0), .Dim = c(0L, 0L)) + if (is.null(spc) && is.null(data$spc)) { + spc <- structure(numeric(0), .Dim = c(0L, 0L)) } - if (! is.null (spc) && !is.matrix (spc)) { - spc <- as.matrix (spc) - if (ncol (spc) == 1L) - spc <- t (spc) + if (!is.null(spc) && !is.matrix(spc)) { + spc <- as.matrix(spc) + if (ncol(spc) == 1L) { + spc <- t(spc) + } } - if (!is.null (spc) && !is.numeric(spc) && !all (is.na (spc))){ - dim <- dim (spc) - spc <- suppressWarnings (as.numeric(spc)) - if (all (is.na (spc))) - stop ("spectra matrix needs to be numeric or convertable to numeric") - else - warning ("spectra matrix is converted from ", class (data$spc), " to numeric.") + if (!is.null(spc) && !is.numeric(spc) && !all(is.na(spc))) { + dim <- dim(spc) + spc <- suppressWarnings(as.numeric(spc)) + if (all(is.na(spc))) { + stop("spectra matrix needs to be numeric or convertable to numeric") + } else { + warning("spectra matrix is converted from ", class(data$spc), " to numeric.") + } - dim (spc) <- dim + dim(spc) <- dim } - if (.options$gc) gc () + if (.options$gc) gc() - if (! is.null (spc)){ - attr (spc, "class") <- "AsIs" # I seems to make more than one copy - if (.options$gc) gc () + if (!is.null(spc)) { + attr(spc, "class") <- "AsIs" # I seems to make more than one copy + if (.options$gc) gc() } - + ## deal with extra data - if (is.null (data)){ - data <- data.frame (spc = spc) - } else if (! is.null (spc)){ - if (nrow (data) == 1 && nrow (spc) > 1) - data <- data [rep (1, nrow (spc)), , drop = FALSE] + if (is.null(data)) { + data <- data.frame(spc = spc) + } else if (!is.null(spc)) { + if (nrow(data) == 1 && nrow(spc) > 1) { + data <- data [rep(1, nrow(spc)), , drop = FALSE] + } data$spc <- spc } - rm (spc) - if (.options$gc) gc () + rm(spc) + if (.options$gc) gc() + + attr(data$spc, "class") <- NULL # more than one copy!? + if (.options$gc) gc() - attr (data$spc, "class") <- NULL # more than one copy!? - if (.options$gc) gc () - .Object@data <- data - if (.options$gc) gc () + if (.options$gc) gc() + + + .Object <- .fix_spc_colnames(.Object) # for consistency with .wl<- - - .Object <- .fix_spc_colnames (.Object) # for consistency with .wl<- - ## finally: check whether we got a valid hyperSpec object - validObject (.Object) + validObject(.Object) .Object } @@ -203,88 +214,88 @@ ##' plot (h) ##' plotc (h, spc ~ pos) ##' -setMethod ("initialize", "hyperSpec", .initialize) +setMethod("initialize", "hyperSpec", .initialize) ##' @include unittest.R -.test (.initialize) <- function (){ - context (".initialize / new (\"hyperSpec\")") +.test(.initialize) <- function() { + context(".initialize / new (\"hyperSpec\")") test_that("empty hyperSpec object", { - expect_equal (dim (new ("hyperSpec")), c (nrow = 0L, ncol = 1L, nwl = 0L)) + expect_equal(dim(new("hyperSpec")), c(nrow = 0L, ncol = 1L, nwl = 0L)) }) test_that("vector for spc", { - h <- new ("hyperSpec", spc = 1 : 4) - expect_equal (h@data$spc, matrix (1 : 4, nrow = 1, dimnames = list (NULL, 1:4))) - expect_equal (as.numeric (colnames (h@data$spc)), 1:4) - expect_equal (dim (h), c (nrow = 1L, ncol = 1L, nwl = 4L)) - expect_equal (h@wavelength, 1 : 4) + h <- new("hyperSpec", spc = 1:4) + expect_equal(h@data$spc, matrix(1:4, nrow = 1, dimnames = list(NULL, 1:4))) + expect_equal(as.numeric(colnames(h@data$spc)), 1:4) + expect_equal(dim(h), c(nrow = 1L, ncol = 1L, nwl = 4L)) + expect_equal(h@wavelength, 1:4) }) test_that("matrix for spc", { - spc <- matrix (c(1 : 12), nrow = 3) - h <- new ("hyperSpec", spc = spc) - - expect_equivalent (h@data$spc, spc) - expect_equal (dimnames (h@data$spc), list (NULL, as.character (1:4))) - expect_equal (dim (h@data$spc), dim (spc)) - - expect_equal (dim (h), c (nrow = 3L, ncol = 1L, nwl = 4L)) - expect_equal (h@wavelength, 1 : 4) + spc <- matrix(c(1:12), nrow = 3) + h <- new("hyperSpec", spc = spc) + + expect_equivalent(h@data$spc, spc) + expect_equal(dimnames(h@data$spc), list(NULL, as.character(1:4))) + expect_equal(dim(h@data$spc), dim(spc)) + + expect_equal(dim(h), c(nrow = 3L, ncol = 1L, nwl = 4L)) + expect_equal(h@wavelength, 1:4) }) - spc <- matrix (c(1 : 12), nrow = 3) + spc <- matrix(c(1:12), nrow = 3) test_that("matrix with numbers in colnames for spc", { colnames(spc) <- c(600, 601, 602, 603) - h <- new ("hyperSpec", spc = spc) - expect_equal (h@data$spc, spc) - expect_equal (dim (h), c (nrow = 3L, ncol = 1L, nwl = 4L)) - expect_equal (h@wavelength, c(600, 601, 602, 603)) + h <- new("hyperSpec", spc = spc) + expect_equal(h@data$spc, spc) + expect_equal(dim(h), c(nrow = 3L, ncol = 1L, nwl = 4L)) + expect_equal(h@wavelength, c(600, 601, 602, 603)) }) colnames(spc) <- c(600, 601, 602, 603) test_that("spc and data given", { - h <- new ("hyperSpec", spc = spc, data = data.frame (x = 3)) - expect_equal (h@data$spc, spc) - expect_equal (dim (h), c (nrow = 3L, ncol = 2L, nwl = 4L)) - expect_equal (h@wavelength, c(600, 601, 602, 603)) - expect_equal (h@data$x, rep (3, 3L)) + h <- new("hyperSpec", spc = spc, data = data.frame(x = 3)) + expect_equal(h@data$spc, spc) + expect_equal(dim(h), c(nrow = 3L, ncol = 2L, nwl = 4L)) + expect_equal(h@wavelength, c(600, 601, 602, 603)) + expect_equal(h@data$x, rep(3, 3L)) }) test_that("spc and data given, data has $spc column (which should be overwritten with warning)", { - expect_warning(h <- new ("hyperSpec", spc = spc, data = data.frame (spc = 11:13))) - expect_equal (h@data$spc, spc) - expect_equal (dim (h), c (nrow = 3L, ncol = 1L, nwl = 4L)) - expect_equal (h@wavelength, c(600, 601, 602, 603)) + expect_warning(h <- new("hyperSpec", spc = spc, data = data.frame(spc = 11:13))) + expect_equal(h@data$spc, spc) + expect_equal(dim(h), c(nrow = 3L, ncol = 1L, nwl = 4L)) + expect_equal(h@wavelength, c(600, 601, 602, 603)) }) test_that("spc and data given, different numbers of rows", { - expect_error (new ("hyperSpec", spc = spc, data = data.frame (x = 11:12))) + expect_error(new("hyperSpec", spc = spc, data = data.frame(x = 11:12))) }) test_that("only data given, data has $spc column with `I()`-protected matrix", { - h <- new ("hyperSpec", data = data.frame (spc = I (spc))) - expect_equal (h@data$spc, spc) - expect_equal (dim (h), c (nrow = 3L, ncol = 1L, nwl = 4L)) - expect_equal (h@wavelength, c(600, 601, 602, 603)) + h <- new("hyperSpec", data = data.frame(spc = I(spc))) + expect_equal(h@data$spc, spc) + expect_equal(dim(h), c(nrow = 3L, ncol = 1L, nwl = 4L)) + expect_equal(h@wavelength, c(600, 601, 602, 603)) }) test_that("spc is data.frame", { - h <- new ("hyperSpec", spc = as.data.frame (spc)) - expect_equal (h@data$spc, spc) - expect_equal (dim (h), c (nrow = 3L, ncol = 1L, nwl = 4L)) + h <- new("hyperSpec", spc = as.data.frame(spc)) + expect_equal(h@data$spc, spc) + expect_equal(dim(h), c(nrow = 3L, ncol = 1L, nwl = 4L)) }) test_that("uncommon spectra matrix class that can be converted to numeric", { - expect_warning (new ("hyperSpec", flu > 100)) + expect_warning(new("hyperSpec", flu > 100)) }) test_that("spectra matrix class cannot be converted to numeric", { - expect_error (new ("hyperSpec", matrix (letters [1:6], 3))) + expect_error(new("hyperSpec", matrix(letters [1:6], 3))) }) - test_that ("error if wavelength is not numeric", { - expect_error(new ("hyperSpec", spc = NA, wavelength = letters [1:3])) + test_that("error if wavelength is not numeric", { + expect_error(new("hyperSpec", spc = NA, wavelength = letters [1:3])) }) @@ -293,8 +304,8 @@ setMethod ("initialize", "hyperSpec", .initialize) on.exit(hy.setOptions(gc = option)) hy.setOptions(gc = TRUE) - spc <- new ("hyperSpec", spc = flu [[]]) - expect_equal(spc [[]], flu [[]]) + spc <- new("hyperSpec", spc = flu [[]]) + expect_equal(spc [[]], flu [[]]) }) } @@ -312,15 +323,16 @@ setMethod ("initialize", "hyperSpec", .initialize) #' @return hyperSpec object #' @seealso \code{\link[hyperSpec]{initialize}} #' @export -setGeneric ("as.hyperSpec", - function (X, ...){ - stop ("as.hyperSpec is not available for objects of class ", class (X)) - } +setGeneric( + "as.hyperSpec", + function(X, ...) { + stop("as.hyperSpec is not available for objects of class ", class(X)) + } ) #' @include guesswavelength.R -.as.hyperSpec.matrix <- function (X, wl = guess.wavelength (colnames (X)), ...){ - new ("hyperSpec", spc = X, wavelength = wl, ...) +.as.hyperSpec.matrix <- function(X, wl = guess.wavelength(colnames(X)), ...) { + new("hyperSpec", spc = X, wavelength = wl, ...) } #' @rdname as.hyperSpec @@ -330,93 +342,93 @@ setGeneric ("as.hyperSpec", #' @export #' #' @examples -#' tmp <- data.frame(flu [[,, 400 ~ 410]]) -#' (wl <- colnames (tmp)) -#' guess.wavelength (wl) +#' tmp <- data.frame(flu [[, , 400 ~ 410]]) +#' (wl <- colnames(tmp)) +#' guess.wavelength(wl) +setMethod("as.hyperSpec", "matrix", .as.hyperSpec.matrix) -setMethod ("as.hyperSpec", "matrix", .as.hyperSpec.matrix) - -.as.hyperSpec.data.frame <- function (X, spc = NULL, wl = guess.wavelength (spc), labels = attr (X, "labels"), ...){ +.as.hyperSpec.data.frame <- function(X, spc = NULL, wl = guess.wavelength(spc), labels = attr(X, "labels"), ...) { # TODO: remove after 31.12.2020 - if (!all (!is.na (guess.wavelength(colnames(X))))) - warning ("as.hyperSpec.data.frame has changed its behaviour. Use as.hyperSpec (as.matrix (X)) instead.") + if (!all(!is.na(guess.wavelength(colnames(X))))) { + warning("as.hyperSpec.data.frame has changed its behaviour. Use as.hyperSpec (as.matrix (X)) instead.") + } - if (is.null (spc)){ - spc <- matrix (ncol = 0, nrow = nrow (X)) - wl <- numeric (0) + if (is.null(spc)) { + spc <- matrix(ncol = 0, nrow = nrow(X)) + wl <- numeric(0) } - new ("hyperSpec", data = X, wavelength = wl, spc = spc, labels = labels, ...) + new("hyperSpec", data = X, wavelength = wl, spc = spc, labels = labels, ...) } #' @rdname as.hyperSpec #' @note \emph{Note that the behaviour of \code{as.hyperSpec (X)} was changed: it now assumes \code{X} to be extra data, #' and returns a hyperSpec object with 0 wavelengths. To get the old behaviour} -setMethod ("as.hyperSpec", "data.frame", .as.hyperSpec.data.frame) +setMethod("as.hyperSpec", "data.frame", .as.hyperSpec.data.frame) ##' @include unittest.R -.test (as.hyperSpec) <- function (){ - context ("as.hyperSpec") - - spc <- matrix(1:12,ncol = 3) - wl <- seq(600, 601, length.out = ncol(spc)) - - test_that("only spc is given", { - expect_identical (new ("hyperSpec", spc = spc), as.hyperSpec(X = spc)) - }) - - test_that("data.frame", { - tmp <- as.hyperSpec(flu$..) - expect_equal(tmp$.., flu$..) - expect_equal(dim (tmp), c (nrow = 6L, ncol = 3L, nwl = 0L)) - expect_equal(wl (tmp), numeric (0)) - }) - - test_that("data.frame with labels attribute", { - tmp <- flu$.. - attr (tmp, "labels") <- labels (flu) - - tmp <- as.hyperSpec(tmp) - - expect_equal(tmp$.., flu$..) - expect_equal(dim (tmp), c (nrow = 6L, ncol = 3L, nwl = 0L)) - expect_equal(wl (tmp), numeric (0)) - expect_equal(labels (tmp) [order (names (labels (tmp)))], - lapply (labels (flu) [order (names (labels (flu)))], as.expression)) - }) - - test_that("spc with characters in colnames", { - colnames(spc) <- make.names(wl) - h <- as.hyperSpec(X = spc) - expect_equivalent (h@data$spc, spc) - expect_equal (dim (h@data$spc), dim (spc)) - expect_equal (dim (h), c (nrow = nrow(spc), ncol = 1L, nwl = ncol(spc))) - expect_equal (h@wavelength, wl) - expect_equal (as.numeric (colnames (h@data$spc)), wl) - }) - - test_that("ignore colnames if wl is set", { - colnames(spc) <- c(601,602,603) - expect_identical (new ("hyperSpec", spc = spc, wavelength = wl), as.hyperSpec(X = spc, wl = wl)) - }) - - test_that("set additional parameters", { - dt <- data.frame(x=1:4,y=letters[1:4]) - lbs <- list (spc = "I / a.u.", .wavelength = expression (tilde (nu) / cm^-1)) - expect_identical (new ("hyperSpec", spc = spc, data = dt, label = lbs), as.hyperSpec(X = spc, data = dt, label = lbs)) - }) - - - test_that ("error on unknown class", { - tmp <- NA - class (tmp) <- "foo" - expect_error (as.hyperSpec(tmp)) - }) - - test_that ("colnames of spectra matrix correctly set (as done by wl<-)", { - tmp <- new ("hyperSpec", spc = spc, wavelength = wl) - expect_equal (colnames (tmp$spc), as.character (signif (wl, 6))) - }) -} +.test(as.hyperSpec) <- function() { + context("as.hyperSpec") + + spc <- matrix(1:12, ncol = 3) + wl <- seq(600, 601, length.out = ncol(spc)) + + test_that("only spc is given", { + expect_identical(new("hyperSpec", spc = spc), as.hyperSpec(X = spc)) + }) + + test_that("data.frame", { + tmp <- as.hyperSpec(flu$..) + expect_equal(tmp$.., flu$..) + expect_equal(dim(tmp), c(nrow = 6L, ncol = 3L, nwl = 0L)) + expect_equal(wl(tmp), numeric(0)) + }) + + test_that("data.frame with labels attribute", { + tmp <- flu$.. + attr(tmp, "labels") <- labels(flu) + + tmp <- as.hyperSpec(tmp) + + expect_equal(tmp$.., flu$..) + expect_equal(dim(tmp), c(nrow = 6L, ncol = 3L, nwl = 0L)) + expect_equal(wl(tmp), numeric(0)) + expect_equal( + labels(tmp) [order(names(labels(tmp)))], + lapply(labels(flu) [order(names(labels(flu)))], as.expression) + ) + }) + test_that("spc with characters in colnames", { + colnames(spc) <- make.names(wl) + h <- as.hyperSpec(X = spc) + expect_equivalent(h@data$spc, spc) + expect_equal(dim(h@data$spc), dim(spc)) + expect_equal(dim(h), c(nrow = nrow(spc), ncol = 1L, nwl = ncol(spc))) + expect_equal(h@wavelength, wl) + expect_equal(as.numeric(colnames(h@data$spc)), wl) + }) + + test_that("ignore colnames if wl is set", { + colnames(spc) <- c(601, 602, 603) + expect_identical(new("hyperSpec", spc = spc, wavelength = wl), as.hyperSpec(X = spc, wl = wl)) + }) + + test_that("set additional parameters", { + dt <- data.frame(x = 1:4, y = letters[1:4]) + lbs <- list(spc = "I / a.u.", .wavelength = expression(tilde(nu) / cm^-1)) + expect_identical(new("hyperSpec", spc = spc, data = dt, label = lbs), as.hyperSpec(X = spc, data = dt, label = lbs)) + }) + + test_that("error on unknown class", { + tmp <- NA + class(tmp) <- "foo" + expect_error(as.hyperSpec(tmp)) + }) + + test_that("colnames of spectra matrix correctly set (as done by wl<-)", { + tmp <- new("hyperSpec", spc = spc, wavelength = wl) + expect_equal(colnames(tmp$spc), as.character(signif(wl, 6))) + }) +} diff --git a/hyperSpec/R/labels.R b/hyperSpec/R/labels.R index a50333a2d..37513a973 100644 --- a/hyperSpec/R/labels.R +++ b/hyperSpec/R/labels.R @@ -1,57 +1,72 @@ ##' @importFrom utils modifyList -.labels <- function (object, which = bquote(), drop = TRUE, ..., use.colnames = TRUE){ - validObject (object) - - if (! missing (which) & ! is.character (which)) - warning ("labels are not guaranteed to have the same order as columns.", - "Consider using indexing by name.") +.labels <- function(object, which = bquote(), drop = TRUE, ..., use.colnames = TRUE) { + validObject(object) + + if (!missing(which) & !is.character(which)) { + warning( + "labels are not guaranteed to have the same order as columns.", + "Consider using indexing by name." + ) + } ## fill in colnames? - if (use.colnames){ - label <- structure (as.list (c(colnames (object@data), ".wavelength")), - names = c(colnames (object@data), ".wavelength")) - label <- modifyList (label, object@label) + if (use.colnames) { + label <- structure(as.list(c(colnames(object@data), ".wavelength")), + names = c(colnames(object@data), ".wavelength") + ) + label <- modifyList(label, object@label) label <- label [which] } else { label <- object@label [which] } - if (drop && length (label) == 1L) + if (drop && length(label) == 1L) { label <- label [[1]] + } label } ##' @include unittest.R -.test (.labels) <- function (){ - context (".labels") +.test(.labels) <- function() { + context(".labels") - .sort <- function (x) - x [order (names (x))] + .sort <- function(x) { + x [order(names(x))] + } - test_that ("return exactly @label with use.colnames == FALSE", - expect_equal(.sort (labels (flu, use.colnames = FALSE)), .sort (flu@label)) + test_that( + "return exactly @label with use.colnames == FALSE", + expect_equal(.sort(labels(flu, use.colnames = FALSE)), .sort(flu@label)) ) - test_that ("fill in missing labels", { + test_that("fill in missing labels", { tmp <- flu tmp@label$filename <- NULL - expect_equal (.sort (labels (flu)), - .sort (c (tmp@label , filename = "filename"))) + expect_equal( + .sort(labels(flu)), + .sort(c(tmp@label, filename = "filename")) + ) }) - test_that ("labels for specified columns", { + test_that("labels for specified columns", { tmp <- flu tmp@label$filename <- NULL - expect_equal (labels (tmp, c ("c", "filename", "file"), use.colnames = FALSE), - structure(list(c = "c / (mg / l)", `NA` = NULL, `NA` = NULL), - .Names = c("c", NA, NA))) - - expect_equal (labels (flu, c ("c", "filename", "file")), - structure(list(c = "c / (mg / l)", filename = "filename", `NA` = NULL), - .Names = c("c", "filename", NA))) + expect_equal( + labels(tmp, c("c", "filename", "file"), use.colnames = FALSE), + structure(list(c = "c / (mg / l)", `NA` = NULL, `NA` = NULL), + .Names = c("c", NA, NA) + ) + ) + + expect_equal( + labels(flu, c("c", "filename", "file")), + structure(list(c = "c / (mg / l)", filename = "filename", `NA` = NULL), + .Names = c("c", "filename", NA) + ) + ) }) } @@ -67,26 +82,26 @@ ##' ##' labels (flu, "c") <- expression ("/" ("c", "mg / l")) ##' -`labels<-` <- function (object, which = NULL, ..., value){ - chk.hy (object) - validObject (object) +`labels<-` <- function(object, which = NULL, ..., value) { + chk.hy(object) + validObject(object) - if (is.null (which)) + if (is.null(which)) { object@label <- value - else { - if ((is.character (which) && !which %in% colnames (object@data)) && - which != ".wavelength" || # neither a colname nor .wavelength - (is.numeric (which) && (which < 1 || which > ncol (object@data) + 1)) || - (is.logical (which) && length (which) != ncol (object@data) + 1) - # or outside valid indices - ) - stop ("Column to label does not exist!") + } else { + if ((is.character(which) && !which %in% colnames(object@data)) && + which != ".wavelength" || # neither a colname nor .wavelength + (is.numeric(which) && (which < 1 || which > ncol(object@data) + 1)) || + (is.logical(which) && length(which) != ncol(object@data) + 1) + # or outside valid indices + ) { + stop("Column to label does not exist!") + } object@label [[which]] <- value - } - validObject (object) + validObject(object) object } @@ -122,5 +137,4 @@ ##' ##' labels (chondro) ##' -setMethod ("labels", signature = signature (object = "hyperSpec"), .labels) - +setMethod("labels", signature = signature(object = "hyperSpec"), .labels) diff --git a/hyperSpec/R/laser.R b/hyperSpec/R/laser.R index ebf11f23b..1bb02d16e 100644 --- a/hyperSpec/R/laser.R +++ b/hyperSpec/R/laser.R @@ -1,8 +1,8 @@ ##' Laser Emission ##' A time series of an unstable laser emission. -##' +##' ##' see the Vignette -##' +##' ##' @name laser ##' @docType data ##' @format The data set consists of 84 laser emission spectra measured during @@ -11,18 +11,18 @@ ##' @author C. Beleites ##' @keywords datasets ##' @examples -##' +##' ##' laser -##' +##' ##' cols <- c ("black", "blue", "darkgreen", "red") ##' wl <- c (405.0, 405.1, 405.3, 405.4) ##' plotspc (laser, axis.args=list (x = list (at = seq (404.5, 405.8, .1)))) ##' for (i in seq_along (wl)) ##' abline (v = wl[i], col = cols[i], lwd = 2, lty = 2) -##' +##' ##' plotc (laser [,, wl], spc ~ t, groups = .wavelength, type = "b", ##' col = cols) -##' +##' ##' \dontrun{vignette ("laser", package="hyperSpec")} -##' +##' NULL diff --git a/hyperSpec/R/levelplot.R b/hyperSpec/R/levelplot.R index 0e181508f..9c698f9b2 100644 --- a/hyperSpec/R/levelplot.R +++ b/hyperSpec/R/levelplot.R @@ -1,5 +1,5 @@ ##' @importFrom lattice latticeParseFormula -setGeneric ("levelplot", package = "lattice") +setGeneric("levelplot", package = "lattice") ################################################################################# ### @@ -10,74 +10,85 @@ setGeneric ("levelplot", package = "lattice") ### the workhorse function ##' @importFrom utils modifyList -.levelplot <- function (x, data, transform.factor = TRUE, ..., - contour = FALSE, useRaster = !contour) { - validObject (data) +.levelplot <- function(x, data, transform.factor = TRUE, ..., + contour = FALSE, useRaster = !contour) { + validObject(data) - data$.row <- row.seq (data) + data$.row <- row.seq(data) ## parse formula to find the columns to be plotted ## they may include also "wavelength" - parsed.formula <- latticeParseFormula (x, - as.long.df (data [1, , 1, wl.index = TRUE], rownames = TRUE), - dimension = 3) + parsed.formula <- latticeParseFormula(x, + as.long.df(data [1, , 1, wl.index = TRUE], rownames = TRUE), + dimension = 3 + ) use.x <- parsed.formula$right.x.name use.y <- parsed.formula$right.y.name use.z <- parsed.formula$left.name - dots <- list (..., contour = contour, useRaster = useRaster) + dots <- list(..., contour = contour, useRaster = useRaster) ## if spc is used as z and the data set has multiple wavelengths cut and warn - if (use.z == "spc" && nwl (data) > 1 && - !any (grepl (".wavelength", c(as.character (x), - as.character (dots$groups), - as.character (dots$subset))))) { + if (use.z == "spc" && nwl(data) > 1 && + !any(grepl(".wavelength", c( + as.character(x), + as.character(dots$groups), + as.character(dots$subset) + )))) { data <- data [, , 1, wl.index = TRUE] - warning ("Only first wavelength is used for plotting") + warning("Only first wavelength is used for plotting") } - dots <- modifyList (list (xlab = data@label [[use.x]], - ylab = data@label [[use.y]]), - dots) - - if (any (grepl ("spc", c(as.character (x), - as.character (dots$groups), - as.character (dots$subset))))){ - data <- as.long.df (data, rownames = TRUE, - wl.factor = ".wavelength" %in% c (as.character (dots$groups), - as.character (dots$subset), - names (parsed.formula$condition)) - ) + dots <- modifyList( + list( + xlab = data@label [[use.x]], + ylab = data@label [[use.y]] + ), + dots + ) + + if (any(grepl("spc", c( + as.character(x), + as.character(dots$groups), + as.character(dots$subset) + )))) { + data <- as.long.df(data, + rownames = TRUE, + wl.factor = ".wavelength" %in% c( + as.character(dots$groups), + as.character(dots$subset), + names(parsed.formula$condition) + ) + ) } else { data <- data$.. - data$.rownames <- as.factor (rownames (data)) + data$.rownames <- as.factor(rownames(data)) } - if (is.factor (data [[use.z]]) && transform.factor) { - dots <- trellis.factor.key (data [[use.z]], dots) - data [[use.z]] <- as.numeric (data [[use.z]]) + if (is.factor(data [[use.z]]) && transform.factor) { + dots <- trellis.factor.key(data [[use.z]], dots) + data [[use.z]] <- as.numeric(data [[use.z]]) } - do.call(levelplot, c (list (x, data), dots)) + do.call(levelplot, c(list(x, data), dots)) } ##' @include unittest.R -.test (.levelplot) <- function (){ - context (".levelplot") +.test(.levelplot) <- function() { + context(".levelplot") - test_that ("no errors", { + test_that("no errors", { ## just check that no errors occur - expect_silent (levelplot (laser, contour = TRUE, col = "#00000080")) + expect_silent(levelplot(laser, contour = TRUE, col = "#00000080")) ## applying a function before plotting - expect_silent (plotmap (chondro, func = max, col.regions = gray (seq (0, 1, 0.05)))) + expect_silent(plotmap(chondro, func = max, col.regions = gray(seq(0, 1, 0.05)))) - expect_silent (plotmap (chondro, clusters ~ x * y, transform.factor = FALSE)) - expect_silent (plotmap (chondro, clusters ~ x * y, col.regions = gray (seq (0, 1, 0.05)))) + expect_silent(plotmap(chondro, clusters ~ x * y, transform.factor = FALSE)) + expect_silent(plotmap(chondro, clusters ~ x * y, col.regions = gray(seq(0, 1, 0.05)))) }) - } ##' @include plotmap.R @@ -91,13 +102,16 @@ setGeneric ("levelplot", package = "lattice") ##' ##' \code{\link{trellis.factor.key}} for improved color coding of factors ##' @importFrom lattice levelplot -setMethod (f = "levelplot", signature = signature (x = "hyperSpec", data = "missing"), - definition = function (x, data, ...) { - .levelplot (x = formula (spc ~ .wavelength * .row), data = x, ...) - }) +setMethod( + f = "levelplot", signature = signature(x = "hyperSpec", data = "missing"), + definition = function(x, data, ...) { + .levelplot(x = formula(spc ~ .wavelength * .row), data = x, ...) + } +) ##' @rdname levelplot ##' @export -setMethod (f = "levelplot", signature = signature (x = "formula", data = "hyperSpec"), - definition = .levelplot) - +setMethod( + f = "levelplot", signature = signature(x = "formula", data = "hyperSpec"), + definition = .levelplot +) diff --git a/hyperSpec/R/makeraster.R b/hyperSpec/R/makeraster.R index 3fb059296..be3aa2a4e 100644 --- a/hyperSpec/R/makeraster.R +++ b/hyperSpec/R/makeraster.R @@ -36,30 +36,31 @@ ##' points (which (onraster), raster$x [onraster], col = "blue", pch = 20) ##' ##' @importFrom utils tail -makeraster <- function (x, startx, d, newlevels, tol = 0.1){ - - if (missing (newlevels)) +makeraster <- function(x, startx, d, newlevels, tol = 0.1) { + if (missing(newlevels)) { ## make sure to cover the whole data range + 1 point - newlevels <- c (rev (seq (startx, min (x, na.rm = TRUE) - d, by = -d) [-1]), - seq (startx, max (x, na.rm = TRUE) + d, by = d) - ) - - inew <- approx (newlevels, seq_along (newlevels), x)$y + newlevels <- c( + rev(seq(startx, min(x, na.rm = TRUE) - d, by = -d) [-1]), + seq(startx, max(x, na.rm = TRUE) + d, by = d) + ) + } + + inew <- approx(newlevels, seq_along(newlevels), x)$y - ## rounding - rinew <- round (inew) - wholenum <- abs (inew - rinew) < tol + ## rounding + rinew <- round(inew) + wholenum <- abs(inew - rinew) < tol xnew <- x xnew [wholenum] <- newlevels [rinew [wholenum]] - list (x = xnew, + list( + x = xnew, - ## usually: drop outside levels 1 and length (newlevels) - levels = newlevels [min (rinew [wholenum]) : max (rinew [wholenum])] - ) - + ## usually: drop outside levels 1 and length (newlevels) + levels = newlevels [min(rinew [wholenum]):max(rinew [wholenum])] + ) } ##' @rdname makeraster @@ -93,43 +94,45 @@ makeraster <- function (x, startx, d, newlevels, tol = 0.1){ ##' onraster <- raster$x %in% raster$levels ##' points (which (onraster), raster$x [onraster], col = "blue", pch = 20) ##' -fitraster <- function (x, tol = 0.1){ - levels <- sort (unique (x)) - - if (length (levels) == 1L) - return (list (x = x, levels = levels)) - - dx <- sort (unique (diff (levels))) - +fitraster <- function(x, tol = 0.1) { + levels <- sort(unique(x)) + + if (length(levels) == 1L) { + return(list(x = x, levels = levels)) + } + + dx <- sort(unique(diff(levels))) + ## reduce by rounding? - dx <- c (dx [! diff (dx) < tol], tail (dx, 1)) + dx <- c(dx [!diff(dx) < tol], tail(dx, 1)) - dx <- rev (dx) + dx <- rev(dx) max.covered <- 0 - - for (d in dx){ - totry <- order (x) - while (length (totry) > 0L){ - ## cat ("totry: ", totry, "\n") + + for (d in dx) { + totry <- order(x) + while (length(totry) > 0L) { + ## cat ("totry: ", totry, "\n") startx <- x [totry [1]] ## cat ("startx: ", startx, "\n") ## cat ("fit: ", c (startx, d), "\n") - raster <- makeraster (x, startx, d, tol = tol) - tmp <- sum (raster$x %in% raster$levels, na.rm = TRUE) + raster <- makeraster(x, startx, d, tol = tol) + tmp <- sum(raster$x %in% raster$levels, na.rm = TRUE) ## cat (" ", tmp, "\n") if (tmp > max.covered) { max.covered <- tmp fit <- raster } - - if (max.covered == length (x)) + + if (max.covered == length(x)) { break + } - totry <- totry [! raster$x [totry] %in% raster$levels] - } + totry <- totry [!raster$x [totry] %in% raster$levels] + } } - + fit } diff --git a/hyperSpec/R/map.identify.R b/hyperSpec/R/map.identify.R index d6fa48b75..7d1e30cb7 100644 --- a/hyperSpec/R/map.identify.R +++ b/hyperSpec/R/map.identify.R @@ -8,73 +8,81 @@ ##' (i.e. in "npc" \link[grid]{unit}s) ##' @param warn should a warning be issued if no point is within the specified ##' tolerance? See also details. -##' @importFrom grid convertX convertY grid.locator grid.circle gpar +##' @importFrom grid convertX convertY grid.locator grid.circle gpar ##' @importFrom lattice trellis.focus ltext ##' @importFrom utils modifyList -map.identify <- function (object, model = spc ~ x * y, voronoi = FALSE, ..., - tol = .02, warn = TRUE){ - - if (! interactive ()) - stop ("map.identify works only on interactive graphics devices.") - - chk.hy (object) - validObject (object) +map.identify <- function(object, model = spc ~ x * y, voronoi = FALSE, ..., + tol = .02, warn = TRUE) { + if (!interactive()) { + stop("map.identify works only on interactive graphics devices.") + } + + chk.hy(object) + validObject(object) + + dots <- modifyList( + list(object = object, model = model, ...), + list(subscripts = TRUE) + ) - dots <- modifyList (list (object = object, model = model, ...), - list (subscripts = TRUE)) - - if (voronoi) { dots <- modifyList (list (col = "black", border = "#00000080"), dots) - - ## we need to mix the spectra, otherwise the voronoi plot does not work with + if (voronoi) { + dots <- modifyList(list(col = "black", border = "#00000080"), dots) + + ## we need to mix the spectra, otherwise the voronoi plot does not work with ## complete rectangular maps. mix keeps track of the reordering. dots$mix <- FALSE - mix <- sample (nrow (object)) + mix <- sample(nrow(object)) dots$object <- object [mix] - lattice <- do.call (plotvoronoi, dots) - mix <- order (mix) + lattice <- do.call(plotvoronoi, dots) + mix <- order(mix) } else { - lattice <- do.call (plotmap, dots) - mix <- row.seq (object) + lattice <- do.call(plotmap, dots) + mix <- row.seq(object) } - print (lattice) - trellis.focus () + print(lattice) + trellis.focus() - tol = tol^2 + tol <- tol^2 xn <- lattice$panel.args.common$x [mix] yn <- lattice$panel.args.common$y [mix] - x = as.numeric (convertX (unit (xn, "native"), "npc")) - y = as.numeric (convertY (unit (yn, "native"), "npc")) + x <- as.numeric(convertX(unit(xn, "native"), "npc")) + y <- as.numeric(convertY(unit(yn, "native"), "npc")) - debuglevel <- hy.getOption ("debuglevel") + debuglevel <- hy.getOption("debuglevel") - res <- numeric (0) + res <- numeric(0) repeat { - tmp <- grid.locator (unit = "npc") - if (debuglevel == 2L) - grid.circle (tmp[1], tmp[2], sqrt (tol), gp = gpar (col = "red")) + tmp <- grid.locator(unit = "npc") + if (debuglevel == 2L) { + grid.circle(tmp[1], tmp[2], sqrt(tol), gp = gpar(col = "red")) + } - if (is.null (tmp)) + if (is.null(tmp)) { break - - tmp <- as.numeric (tmp) + } + + tmp <- as.numeric(tmp) d2 <- (x - tmp [1])^2 + (y - tmp [2])^2 - pt <- which.min (d2) + pt <- which.min(d2) if (d2 [pt] <= tol) { - res <- c (res, pt) - if (debuglevel >= 1L) - ltext (xn [pt], yn [pt], label = pt) + res <- c(res, pt) + if (debuglevel >= 1L) { + ltext(xn [pt], yn [pt], label = pt) + } } else { if (warn) { - warning ("No point within tolerance (", tol, " = ", - convertX (unit (sqrt (tol), "npc"), "native")," x-units or", - convertY (unit (sqrt (tol), "npc"), "native")," y-units).") - if (debuglevel == 1L) - grid.circle (tmp[1], tmp[2], sqrt (tol), gp = gpar (col = "red")) + warning( + "No point within tolerance (", tol, " = ", + convertX(unit(sqrt(tol), "npc"), "native"), " x-units or", + convertY(unit(sqrt(tol), "npc"), "native"), " y-units)." + ) + if (debuglevel == 1L) { + grid.circle(tmp[1], tmp[2], sqrt(tol), gp = gpar(col = "red")) + } } } } res } - diff --git a/hyperSpec/R/map.sel.poly.R b/hyperSpec/R/map.sel.poly.R index 70271cfae..e5bce5f5d 100644 --- a/hyperSpec/R/map.sel.poly.R +++ b/hyperSpec/R/map.sel.poly.R @@ -1,15 +1,15 @@ ##' Interactively select a polygon (grid graphics) and highlight points ##' ##' Click the points that should be connected as polygon. Input ends with right click (see -##' \code{\link[grid]{grid.locator}}). Polygon will be drawn closed. -##' -##' \code{map.sel.poly} is a convenience wrapper for \code{\link{plotmap}}, \code{sel.poly}, -##' and \code{\link[sp]{point.in.polygon}}. For custiomized plotting, the plot can be produced by -##' \code{\link{plotmap}}, \code{\link{plotvoronoi}} or \code{\link{levelplot}}, and the result of +##' \code{\link[grid]{grid.locator}}). Polygon will be drawn closed. +##' +##' \code{map.sel.poly} is a convenience wrapper for \code{\link{plotmap}}, \code{sel.poly}, +##' and \code{\link[sp]{point.in.polygon}}. For custiomized plotting, the plot can be produced by +##' \code{\link{plotmap}}, \code{\link{plotvoronoi}} or \code{\link{levelplot}}, and the result of ##' that plot command handed over to \code{map.sel.poly}, see the example below. -##' +##' ##' If even more customized plotting is required,\code{sel.poly} should be used (see example). -##' +##' ##' @param data hyperSpec object for plotting map or list returned by \code{\link{plotmap}} ##' @param pch symbol to display the points of the polygon for \code{\link{sel.poly}} ##' @param size size for polygon point symbol for \code{\link{sel.poly}} @@ -25,58 +25,60 @@ ##' if (interactive ()){ ##' ## convenience wrapper ##' map.sel.poly (chondro) -##' +##' ##' ## customized version ##' data <- sample (chondro [,, 1004 - 2i ~ 1004 + 2i], 300) -##' +##' ##' plotdata <- plotvoronoi (data, clusters ~ y * x, col.regions = alois.palette ()) ##' print (plotdata) ##' map.sel.poly (plotdata) -##' +##' ##' ## even more customization: ##' plotvoronoi (data) -##' +##' ##' ## interactively retrieve polygon ##' polygon <- sel.poly () -##' +##' ##' ## find data points within polygon -##' require ("sp") +##' require ("sp") ##' i.sel <- which (point.in.polygon (data$x, data$y, polygon [, 1], polygon [, 2]) > 0) -##' +##' ##' ## work with selected points ##' grid.points (unit (data$x [i.sel], "native"), unit (data$y [i.sel], "native")) ##' } -map.sel.poly <- function (data, pch = 19, size = 0.3, ...){ +map.sel.poly <- function(data, pch = 19, size = 0.3, ...) { + if (!interactive()) { + stop("map.sel.poly works only on interactive graphics devices.") + } - if (! interactive ()) - stop ("map.sel.poly works only on interactive graphics devices.") - - ## sp is only in Suggests, not a strict Dependency. - if (! requireNamespace ("sp")) - stop ("package sp required for point.in.polygon ()") + ## sp is only in Suggests, not a strict Dependency. + if (!requireNamespace("sp")) { + stop("package sp required for point.in.polygon ()") + } - if (is (data, "hyperSpec")) { + if (is(data, "hyperSpec")) { ## plot hyperSpec object - print (plotmap (data)) + print(plotmap(data)) x <- data$x y <- data$y - } else if (is (data, "trellis")) { - + } else if (is(data, "trellis")) { + ## data is list with plotting data of hyperSpec object x <- data$panel.args.common$x y <- data$panel.args.common$y } else { - stop ("data must either be a hyperSpec object or a trellis object as returned by plotmap, plotvoronoi, or levelplot") + stop("data must either be a hyperSpec object or a trellis object as returned by plotmap, plotvoronoi, or levelplot") } - - poly <- sel.poly (pch = pch, size = size, ...) - - pts <- sp::point.in.polygon (x, y, poly [, 1], poly [, 2]) + + poly <- sel.poly(pch = pch, size = size, ...) + + pts <- sp::point.in.polygon(x, y, poly [, 1], poly [, 2]) ind <- pts > 0 - if (! any (ind)) - warning ("Empty selection: no point in polygon.") + if (!any(ind)) { + warning("Empty selection: no point in polygon.") + } ind } @@ -91,36 +93,45 @@ map.sel.poly <- function (data, pch = 19, size = 0.3, ...){ ##' @rdname map-sel-poly ##' @importFrom grid grid.lines grid.points ##' @importFrom utils tail -sel.poly <- function (pch = 19, size = 0.3, ...){ - if (! interactive ()) - stop ("sel.poly works only on interactive graphics devices.") - - trellis.focus () - - pts <- matrix (NA, nrow = 0, ncol = 2) - +sel.poly <- function(pch = 19, size = 0.3, ...) { + if (!interactive()) { + stop("sel.poly works only on interactive graphics devices.") + } + + trellis.focus() + + pts <- matrix(NA, nrow = 0, ncol = 2) + repeat { - pt <- grid.locator (unit="native") - if (!is.null (pt)){ - pts <- rbind (pts, as.numeric (pt)) # comparably few executions: low performance doesn't matter - + pt <- grid.locator(unit = "native") + if (!is.null(pt)) { + pts <- rbind(pts, as.numeric(pt)) # comparably few executions: low performance doesn't matter + ## display the clicked point - grid.points (unit (tail (pts [, 1], 1), "native"), - unit (tail (pts [, 2], 1), "native"), pch = pch, - size = unit (size, "char"), gp = gpar (...)) - + grid.points(unit(tail(pts [, 1], 1), "native"), + unit(tail(pts [, 2], 1), "native"), + pch = pch, + size = unit(size, "char"), gp = gpar(...) + ) + ## connect last 2 points by line - if (nrow (pts) > 1L) - grid.lines (unit (tail (pts [, 1L], 2L) , "native"), - unit (tail (pts [, 2L], 2L) , "native"), gp = gpar (...)) + if (nrow(pts) > 1L) { + grid.lines(unit(tail(pts [, 1L], 2L), "native"), + unit(tail(pts [, 2L], 2L), "native"), + gp = gpar(...) + ) + } } else { ## visually close polygon (if at least 3 pts) - if (nrow (pts) > 2L) - grid.lines (unit (c (tail (pts [, 1L], 1L), pts [1L, 1L]), "native"), - unit (c (tail (pts [, 2L], 1L), pts [1L, 2L]), "native"), gp = gpar (...)) - break + if (nrow(pts) > 2L) { + grid.lines(unit(c(tail(pts [, 1L], 1L), pts [1L, 1L]), "native"), + unit(c(tail(pts [, 2L], 1L), pts [1L, 2L]), "native"), + gp = gpar(...) + ) + } + break } } - + pts } diff --git a/hyperSpec/R/mark.dendrogram.R b/hyperSpec/R/mark.dendrogram.R index 1615ec6ee..63db67cd6 100644 --- a/hyperSpec/R/mark.dendrogram.R +++ b/hyperSpec/R/mark.dendrogram.R @@ -1,6 +1,6 @@ ##' Groups are marked by colored rectangles as well as by their levels. ##' -##' The dendrogram should be plotted separately, see the example. +##' The dendrogram should be plotted separately, see the example. ##' @title Mark groups in \code{\link[stats]{hclust}} dendrograms ##' @param dendrogram the dendrogram ##' @param groups factor giving the the groups to mark @@ -17,57 +17,65 @@ ##' @export ##' @rdname mark.dendrogram ##' @examples -##' +##' ##' dend <- hclust (pearson.dist (laser[[]])) ##' par (xpd = TRUE, mar = c (5.1, 4, 4, 3)) # allows plotting into the margin ##' plot (dend, hang = -1, labels = FALSE) -##' +##' ##' ## mark clusters ##' clusters <- as.factor (cutree (dend, k = 4)) ##' levels (clusters) <- LETTERS [1 : 4] ##' mark.dendrogram (dend, clusters, label = "cluster") -##' +##' ##' ## mark independent factor ##' mark.dendrogram (dend, as.factor (laser [,,405.36] > 11000), ##' pos.marker = -0.02, pos.text = - 0.03) -##' +##' ##' ## mark continuous variable: convert it to a factor and omit labels ##' mark.dendrogram (dend, cut (laser [[,, 405.36]], 100), alois.palette (100), ##' pos.marker = -.015, text.col = NA, ##' label = expression (I [lambda == 405.36~nm]), label.right = FALSE) -##' +##' ##' @importFrom utils head tail -mark.dendrogram <- function (dendrogram, groups, col = seq_along (unique (groups)), - pos.marker = 0, - height = 0.025 * max (dendrogram$height), - pos.text = -2.5 * height, - border = NA, text.col = "black", label, label.right = TRUE, - ...){ - if (! is.factor (groups)) - groups <- as.factor (groups) - +mark.dendrogram <- function(dendrogram, groups, col = seq_along(unique(groups)), + pos.marker = 0, + height = 0.025 * max(dendrogram$height), + pos.text = -2.5 * height, + border = NA, text.col = "black", label, label.right = TRUE, + ...) { + if (!is.factor(groups)) { + groups <- as.factor(groups) + } + groups.x <- groups [dendrogram$order] # clusters in order on x axis - - rle.groups <- rle (as.integer (groups.x)) # run-length encoding gives borders - - end <- cumsum (rle.groups$lengths) + 0.5 - start <- c (0.5, (head (end, -1))) - text <- (start + end) / 2 - text.col <- rep (text.col, length.out = length (text)) - - for (g in seq_along (rle.groups$lengths)){ - rect (xleft = start [g], ybottom = pos.marker - height, - xright = end [g], ytop = pos.marker, - col = col [rle.groups$values[g]], border = border, ...) - if (! is.na (text.col [g])) - text (x = text [g], y = pos.text, - levels (groups) [rle.groups$values [g]], - col = text.col [rle.groups$values [g]], ...) + rle.groups <- rle(as.integer(groups.x)) # run-length encoding gives borders + + end <- cumsum(rle.groups$lengths) + 0.5 + start <- c(0.5, (head(end, -1))) + text <- (start + end) / 2 + + text.col <- rep(text.col, length.out = length(text)) + + for (g in seq_along(rle.groups$lengths)) { + rect( + xleft = start [g], ybottom = pos.marker - height, + xright = end [g], ytop = pos.marker, + col = col [rle.groups$values[g]], border = border, ... + ) + if (!is.na(text.col [g])) { + text( + x = text [g], y = pos.text, + levels(groups) [rle.groups$values [g]], + col = text.col [rle.groups$values [g]], ... + ) + } } - if (! missing (label)) - text (x = label.right * tail (end, 1) * 1.01, y = pos.marker - height/2, - label, adj = c(1 - label.right, .5)) - + if (!missing(label)) { + text( + x = label.right * tail(end, 1) * 1.01, y = pos.marker - height / 2, + label, adj = c(1 - label.right, .5) + ) + } } diff --git a/hyperSpec/R/mark.peak.R b/hyperSpec/R/mark.peak.R index a9937470a..c1c211d11 100644 --- a/hyperSpec/R/mark.peak.R +++ b/hyperSpec/R/mark.peak.R @@ -1,24 +1,25 @@ ##' Mark peak -##' +##' ##' Marks location of the \emph{first} spectrum at the data point closest to the ##' specified position on the current plot. -##' +##' ##' @param spc the \code{hyperSpec} object ##' @param xpos position of the peak(s) in current x-axis units ##' @param col color of the markers and text -##' -##' +##' +##' ##' @author R. Kiselev ##' @export -##' @examples +##' @examples ##' plot (chondro [7]) ##' markpeak (chondro [7], 1662) -markpeak <- function(spc, xpos, col="red"){ +markpeak <- function(spc, xpos, col = "red") { + chk.hy(spc) + validObject(spc) - chk.hy (spc) - validObject (spc) - - plot(spc[1,,xpos], add=T, lines.args=list(type="p"), col=col) - text(x=xpos, y=spc[[1,,xpos]], col=col, labels=sprintf("<- %.1f", xpos), - adj=c(-0.2,0.37), srt=90, cex=0.75) + plot(spc[1, , xpos], add = T, lines.args = list(type = "p"), col = col) + text( + x = xpos, y = spc[[1, , xpos]], col = col, labels = sprintf("<- %.1f", xpos), + adj = c(-0.2, 0.37), srt = 90, cex = 0.75 + ) } diff --git a/hyperSpec/R/matlab.palette.R b/hyperSpec/R/matlab.palette.R index c5453e95a..d8fcf0318 100644 --- a/hyperSpec/R/matlab.palette.R +++ b/hyperSpec/R/matlab.palette.R @@ -2,8 +2,8 @@ ##' Two palettes going from blue over green to red, approximately as the ##' standard palette of Matlab does. The second one has darker green values and ##' is better suited for plotting lines on white background. -##' -##' +##' +##' ##' @rdname palettes ##' @aliases matlab.palette ##' @param n the number of colors to be in the palette. @@ -16,34 +16,34 @@ ##' @importFrom grDevices rainbow ##' @keywords color ##' @examples -##' +##' ##' plotmap (chondro [,, 778], col.regions = matlab.palette ()) -##' -matlab.palette <- function (n = 100, ...) { - rev (rainbow (n, start = 0, end = 4/6, ...)) +##' +matlab.palette <- function(n = 100, ...) { + rev(rainbow(n, start = 0, end = 4 / 6, ...)) } ##' @rdname palettes ##' @aliases matlab.dark.palette ##' @export ##' @examples -##' +##' ##' plot (flu, col = matlab.dark.palette (nrow (flu))) ##' @importFrom grDevices col2rgb rgb -matlab.dark.palette <- function (n = 100, ...) { - pal <- rev (rainbow (n, start = 0, end = 4/6, ...)) +matlab.dark.palette <- function(n = 100, ...) { + pal <- rev(rainbow(n, start = 0, end = 4 / 6, ...)) pal <- col2rgb(pal) - pal ["green",] <- pal ["green",] / 2 + pal ["green", ] <- pal ["green", ] / 2 - rgb (t (pal)/255) + rgb(t(pal) / 255) } ##' @rdname palettes ##' @export ##' @examples -##' +##' ##' plotmap (chondro, col = alois.palette) ##' @importFrom grDevices colorRampPalette -alois.palette <- function (n = 100, ...) { - colorRampPalette(c("black", "blue","cyan", "green", "yellow", "red"), ...) (n) +alois.palette <- function(n = 100, ...) { + colorRampPalette(c("black", "blue", "cyan", "green", "yellow", "red"), ...)(n) } diff --git a/hyperSpec/R/mean_sd.R b/hyperSpec/R/mean_sd.R index 6ee629566..00fe153ea 100644 --- a/hyperSpec/R/mean_sd.R +++ b/hyperSpec/R/mean_sd.R @@ -1,15 +1,15 @@ ## make generic functions without default ##' @noRd -setGeneric ("mean_sd", function (x, na.rm = TRUE, ...) standardGeneric ("mean_sd")) +setGeneric("mean_sd", function(x, na.rm = TRUE, ...) standardGeneric("mean_sd")) ##' @noRd -setGeneric ("mean_pm_sd", function (x, na.rm = TRUE, ...) standardGeneric ("mean_pm_sd")) +setGeneric("mean_pm_sd", function(x, na.rm = TRUE, ...) standardGeneric("mean_pm_sd")) ##' Mean and Standard Deviation ##' Calculate mean and standard deviation, and mean, mean \eqn{\pm}{+-} one ##' standard deviation, respectively. -##' +##' ##' These functions are provided for convenience. -##' +##' ##' @aliases mean_sd ##' @rdname mean_sd ##' @param x a numeric vector @@ -21,28 +21,32 @@ setGeneric ("mean_pm_sd", function (x, na.rm = TRUE, ...) standardGeneric ("mean ##' @keywords multivar ##' @export ##' @examples -##' +##' ##' mean_sd (flu [,, 405 ~ 410]) -setMethod ("mean_sd", signature = signature (x = "numeric"), - function (x, na.rm = TRUE, ...) { - c (mean = mean (x, na.rm = na.rm), - sd = sd (x, na.rm = na.rm) - ) - } - ) +setMethod("mean_sd", + signature = signature(x = "numeric"), + function(x, na.rm = TRUE, ...) { + c( + mean = mean(x, na.rm = na.rm), + sd = sd(x, na.rm = na.rm) + ) + } +) ##' @rdname mean_sd ##' @return \code{mean_sd (matrix)} returns a matrix with the mean spectrum in the first row and the standard deviation in the 2nd. ##' @export ##' @examples -##' +##' ##' mean_sd (flu$spc) -setMethod ("mean_sd", signature = signature (x = "matrix"), - function (x, na.rm = TRUE, ...) { - m <- colMeans (x, na.rm = na.rm) - s <- apply (x, 2, sd, na.rm = na.rm) - rbind (mean = m, sd = s) - }) +setMethod("mean_sd", + signature = signature(x = "matrix"), + function(x, na.rm = TRUE, ...) { + m <- colMeans(x, na.rm = na.rm) + s <- apply(x, 2, sd, na.rm = na.rm) + rbind(mean = m, sd = s) + } +) ##' @rdname mean_sd ##' @return \code{mean_sd} returns a hyperSpec object with the mean spectrum in the first row and the standard deviation in the 2nd. @@ -51,70 +55,78 @@ setMethod ("mean_sd", signature = signature (x = "matrix"), ##' @keywords univar ##' @export ##' @examples -##' +##' ##' mean_sd (flu) -setMethod ("mean_sd", signature = signature (x = "hyperSpec"), - function (x, na.rm = TRUE, ...) { - decomposition (x, mean_sd (x@data$spc), scores = FALSE) - }) +setMethod("mean_sd", + signature = signature(x = "hyperSpec"), + function(x, na.rm = TRUE, ...) { + decomposition(x, mean_sd(x@data$spc), scores = FALSE) + } +) ##' @aliases mean_pm_sd ##' @rdname mean_sd ##' @return -##' +##' ##' \code{mean_pm_sd} returns a vector with 3 values: mean - 1 sd, mean, mean + 1 sd ##' @export ##' @examples -##' +##' ##' mean_pm_sd (flu$c) -setMethod ("mean_pm_sd", signature = signature (x = "numeric"), - function (x, na.rm = TRUE, ...){ - m <- mean (x, na.rm = na.rm) - s <- sd (x, na.rm = na.rm) - c("mean.minus.sd" = m - s, "mean" = m, "mean.plus.sd" = m + s) - }) +setMethod("mean_pm_sd", + signature = signature(x = "numeric"), + function(x, na.rm = TRUE, ...) { + m <- mean(x, na.rm = na.rm) + s <- sd(x, na.rm = na.rm) + c("mean.minus.sd" = m - s, "mean" = m, "mean.plus.sd" = m + s) + } +) ##' @rdname mean_sd ##' @return \code{mean_pm_sd (matrix)} returns a matrix containing mean - sd, mean, and mean + sd ##' rows. ##' @export ##' @examples -##' +##' ##' mean_pm_sd (flu$spc) -setMethod ("mean_pm_sd", signature = signature (x = "matrix"), - function (x, na.rm = TRUE, ...) { - m <- colMeans (x, na.rm = na.rm) - s <- apply (x, 2, sd, na.rm = na.rm) - rbind ("mean - sd" = m - s, mean = m, "mean + sd"= m + s) - }) +setMethod("mean_pm_sd", + signature = signature(x = "matrix"), + function(x, na.rm = TRUE, ...) { + m <- colMeans(x, na.rm = na.rm) + s <- apply(x, 2, sd, na.rm = na.rm) + rbind("mean - sd" = m - s, mean = m, "mean + sd" = m + s) + } +) ##' @rdname mean_sd ##' @return For hyperSpec objects, \code{mean_pm_sd} returns a hyperSpec object containing mean - sd, ##' mean, and mean + sd spectra. ##' @export ##' @examples -##' +##' ##' mean_pm_sd (flu) -setMethod ("mean_pm_sd", signature = signature (x = "hyperSpec"), - function (x, na.rm = TRUE, ...) { - decomposition (x, mean_pm_sd (x@data$spc)) - }) +setMethod("mean_pm_sd", + signature = signature(x = "hyperSpec"), + function(x, na.rm = TRUE, ...) { + decomposition(x, mean_pm_sd(x@data$spc)) + } +) ##' @rdname mean_sd ##' @return For hyperSpec object, \code{mean} returns a hyperSpec object containing the mean ##' spectrum. ##' @export ##' @examples -##' +##' ##' plot (mean (chondro)) -setMethod ("mean", signature = signature (x = "hyperSpec"), - function (x, na.rm = TRUE, ...){ - m <- structure (colMeans (x@data$spc), - dim = c (1, length (x@wavelength)), - dimnames = list ("mean", NULL)) - decomposition (x, m) - }) - - - +setMethod("mean", + signature = signature(x = "hyperSpec"), + function(x, na.rm = TRUE, ...) { + m <- structure(colMeans(x@data$spc), + dim = c(1, length(x@wavelength)), + dimnames = list("mean", NULL) + ) + decomposition(x, m) + } +) diff --git a/hyperSpec/R/merge.R b/hyperSpec/R/merge.R index 84113aa06..779a22dcd 100644 --- a/hyperSpec/R/merge.R +++ b/hyperSpec/R/merge.R @@ -55,146 +55,147 @@ ##' ## merging hyperSpec object into data.frame => data.frame ##' merge (y, flu) -setMethod ("merge", signature = signature (x = "hyperSpec", y = "hyperSpec"), - function (x, y, ...){ - validObject (x) - validObject (y) +setMethod("merge", + signature = signature(x = "hyperSpec", y = "hyperSpec"), + function(x, y, ...) { + validObject(x) + validObject(y) - tmp <- .merge (x, y, ...) + tmp <- .merge(x, y, ...) - if (nrow (tmp) == 0 && nrow (x) > 0 && nrow (y) > 0) - warning ("Merge results in 0 spectra.") + if (nrow(tmp) == 0 && nrow(x) > 0 && nrow(y) > 0) { + warning("Merge results in 0 spectra.") + } - tmp - } - ) + tmp + } +) -.merge <- function (x, y, - by = setdiff (intersect(colnames(x), colnames(y)), "spc"), - by.x = by, by.y = by, - ...){ - force (by) - force (by.x) - force (by.y) +.merge <- function(x, y, + by = setdiff(intersect(colnames(x), colnames(y)), "spc"), + by.x = by, by.y = by, + ...) { + force(by) + force(by.x) + force(by.y) - if (any (grepl ("^spc$", by.x))){ - by.x <- setdiff (by.x, "spc") - warning ('"spc" removed from by.x') + if (any(grepl("^spc$", by.x))) { + by.x <- setdiff(by.x, "spc") + warning('"spc" removed from by.x') } - if (any (grepl ("^spc$", by.y))){ - by.y <- setdiff (by.y, "spc") - warning ('"spc" removed from by.y') + if (any(grepl("^spc$", by.y))) { + by.y <- setdiff(by.y, "spc") + warning('"spc" removed from by.y') } - x$.nx <- seq_len (nrow (x)) - y$.ny <- seq_len (nrow (y)) + x$.nx <- seq_len(nrow(x)) + y$.ny <- seq_len(nrow(y)) - x.spc <- match ("spc", colnames (x)) - y.spc <- match ("spc", colnames (y)) + x.spc <- match("spc", colnames(x)) + y.spc <- match("spc", colnames(y)) - tmp <- merge (x@data [, -x.spc], y@data [, -y.spc], by.x = by.x, by.y = by.y, ...) + tmp <- merge(x@data [, -x.spc], y@data [, -y.spc], by.x = by.x, by.y = by.y, ...) - spc.x <- matrix (NA, nrow = nrow (tmp), ncol = nwl (x)) - spc.x [! is.na (tmp$.nx),] <- x@data [tmp$.nx[! is.na (tmp$.nx)], x.spc] + spc.x <- matrix(NA, nrow = nrow(tmp), ncol = nwl(x)) + spc.x [!is.na(tmp$.nx), ] <- x@data [tmp$.nx[!is.na(tmp$.nx)], x.spc] - spc.y <- matrix (NA, nrow = nrow (tmp), ncol = nwl (y)) - spc.y [! is.na (tmp$.ny),] <- y@data [tmp$.ny[! is.na (tmp$.ny)], y.spc] + spc.y <- matrix(NA, nrow = nrow(tmp), ncol = nwl(y)) + spc.y [!is.na(tmp$.ny), ] <- y@data [tmp$.ny[!is.na(tmp$.ny)], y.spc] - tmp$spc <- cbind (spc.x, spc.y) # omit I () + tmp$spc <- cbind(spc.x, spc.y) # omit I () x@data <- tmp - .wl (x) <- c (x@wavelength, y@wavelength) + .wl(x) <- c(x@wavelength, y@wavelength) x } ##' @rdname merge -setMethod ("merge", signature = signature (x = "hyperSpec", y = "data.frame"), - function (x, y, ...){ - validObject (x) +setMethod("merge", + signature = signature(x = "hyperSpec", y = "data.frame"), + function(x, y, ...) { + validObject(x) - tmp <- merge (x@data, y, ...) - tmp - if (nrow (tmp) == 0 && nrow (x) > 0 && nrow (y) > 0) - warning ("Merge results in 0 spectra.") + tmp <- merge(x@data, y, ...) + tmp + if (nrow(tmp) == 0 && nrow(x) > 0 && nrow(y) > 0) { + warning("Merge results in 0 spectra.") + } - x@data <- tmp + x@data <- tmp - x - } + x + } ) ##' @rdname merge -setMethod ("merge", signature = signature (x = "data.frame", y = "hyperSpec"), - function (x, y, ...){ - validObject (y) +setMethod("merge", + signature = signature(x = "data.frame", y = "hyperSpec"), + function(x, y, ...) { + validObject(y) - merge (x, y@data, ...) - } + merge(x, y@data, ...) + } ) ##' @include unittest.R -.test (.merge) <- function (){ - context ("merge") +.test(.merge) <- function() { + context("merge") - test_that ("correct number of rows", { - expect_equivalent (nrow (merge (chondro [1:10], chondro [5:15], all = TRUE)), 15) - expect_equivalent (nrow (merge (chondro [1:10], chondro [5:15])), 6) + test_that("correct number of rows", { + expect_equivalent(nrow(merge(chondro [1:10], chondro [5:15], all = TRUE)), 15) + expect_equivalent(nrow(merge(chondro [1:10], chondro [5:15])), 6) }) test_that("merging hyperSpec object with data.frame", { ## y has multiple rows for each x row - y <- data.frame (filename = rep (flu$filename, 2), cpred = 1:12) - tmp <- merge (flu, y) + y <- data.frame(filename = rep(flu$filename, 2), cpred = 1:12) + tmp <- merge(flu, y) expect_s4_class(tmp, "hyperSpec") - expect_equivalent (nrow (tmp), 12L) - expect_equivalent (sort (unique (c (colnames (flu), colnames (y)))), sort (colnames (tmp))) + expect_equivalent(nrow(tmp), 12L) + expect_equivalent(sort(unique(c(colnames(flu), colnames(y)))), sort(colnames(tmp))) ## y has rows x does not have - tmp <- merge (flu [1:2], y) - expect_equivalent (nrow (tmp), 4L) + tmp <- merge(flu [1:2], y) + expect_equivalent(nrow(tmp), 4L) ## all.y = TRUE - tmp <- merge (flu [1:2], y, all.y = TRUE) - expect_equivalent (nrow (tmp), 12L) - expect_equivalent(sum (is.na (tmp$c)), 8) + tmp <- merge(flu [1:2], y, all.y = TRUE) + expect_equivalent(nrow(tmp), 12L) + expect_equivalent(sum(is.na(tmp$c)), 8) ## x has rows y does not have - tmp <- merge (flu, y [1:2,]) - expect_equivalent (nrow (tmp), 2L) + tmp <- merge(flu, y [1:2, ]) + expect_equivalent(nrow(tmp), 2L) ## all.x = TRUE - tmp <- merge (flu, y [c (1,7),], all.x = TRUE) - expect_equivalent (nrow (tmp), 7L) - expect_equivalent(sum (is.na (tmp$cpred)), 5) + tmp <- merge(flu, y [c(1, 7), ], all.x = TRUE) + expect_equivalent(nrow(tmp), 7L) + expect_equivalent(sum(is.na(tmp$cpred)), 5) }) test_that("merge hyperSpec object with tibble", { - skip_if_not (requireNamespace ("tibble", quietly = TRUE)) - y <- data.frame (filename = rep (flu$filename, 2), cpred = 1:12) - y <- tibble::as_tibble (y) + skip_if_not(requireNamespace("tibble", quietly = TRUE)) + y <- data.frame(filename = rep(flu$filename, 2), cpred = 1:12) + y <- tibble::as_tibble(y) - tmp <- merge (flu, y) - expect_equivalent (nrow (tmp), 12L) - expect_equivalent (sort (unique (c (colnames (flu), colnames (y)))), sort (colnames (tmp))) + tmp <- merge(flu, y) + expect_equivalent(nrow(tmp), 12L) + expect_equivalent(sort(unique(c(colnames(flu), colnames(y)))), sort(colnames(tmp))) }) test_that("merge hyperSpec object into data.frame", { - - y <- data.frame (filename = rep (flu$filename, 2), cpred = 1:12) - tmp <- merge (y, flu) + y <- data.frame(filename = rep(flu$filename, 2), cpred = 1:12) + tmp <- merge(y, flu) expect_s3_class(tmp, "data.frame") - }) } - - diff --git a/hyperSpec/R/mvtnorm.R b/hyperSpec/R/mvtnorm.R index 2700bd8ca..ad068cabd 100644 --- a/hyperSpec/R/mvtnorm.R +++ b/hyperSpec/R/mvtnorm.R @@ -1,30 +1,31 @@ -.rmmvnorm <- function (n, mean, sigma) { - - if (! requireNamespace("mvtnorm")) - stop ("package 'mvtnorm' needed to generate multivariate normal random data.") - - .group <- rep.int (seq_along (n), n) +.rmmvnorm <- function(n, mean, sigma) { + if (!requireNamespace("mvtnorm")) { + stop("package 'mvtnorm' needed to generate multivariate normal random data.") + } + + .group <- rep.int(seq_along(n), n) - ## make indices so that pooled or individual covariance matrices can be used. - if (length (dim (sigma)) == 3L) - isigma <- seq_len (dim (sigma) [3]) - else { - isigma <- rep (1L, nrow (mean)) - dim (sigma) <- c (dim (sigma), 1L) + ## make indices so that pooled or individual covariance matrices can be used. + if (length(dim(sigma)) == 3L) { + isigma <- seq_len(dim(sigma) [3]) + } else { + isigma <- rep(1L, nrow(mean)) + dim(sigma) <- c(dim(sigma), 1L) } - tmp <- matrix (NA_real_, sum (n), ncol (mean)) - for (i in seq_along (n)) - tmp [.group == i,] <- mvtnorm::rmvnorm (n [i], mean [i,], sigma [,, isigma [i]]) + tmp <- matrix(NA_real_, sum(n), ncol(mean)) + for (i in seq_along(n)) { + tmp [.group == i, ] <- mvtnorm::rmvnorm(n [i], mean [i, ], sigma [, , isigma [i]]) + } - attr (tmp, "group") <- .group + attr(tmp, "group") <- .group tmp } ##' @export ##' @name rmmvnorm -setGeneric ("rmmvnorm", .rmmvnorm) +setGeneric("rmmvnorm", .rmmvnorm) ##' Multivariate normal random numbers @@ -47,50 +48,58 @@ setGeneric ("rmmvnorm", .rmmvnorm) ##' @docType methods ##' @examples ##' ## multiple groups, common covariance matrix -##' +##' ##' if (require ("mvtnorm")){ ##' pcov <- pooled.cov (chondro, chondro$clusters) ##' rnd <- rmmvnorm (rep (10, 3), mean = pcov$mean, sigma = pcov$COV) ##' plot (rnd, col = rnd$.group) ##' } -setMethod ("rmmvnorm", signature (n = "numeric", mean = "hyperSpec", sigma = "matrix"), - function (n, mean, sigma){ - tmp <- .rmmvnorm (n, mean@data$spc, sigma) +setMethod( + "rmmvnorm", signature(n = "numeric", mean = "hyperSpec", sigma = "matrix"), + function(n, mean, sigma) { + tmp <- .rmmvnorm(n, mean@data$spc, sigma) - data <- mean [attr (tmp, "group"),, drop = FALSE] - if (hy.getOption ("gc")) gc () - data@data$spc <- tmp - if (hy.getOption ("gc")) gc () - data$.group <- attr (tmp, "group") - if (hy.getOption ("gc")) gc () - data - }) + data <- mean [attr(tmp, "group"), , drop = FALSE] + if (hy.getOption("gc")) gc() + data@data$spc <- tmp + if (hy.getOption("gc")) gc() + data$.group <- attr(tmp, "group") + if (hy.getOption("gc")) gc() + data + } +) ##' @rdname rmmvnorm ##' @export -setMethod ("rmmvnorm", signature (n = "numeric", mean = "hyperSpec", sigma = "array"), - function (n, mean, sigma){ - tmp <- .rmmvnorm (n, mean@data$spc, sigma) +setMethod( + "rmmvnorm", signature(n = "numeric", mean = "hyperSpec", sigma = "array"), + function(n, mean, sigma) { + tmp <- .rmmvnorm(n, mean@data$spc, sigma) - data <- mean [attr (tmp, "group"),, drop = FALSE] - if (hy.getOption ("gc")) gc () - data@data$spc <- tmp - if (hy.getOption ("gc")) gc () - data$.group <- attr (tmp, "group") - if (hy.getOption ("gc")) gc () - data - }) + data <- mean [attr(tmp, "group"), , drop = FALSE] + if (hy.getOption("gc")) gc() + data@data$spc <- tmp + if (hy.getOption("gc")) gc() + data$.group <- attr(tmp, "group") + if (hy.getOption("gc")) gc() + data + } +) ##' @rdname rmmvnorm ##' @export -setMethod ("rmmvnorm", signature (n = "numeric", mean = "matrix", sigma = "matrix"), - .rmmvnorm) +setMethod( + "rmmvnorm", signature(n = "numeric", mean = "matrix", sigma = "matrix"), + .rmmvnorm +) ##' @rdname rmmvnorm ##' @export -setMethod ("rmmvnorm", signature (n = "numeric", mean = "matrix", sigma = "array"), - .rmmvnorm) +setMethod( + "rmmvnorm", signature(n = "numeric", mean = "matrix", sigma = "array"), + .rmmvnorm +) -## produces matrices instead of hyperSpec objects. +## produces matrices instead of hyperSpec objects. ## mapply (rmvnorm, n = 1:3, mean = pcov$mean, MoreArgs= list (sigma = pcov$COV), SIMPLIFY = FALSE)) diff --git a/hyperSpec/R/normalize01.R b/hyperSpec/R/normalize01.R index f1299386d..d8f75f715 100644 --- a/hyperSpec/R/normalize01.R +++ b/hyperSpec/R/normalize01.R @@ -12,79 +12,82 @@ ##' @author C. Beleites ##' @seealso \code{\link[hyperSpec]{wl.eval}}, \code{\link[hyperSpec]{vanderMonde}} ##' @export -setGeneric ("normalize01", function (x, ...) standardGeneric ("normalize01")) +setGeneric("normalize01", function(x, ...) standardGeneric("normalize01")) ##' @export ##' @rdname normalize01 -setMethod (normalize01, signature (x = "matrix"), - function (x, tolerance = hy.getOption ("tolerance")){ - m <- apply (x, 1, min) - x <- sweep (x, 1, m, `-`) - m <- apply (x, 1, max) - x <- sweep (x, 1, m, `/`) - x [m < tolerance, ] <- 1 - x -}) +setMethod( + normalize01, signature(x = "matrix"), + function(x, tolerance = hy.getOption("tolerance")) { + m <- apply(x, 1, min) + x <- sweep(x, 1, m, `-`) + m <- apply(x, 1, max) + x <- sweep(x, 1, m, `/`) + x [m < tolerance, ] <- 1 + x + } +) ##' @export ##' @rdname normalize01 -setMethod ("normalize01", signature (x = "numeric"), function (x, tolerance = hy.getOption ("tolerance")){ - x <- x - min (x) +setMethod("normalize01", signature(x = "numeric"), function(x, tolerance = hy.getOption("tolerance")) { + x <- x - min(x) - m <- max (x) - if (m < tolerance) - rep (1, length (x)) - else + m <- max(x) + if (m < tolerance) { + rep(1, length(x)) + } else { x / m + } }) ##' @export ##' @rdname normalize01 -setMethod (normalize01, signature (x = "hyperSpec"), function (x, ...){ - validObject (x) +setMethod(normalize01, signature(x = "hyperSpec"), function(x, ...) { + validObject(x) - x@data$spc <- normalize01 (unclass (x@data$spc), ...) + x@data$spc <- normalize01(unclass(x@data$spc), ...) ## logbook x }) ##' @include unittest.R -.test (normalize01) <- function (){ - context ("normalize01") +.test(normalize01) <- function() { + context("normalize01") test_that("random numbers", { - x <- runif (10, min = -1e3, max = 1e3) - tmp.x <- normalize01 (x) + x <- runif(10, min = -1e3, max = 1e3) + tmp.x <- normalize01(x) - expect_equivalent (min (normalize01 (x)), 0) - expect_equivalent (max (normalize01 (x)), 1) + expect_equivalent(min(normalize01(x)), 0) + expect_equivalent(max(normalize01(x)), 1) - expect_equivalent (normalize01 (x), (x - min (x)) / diff (range (x))) + expect_equivalent(normalize01(x), (x - min(x)) / diff(range(x))) }) test_that("0, 1, constant", { - expect_equivalent (normalize01 (1), 1) - expect_equivalent (normalize01 (0), 1) - expect_equivalent (normalize01 (5), 1) - expect_equivalent (normalize01 (rep (5, 3L)), rep (1, 3L)) + expect_equivalent(normalize01(1), 1) + expect_equivalent(normalize01(0), 1) + expect_equivalent(normalize01(5), 1) + expect_equivalent(normalize01(rep(5, 3L)), rep(1, 3L)) }) test_that("matrix method", { - m <- matrix (runif (12), 3) + m <- matrix(runif(12), 3) m [3, ] <- 7 - tmp.m <- normalize01 (m) + tmp.m <- normalize01(m) - expect_equal (apply (tmp.m, 1, max), c (1, 1, 1)) - expect_equal (apply (tmp.m, 1, min), c (0, 0, 1)) + expect_equal(apply(tmp.m, 1, max), c(1, 1, 1)) + expect_equal(apply(tmp.m, 1, min), c(0, 0, 1)) }) test_that("hyperSpec method", { - tmp.hy <- normalize01 (-vanderMonde (flu, 1)) + tmp.hy <- normalize01(-vanderMonde(flu, 1)) - expect_equal (apply (tmp.hy [[]], 1, min), 1 : 0) - expect_equal (apply (tmp.hy [[]], 1, max), c (1, 1)) + expect_equal(apply(tmp.hy [[]], 1, min), 1:0) + expect_equal(apply(tmp.hy [[]], 1, max), c(1, 1)) }) } diff --git a/hyperSpec/R/options.R b/hyperSpec/R/options.R index 0121db8ca..5d3a9ebc1 100644 --- a/hyperSpec/R/options.R +++ b/hyperSpec/R/options.R @@ -1,14 +1,15 @@ -.options <- list (debuglevel = 0L, - gc = FALSE, - file.remove.emptyspc = TRUE, - file.keep.name = TRUE, - tolerance = sqrt (.Machine$double.eps), - wl.tolerance = sqrt (.Machine$double.eps), - plot.spc.nmax = 25, - ggplot.spc.nmax = 10 - ) +.options <- list( + debuglevel = 0L, + gc = FALSE, + file.remove.emptyspc = TRUE, + file.keep.name = TRUE, + tolerance = sqrt(.Machine$double.eps), + wl.tolerance = sqrt(.Machine$double.eps), + plot.spc.nmax = 25, + ggplot.spc.nmax = 10 +) ##' Options for package hyperSpec ##' Functions to access and set hyperSpec's options. @@ -48,127 +49,131 @@ ##' ##' hy.getOptions () ##' -hy.getOptions <- function (...){ - dots <- c (...) - if (length (dots) == 0L) +hy.getOptions <- function(...) { + dots <- c(...) + if (length(dots) == 0L) { .options - else - .options [dots] + } else { + .options [dots] + } } ##' @include unittest.R -.test (hy.getOptions) <- function (){ +.test(hy.getOptions) <- function() { context("hy.getOptions") test_that("proper return", { - hy.opts <- get (".options", asNamespace("hyperSpec")) - expect_equal (hy.getOptions (), hy.opts) + hy.opts <- get(".options", asNamespace("hyperSpec")) + expect_equal(hy.getOptions(), hy.opts) - expect_equal (hy.getOptions ("debuglevel"), - hy.opts["debuglevel"]) + expect_equal( + hy.getOptions("debuglevel"), + hy.opts["debuglevel"] + ) - .options <- list () - expect_equal (hy.getOptions (), hy.opts) + .options <- list() + expect_equal(hy.getOptions(), hy.opts) }) } ##' @rdname options ##' @export ##' @param name the name of the option -hy.getOption <- function (name){ +hy.getOption <- function(name) { .options [[name]] } ##' @rdname options ##' @export ##' @importFrom utils modifyList -hy.setOptions <- function (...){ - new <- list (...) +hy.setOptions <- function(...) { + new <- list(...) ## if called with list in 1st argument, use that list - if (length (new) == 1 && is.list (new [[1]])) + if (length(new) == 1 && is.list(new [[1]])) { new <- new [[1]] + } - names <- nzchar (names (new)) + names <- nzchar(names(new)) - if (! all (names) || length (names) != length (new)) - warning ("options without name are discarded: ", which (! names)) + if (!all(names) || length(names) != length(new)) { + warning("options without name are discarded: ", which(!names)) + } - opts <- modifyList (.options, new [names]) + opts <- modifyList(.options, new [names]) - opts$tolerance <- .checkpos (opts$tolerance, "tolerance") - opts$wl.tolerance <- .checkpos (opts$wl.tolerance, "wl.tolerance") + opts$tolerance <- .checkpos(opts$tolerance, "tolerance") + opts$wl.tolerance <- .checkpos(opts$wl.tolerance, "wl.tolerance") - assign(".options", opts, envir = asNamespace ("hyperSpec")) + assign(".options", opts, envir = asNamespace("hyperSpec")) - invisible (opts) + invisible(opts) } ## check particular options that should exist and be finite and strictly positive -.checkpos <- function (opt, name){ - if (length (opt) != 1L || ! is.finite (opt) || opt < .Machine$double.eps){ - warning (name, " must be a strictly positive finite number => set to .Machine$double.eps (", .Machine$double.eps, ").") - opt <- .Machine$double.eps - } +.checkpos <- function(opt, name) { + if (length(opt) != 1L || !is.finite(opt) || opt < .Machine$double.eps) { + warning(name, " must be a strictly positive finite number => set to .Machine$double.eps (", .Machine$double.eps, ").") + opt <- .Machine$double.eps + } - opt + opt } -.test (hy.setOptions) <- function (){ - context ("hy.setOptions") +.test(hy.setOptions) <- function() { + context("hy.setOptions") - old <- hy.getOptions () - on.exit(hy.setOptions (old)) + old <- hy.getOptions() + on.exit(hy.setOptions(old)) test_that("new option and proper return value", { - expect_equal(hy.setOptions (bla = 1)$bla, 1) - expect_equal (hy.getOption ("bla"), 1) + expect_equal(hy.setOptions(bla = 1)$bla, 1) + expect_equal(hy.getOption("bla"), 1) }) test_that("setting", { - tmp <- hy.setOptions (debuglevel = 27) + tmp <- hy.setOptions(debuglevel = 27) expect_equal(tmp$debuglevel, 27) - tmp <- hy.setOptions (list (debuglevel = 20)) + tmp <- hy.setOptions(list(debuglevel = 20)) expect_equal(tmp$debuglevel, 20) - tmp <- hy.setOptions (debuglevel = 27, tolerance = 4) + tmp <- hy.setOptions(debuglevel = 27, tolerance = 4) expect_equal(tmp$debuglevel, 27) expect_equal(tmp$tolerance, 4) - tmp <- hy.setOptions (list (debuglevel = 20, tolerance = 5)) + tmp <- hy.setOptions(list(debuglevel = 20, tolerance = 5)) expect_equal(tmp$debuglevel, 20) expect_equal(tmp$tolerance, 5) }) - test_that ("restrictions on tolerances", { - for (o in c ("tolerance", "wl.tolerance")){ - expect_warning(hy.setOptions (structure (list (0), .Names = o))) - expect_equal(hy.getOption (o), .Machine$double.eps, label = o) + test_that("restrictions on tolerances", { + for (o in c("tolerance", "wl.tolerance")) { + expect_warning(hy.setOptions(structure(list(0), .Names = o))) + expect_equal(hy.getOption(o), .Machine$double.eps, label = o) - hy.setOptions (structure (list (1), .Names = o)) - expect_equal(hy.getOption (o), 1) - expect_warning(hy.setOptions (structure (list (-1), .Names = o))) - expect_equal(hy.getOption (o), .Machine$double.eps, label = o) + hy.setOptions(structure(list(1), .Names = o)) + expect_equal(hy.getOption(o), 1) + expect_warning(hy.setOptions(structure(list(-1), .Names = o))) + expect_equal(hy.getOption(o), .Machine$double.eps, label = o) - hy.setOptions (structure (list (1), .Names = o)) - expect_equal(hy.getOption (o), 1) - expect_warning(hy.setOptions (structure (list (NA), .Names = o))) - expect_equal(hy.getOption (o), .Machine$double.eps, label = o) + hy.setOptions(structure(list(1), .Names = o)) + expect_equal(hy.getOption(o), 1) + expect_warning(hy.setOptions(structure(list(NA), .Names = o))) + expect_equal(hy.getOption(o), .Machine$double.eps, label = o) } - expect_warning(hy.setOptions (tolerance = NULL)) - expect_equal(hy.getOption ("tolerance"), .Machine$double.eps) + expect_warning(hy.setOptions(tolerance = NULL)) + expect_equal(hy.getOption("tolerance"), .Machine$double.eps) - expect_warning(hy.setOptions (wl.tolerance = NULL)) - expect_equal(hy.getOption ("wl.tolerance"), .Machine$double.eps) + expect_warning(hy.setOptions(wl.tolerance = NULL)) + expect_equal(hy.getOption("wl.tolerance"), .Machine$double.eps) }) test_that("options must be named", { - tmp.a <- hy.getOptions () - expect_warning (tmp.b <- hy.setOptions (1)) + tmp.a <- hy.getOptions() + expect_warning(tmp.b <- hy.setOptions(1)) expect_equal(tmp.a, tmp.b) }) - } diff --git a/hyperSpec/R/orderwl.R b/hyperSpec/R/orderwl.R index 4ee8ed357..c9bcddcc4 100644 --- a/hyperSpec/R/orderwl.R +++ b/hyperSpec/R/orderwl.R @@ -2,9 +2,9 @@ ##' Sorting the Wavelengths of a hyperSpec Object ##' Rearranges the \code{hyperSpec} object so that the wavelength vector is in increasing (or ##' decreasing) order. -##' +##' ##' The wavelength vector is sorted and the columns of the spectra matrix are rearranged accordingly. -##' +##' ##' @param x The \code{hyperSpec} object. ##' @param na.last,decreasing Handed to \code{\link[base]{order}}. ##' @return A \code{hyperSpec} object. @@ -12,40 +12,40 @@ ##' @export ##' @seealso \code{\link[base]{order}} ##' @examples -##' +##' ##' ## Example 1: different drawing order in plotspc ##' spc <- new ("hyperSpec", spc = matrix (rnorm (5) + 1:5, ncol = 5)) ##' spc <- cbind (spc, spc+.5) -##' +##' ##' plot (spc, "spc") ##' text (wl (spc), spc [[]], as.character (1:10)) ##' spc <- orderwl (spc) ##' plot (spc, "spc") ##' text (wl (spc), spc [[]], as.character (1:10)) -##' +##' ##' ## Example 2 ##' spc <- new ("hyperSpec", spc = matrix (rnorm (5)*2 + 1:5, ncol = 5)) ##' spc <- cbind (spc, spc) -##' +##' ##' plot (seq_len(nwl(spc)), spc[[]], type = "b") ##' spc[[]] -##' +##' ##' spc <- orderwl (spc) ##' lines (seq_len(nwl(spc)), spc[[]], type = "l", col = "red") ##' spc[[]] -##' -orderwl <- function (x, na.last = TRUE, decreasing = FALSE){ - chk.hy (x) - validObject (x) +##' +orderwl <- function(x, na.last = TRUE, decreasing = FALSE) { + chk.hy(x) + validObject(x) - .orderwl (x) + .orderwl(x) } -.orderwl <- function (x, na.last = TRUE, decreasing = FALSE){ - ord <- order (x@wavelength, na.last = na.last, decreasing = decreasing) +.orderwl <- function(x, na.last = TRUE, decreasing = FALSE) { + ord <- order(x@wavelength, na.last = na.last, decreasing = decreasing) - if (any (ord != seq_along (x@wavelength))){ - x@data$spc <- x@data$spc [, ord, drop = FALSE] + if (any(ord != seq_along(x@wavelength))) { + x@data$spc <- x@data$spc [, ord, drop = FALSE] .wl(x) <- x@wavelength [ord] } diff --git a/hyperSpec/R/paracetamol.R b/hyperSpec/R/paracetamol.R index ab92f3ee6..b0e99096f 100644 --- a/hyperSpec/R/paracetamol.R +++ b/hyperSpec/R/paracetamol.R @@ -1,7 +1,7 @@ ##' Paracetamol Spectrum ##' A Raman spectrum of a paracetamol tablet. -##' -##' +##' +##' ##' @name paracetamol ##' @docType data ##' @format The spectrum was acquired with a Renishaw InVia spectrometer from @@ -10,12 +10,11 @@ ##' @author C. Beleites ##' @keywords datasets ##' @examples -##' +##' ##' paracetamol -##' +##' ##' plot (paracetamol) ##' plotspc (paracetamol, c (min ~ 1750, 2800 ~ max), xoffset = 800, ##' wl.reverse = TRUE) -##' +##' NULL - diff --git a/hyperSpec/R/paste.row.R b/hyperSpec/R/paste.row.R index bca900c15..737d324d2 100644 --- a/hyperSpec/R/paste.row.R +++ b/hyperSpec/R/paste.row.R @@ -1,63 +1,76 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### .paste.row ### ### ##' @importFrom utils head tail -.paste.row <- function (x, label = "", name = "", ins = 0, i = NULL, val = FALSE, - ...){ - .print.val <- function (x, range = TRUE, digits = getOption ("digits"), - max.print = 5, shorten.to = c (2,1)){ - if (is.list (x)){ # also for data.frames - paste ("", "columns/entries", paste (names (x), collapse = ", ")) - } else { - if (length (x) == 0) - return ("") - - if (any (is.na (x))) - text <- "+ NA" - else - text <- "" - - if (range) - x <- sort (unique (as.vector (x))) - else - x <- as.vector (x) - - if (length (x) > max.print){ - from <- format (head (x, shorten.to [1]), digits = digits, trim = TRUE) - to <- format (tail (x, shorten.to [2]), digits = digits, trim = TRUE) - - text <- paste (paste (from, collapse = " "), "...", - paste (to, collapse = " "), text, collapse = " ") - } else { - text <- paste (paste (format (x, digits = digits, trim = TRUE), - collapse = " "), - text, collapse = " ") - } - - paste (if (range) " rng ", text, collapse = "") - - } +.paste.row <- function(x, label = "", name = "", ins = 0, i = NULL, val = FALSE, + ...) { + .print.val <- function(x, range = TRUE, digits = getOption("digits"), + max.print = 5, shorten.to = c(2, 1)) { + if (is.list(x)) { # also for data.frames + paste("", "columns/entries", paste(names(x), collapse = ", ")) + } else { + if (length(x) == 0) { + return("") + } + + if (any(is.na(x))) { + text <- "+ NA" + } else { + text <- "" + } + + if (range) { + x <- sort(unique(as.vector(x))) + } else { + x <- as.vector(x) + } + + if (length(x) > max.print) { + from <- format(head(x, shorten.to [1]), digits = digits, trim = TRUE) + to <- format(tail(x, shorten.to [2]), digits = digits, trim = TRUE) + + text <- paste(paste(from, collapse = " "), "...", + paste(to, collapse = " "), text, + collapse = " " + ) + } else { + text <- paste(paste(format(x, digits = digits, trim = TRUE), + collapse = " " + ), + text, + collapse = " " + ) + } + + paste(if (range) " rng ", text, collapse = "") + } } - - label <- paste (as.character (label), "", collapse = " ") - - paste (paste (rep (" ", ins), collapse = ""), - if (!is.null (i)) paste(i, ". ", collapse = "", sep = ""), - name, - ": ", - label, - "[", - paste (class (x), collapse = ", "), - if (! is.null (dim (x))) - paste (if (is.matrix (x) & all (class (x) != "matrix")) " matrix x " else - if (is.array (x) & all (class (x) != "array") & all (class (x) != "matrix")) - " array x ", - paste (dim (x) [-1], collapse = " x ") - , sep = ""), - "]", - if (val) .print.val (x, ...), - sep ="", collapse = "") + + label <- paste(as.character(label), "", collapse = " ") + + paste(paste(rep(" ", ins), collapse = ""), + if (!is.null(i)) paste(i, ". ", collapse = "", sep = ""), + name, + ": ", + label, + "[", + paste(class(x), collapse = ", "), + if (!is.null(dim(x))) { + paste(if (is.matrix(x) & all(class(x) != "matrix")) { + " matrix x " + } else + if (is.array(x) & all(class(x) != "array") & all(class(x) != "matrix")) { + " array x " + }, + paste(dim(x) [-1], collapse = " x "), + sep = "" + ) + }, + "]", + if (val) .print.val(x, ...), + sep = "", collapse = "" + ) } diff --git a/hyperSpec/R/pearson.dist.R b/hyperSpec/R/pearson.dist.R index 1bf488e4f..9a4f50da8 100644 --- a/hyperSpec/R/pearson.dist.R +++ b/hyperSpec/R/pearson.dist.R @@ -18,34 +18,34 @@ ##' ##' pearson.dist (flu [[]]) ##' pearson.dist (flu) -pearson.dist <- function (x) { - - x <- as.matrix (x) +pearson.dist <- function(x) { + x <- as.matrix(x) ## center & scale *row*s ## (n - 1) factor cancels out between variance scaling and calculating correlation - x <- x - rowMeans (x) - x <- x / sqrt (rowSums (x^2)) + x <- x - rowMeans(x) + x <- x / sqrt(rowSums(x^2)) - if (hy.getOption("gc")) gc () - x <- tcrossprod (x) + if (hy.getOption("gc")) gc() + x <- tcrossprod(x) ## keep only lower triagonal - if (hy.getOption("gc")) gc () - x <- as.dist (x) + if (hy.getOption("gc")) gc() + x <- as.dist(x) - if (hy.getOption("gc")) gc () + if (hy.getOption("gc")) gc() 0.5 - x / 2 } ##' @include unittest.R -.test (pearson.dist) <- function (){ - context ("pearson.dist") +.test(pearson.dist) <- function() { + context("pearson.dist") test_that("pearson.dist against manual calculation", { - expect_equivalent ( - pearson.dist (flu), - as.dist (0.5 - cor (t (as.matrix (flu))) / 2)) + expect_equivalent( + pearson.dist(flu), + as.dist(0.5 - cor(t(as.matrix(flu))) / 2) + ) }) } diff --git a/hyperSpec/R/plot.R b/hyperSpec/R/plot.R index b04792d67..070dfc924 100644 --- a/hyperSpec/R/plot.R +++ b/hyperSpec/R/plot.R @@ -1,14 +1,14 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### plot methods ### -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### .plot: main switchyard for plotting functions ### ##' @importFrom utils modifyList -.plot <- function (x, y, ...){ +.plot <- function(x, y, ...) { ## 'spc' ... spectra ## 'map' ... map ## 'voronoi' ... voronoi tiled map @@ -19,97 +19,106 @@ ## 'spcmeansd' ... mean spectrum +- 1 standard deviation ## 'spcprctile' ... median spectrum , 16th and 84th percentile ## 'spcprctl5' ... spcprctile plus 5th and 95th percentile - - dots <- list(...) # to allow optional argument checks - - if (missing (y)){ - stop ("second argument to plot is missing. Should be a character indicating the type of plot.") - y = "spc" + + dots <- list(...) # to allow optional argument checks + + if (missing(y)) { + stop("second argument to plot is missing. Should be a character indicating the type of plot.") + y <- "spc" } - - switch (tolower (y), - spc = plotspc (x, ...), - spcmeansd = { - dots <- modifyList (list (object = mean_pm_sd (x), - fill = c (1, NA, 1) - ), - dots) - do.call (plotspc, dots) - }, - spcprctile = { - dots <- modifyList (list (object = quantile (x, probs = c (0.16, 0.5, 0.84)), - fill = c (1, NA, 1) - ), - dots) - do.call (plotspc, dots) - }, - spcprctl5 = { - dots <- modifyList (list (object = quantile (x, probs = c (0.05, 0.16, 0.5, 0.84, 0.95)), - fill = c (1, 2, 3, 2, 1), - fill.col = c("#00000040") - ), - dots) - do.call (plotspc, dots) - }, - map = plotmap (x, ...), - voronoi = plotvoronoi (x, ...), - mat = plotmat (x, ...), - c = plotc (x, ...), - ts = plotc (x, spc ~ t, ...), - depth = plotc (x, spc ~ z, ...), - stop (paste ("y = ", y, "unknown.", collapse = " ")) - ) + + switch(tolower(y), + spc = plotspc(x, ...), + spcmeansd = { + dots <- modifyList( + list( + object = mean_pm_sd(x), + fill = c(1, NA, 1) + ), + dots + ) + do.call(plotspc, dots) + }, + spcprctile = { + dots <- modifyList( + list( + object = quantile(x, probs = c(0.16, 0.5, 0.84)), + fill = c(1, NA, 1) + ), + dots + ) + do.call(plotspc, dots) + }, + spcprctl5 = { + dots <- modifyList( + list( + object = quantile(x, probs = c(0.05, 0.16, 0.5, 0.84, 0.95)), + fill = c(1, 2, 3, 2, 1), + fill.col = c("#00000040") + ), + dots + ) + do.call(plotspc, dots) + }, + map = plotmap(x, ...), + voronoi = plotvoronoi(x, ...), + mat = plotmat(x, ...), + c = plotc(x, ...), + ts = plotc(x, spc ~ t, ...), + depth = plotc(x, spc ~ z, ...), + stop(paste("y = ", y, "unknown.", collapse = " ")) + ) } ##' @noRd ##' @export -setGeneric ('plot') +setGeneric("plot") ##' Plotting hyperSpec Objects -##' +##' ##' Plotting \code{hyperSpec} objects. The \code{plot} method for ##' \code{hyperSpec} objects is a switchyard to \code{\link{plotspc}}, ##' \code{\link{plotmap}}, and \code{\link{plotc}}. -##' +##' ##' It also supplies some convenient abbrevations for much used plots. -##' +##' ##' If \code{y} is missing, \code{plot} behaves like \code{plot (x, y = ##' "spc")}. -##' +##' ##' Supported values for \code{y} are: -##' +##' ##' \describe{ \item{"spc"}{calls \code{\link{plotspc}} to produce a spectra ##' plot.} -##' +##' ##' \item{"spcmeansd"}{plots mean spectrum +/- one standard deviation} -##' +##' ##' \item{"spcprctile"}{plots 16th, 50th, and 84th percentile spectre. If the ##' distributions of the intensities at all wavelengths were normal, this would ##' correspond to \code{"spcmeansd"}. However, this is frequently not the case. ##' Then \code{"spcprctile"} gives a better impression of the spectral data ##' set.} -##' +##' ##' \item{"spcprctl5"}{like \code{"spcprctile"}, but additionally the 5th and ##' 95th percentile spectra are plotted.} -##' +##' ##' \item{"map"}{calls \code{\link{plotmap}} to produce a map plot.} -##' +##' ##' \item{"voronoi"}{calls \code{\link{plotvoronoi}} to produce a Voronoi plot ##' (tesselated plot, like "map" for hyperSpec objects with uneven/non-rectangular ##' grid).} ##' ##' \item{"mat"}{calls \code{\link{plotmat}} to produce a plot of the spectra ##' matrix (not to be confused with \code{\link[graphics]{matplot}}).} -##' +##' ##' \item{"c"}{calls \code{\link{plotc}} to produce a calibration (or time ##' series, depth-profile, or the like)} -##' +##' ##' \item{"ts"}{plots a time series: abbrevation for \code{\link{plotc} (x, ##' use.c = "t")}} -##' +##' ##' \item{"depth"}{plots a depth profile: abbrevation for \code{\link{plotc} ##' (x, use.c = "z")}} } -##' +##' ##' @name plot-methods ##' @rdname plot ##' @aliases plot plot,ANY,ANY-method plot,hyperSpec,character-method @@ -121,23 +130,23 @@ setGeneric ('plot') ##' @author C. Beleites ##' @seealso \code{\link{plotspc}} for spectra plots (intensity over ##' wavelength), -##' +##' ##' \code{\link{plotmap}} for plotting maps, i.e. color coded summary value on ##' two (usually spatial) dimensions. -##' +##' ##' \code{\link{plotc}} -##' +##' ##' \code{\link[graphics]{plot}} ##' @keywords methods hplot ##' @export ##' @examples -##' +##' ##' plot (flu) -##' +##' ##' plot (flu, "c") -##' +##' ##' plot (laser, "ts") -##' +##' ##' spc <- apply (chondro, 2, quantile, probs = 0.05) ##' spc <- sweep (chondro, 2, spc, "-") ##' plot (spc, "spcprctl5") @@ -145,13 +154,16 @@ setGeneric ('plot') ##' plot (spc, "spcmeansd") ##' ### use plotspc as default plot function -setMethod ("plot", - signature (x = "hyperSpec", y = "missing"), - function (x, y, ...) plotspc (x, ...) - ) +setMethod( + "plot", + signature(x = "hyperSpec", y = "missing"), + function(x, y, ...) plotspc(x, ...) +) ### allow choice of spectral or map plot by second argument ##' @rdname plot ##' @export -setMethod ("plot", - signature (x = "hyperSpec", y = "character"), .plot) +setMethod( + "plot", + signature(x = "hyperSpec", y = "character"), .plot +) diff --git a/hyperSpec/R/plotc.R b/hyperSpec/R/plotc.R index 08cb8f9d0..0f0a80742 100644 --- a/hyperSpec/R/plotc.R +++ b/hyperSpec/R/plotc.R @@ -1,6 +1,6 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### -### plotc - plot timeseries, concentration, ... +### plotc - plot timeseries, concentration, ... ### ### C. Beleites @@ -9,23 +9,23 @@ ##' Calibration- and Timeseries Plots, Depth-Profiles and the like ##' \code{plotc} plots intensities of a \code{hyperSpec} object over another ##' dimension such as concentration, time, or a spatial coordinate. -##' +##' ##' If \code{func} is not \code{NULL}, the summary characteristic is calculated ##' first by applying \code{func} with the respective arguments (in ##' \code{func.args}) to each of the spectra. If \code{func} returns more than ##' one value (for each spectrum), the different values end up as different ##' wavelengths. -##' +##' ##' If the wavelength is not used in the model specification nor in ##' \code{groups}, nor for specifying \code{subsets}, and neither is ##' \code{func} given, then only the first wavelength's intensities are plotted ##' and a warning is issued. -##' +##' ##' The special column names \code{.rownames} and \code{.wavelength} may be ##' used. -##' +##' ##' The actual plotting is done by \code{\link[lattice]{xyplot}}. -##' +##' ##' @param object the \code{hyperSpec} object ##' @param model the lattice model specifying the plot ##' @param func function to compute a summary value from the spectra to be @@ -41,24 +41,24 @@ ##' @import graphics ##' @importFrom lattice xyplot ##' @examples -##' -##' -##' ## example 1: calibration of fluorescence +##' +##' +##' ## example 1: calibration of fluorescence ##' plotc (flu) ## gives a warning -##' +##' ##' plotc (flu, func = mean) ##' plotc (flu, func = range, groups = .wavelength) -##' +##' ##' plotc (flu[,,450], ylab = expression (I ["450 nm"] / a.u.)) -##' -##' +##' +##' ##' calibration <- lm (spc ~ c, data = flu[,,450]$.) ##' summary (calibration) ##' plotc (flu [,, 450], type = c("p", "r")) -##' +##' ##' conc <- list (c = seq (from = 0.04, to = 0.31, by = 0.01)) -##' ci <- predict (calibration, newdata = conc, interval = "confidence", level = 0.999) -##' +##' ci <- predict (calibration, newdata = conc, interval = "confidence", level = 0.999) +##' ##' panel.ci <- function (x, y, ..., ##' conc, ci.lwr, ci.upr, ci.col = "#606060") { ##' panel.xyplot (x, y, ...) @@ -66,89 +66,101 @@ ##' panel.lines (conc, ci.lwr, col = ci.col) ##' panel.lines (conc, ci.upr, col = ci.col) ##' } -##' +##' ##' plotc (flu [,, 450], panel = panel.ci, ##' conc = conc$c, ci.lwr = ci [, 2], ci.upr = ci [, 3]) -##' +##' ##' ## example 2: time-trace of laser emission modes ##' cols <- c ("black", "blue", "#008000", "red") ##' wl <- i2wl (laser, c(13, 17, 21, 23)) -##' +##' ##' plotspc (laser, axis.args=list (x = list (at = seq (404.5, 405.8, .1)))) ##' for (i in seq_along (wl)) ##' abline (v = wl[i], col = cols[i], lwd = 2) -##' +##' ##' plotc (laser [,, wl], spc ~ t, groups = .wavelength, type = "b", ##' col = cols) -##' +##' ##' @importFrom utils modifyList -plotc <- function (object, model = spc ~ c, groups = NULL, - func = NULL, func.args = list (), ...){ - chk.hy (object) - validObject (object) +plotc <- function(object, model = spc ~ c, groups = NULL, + func = NULL, func.args = list(), ...) { + chk.hy(object) + validObject(object) - dots <- list (...) + dots <- list(...) + + if (!is.null(func)) { + object <- do.call(apply, c(list(object, 1, func), func.args)) + } - if (! is.null (func)) - object <- do.call (apply, c (list (object, 1, func), func.args)) - ## allow to plot against the row number - object$.row <- row.seq (object) + object$.row <- row.seq(object) + + groups <- substitute(groups) - groups <- substitute (groups) - ## find out whether the wavelengths are needed individually, ## if not, use only the first wavelength and issue a warning - parsed.formula <- latticeParseFormula (model, - as.long.df (object [1, , 1, wl.index = TRUE], rownames = TRUE), - groups = groups, dimension = 2) - + parsed.formula <- latticeParseFormula(model, + as.long.df(object [1, , 1, wl.index = TRUE], rownames = TRUE), + groups = groups, dimension = 2 + ) + use.c <- parsed.formula$right.name use.spc <- parsed.formula$left.name - if (use.spc == "spc" && nwl (object) > 1 && is.null (func) && - !any (grepl (".wavelength", c(as.character (model), - as.character (groups), - as.character (dots$subset))))) { - object <- object [,, 1, wl.index = TRUE] - warning ("Intensity at first wavelengh only is used.") + if (use.spc == "spc" && nwl(object) > 1 && is.null(func) && + !any(grepl(".wavelength", c( + as.character(model), + as.character(groups), + as.character(dots$subset) + )))) { + object <- object [, , 1, wl.index = TRUE] + warning("Intensity at first wavelengh only is used.") } - if (is.null (func)) + if (is.null(func)) { ylab <- object@label [[use.spc]] - else { - ylab <- substitute (func ()) + } else { + ylab <- substitute(func()) ylab [[2]] <- object@label [[use.spc]][[1]] - for (i in seq_along (func.args)){ - if (names (func.args)[[i]] == "") + for (i in seq_along(func.args)) { + if (names(func.args)[[i]] == "") { ylab [[i + 2]] <- func.args [[i]] - else - ylab [[i + 2]] <- bquote (.(x) == .(y), - list (x = names (func.args) [[i]], - y = as.character (func.args [[i]]))) - + } else { + ylab [[i + 2]] <- bquote( + .(x) == .(y), + list( + x = names(func.args) [[i]], + y = as.character(func.args [[i]]) + ) + ) } - ylab <- as.expression (ylab) + } + ylab <- as.expression(ylab) } - + ## set defaults: axis labels, plot style - dots <- modifyList (list (xlab = object@label [[use.c]], - ylab = ylab, - pch = 19), - dots) + dots <- modifyList( + list( + xlab = object@label [[use.c]], + ylab = ylab, + pch = 19 + ), + dots + ) ## expand the data.frame - df <- as.long.df (object, rownames = TRUE, wl.factor = TRUE) + df <- as.long.df(object, rownames = TRUE, wl.factor = TRUE) ## if plots should be grouped or conditioned by wavelength, ## it is better to have a factor - if ((! is.null (parsed.formula$condition) && - parsed.formula$condition == ".wavelength") || - (! is.null (groups) && - as.character (groups) == ".wavelength")) - df$.wavelength <- as.factor (df$.wavelength) + if ((!is.null(parsed.formula$condition) && + parsed.formula$condition == ".wavelength") || + (!is.null(groups) && + as.character(groups) == ".wavelength")) { + df$.wavelength <- as.factor(df$.wavelength) + } ## plot - do.call(xyplot, c (list (x = model, data = df, groups = groups), dots)) + do.call(xyplot, c(list(x = model, data = df, groups = groups), dots)) } - diff --git a/hyperSpec/R/plotmap.R b/hyperSpec/R/plotmap.R index 212367800..6a85da857 100644 --- a/hyperSpec/R/plotmap.R +++ b/hyperSpec/R/plotmap.R @@ -1,7 +1,7 @@ ################################################################################# ### ### plotmap - plot spectral maps -### +### ### plots intensity or extra data column over 2 extra data columns ## TODO: check wheter func should be applied or not @@ -11,17 +11,17 @@ ##' Plot a Map and Identify/Select Spectra in the Map ##' \code{\link[lattice]{levelplot}} functions for hyperSpec objects. An image or map of a summary ##' value of each spectrum is plotted. Spectra may be identified by mouse click. -##' +##' ##' The \code{model} can contain the special column name \code{.wavelength} to specify the wavelength ##' axis. -##' +##' ##' \code{plotmap}, \code{map.identify}, and the \code{levelplot} methods internally use the same ##' gateway function to \code{\link[lattice]{levelplot}}. Thus \code{transform.factor} can be used ##' with all of them and the panel function defaults to \code{\link[lattice]{panel.levelplot.raster}} -##' for all three. Two special column names, \code{.rownames} and \code{.wavelength} may be used. -##' +##' for all three. Two special column names, \code{.rownames} and \code{.wavelength} may be used. +##' ##' \code{levelplot} plots the spectra matrix. -##' +##' ##' \code{plotvoronoi} calls \code{plotmap} with different default settings, namely the panel ##' function defaults to \code{\link[latticeExtra]{panel.voronoi}}. ##' \code{\link[latticeExtra]{panel.voronoi}} depends on either of the packages 'tripack' or 'deldir' @@ -31,19 +31,19 @@ ##' \code{plotvoronoi} using deldir. Package tripack, however, is free only for non-commercial ##' use. Also, it seems that tripack version hang (R running at full CPU power, but not responding ##' nor finishing the calculation) for certain data sets. In this case, \code{mix = TRUE} may help. -##' +##' ##' \code{map.identify} calls \code{plotmap} and \code{plotvoronoi}, respectively and waits for ##' (left) mouse clicks on points. Other mouse clicks end the input. -##' +##' ##' Unlike \code{\link[lattice]{panel.identify}}, the indices returned by \code{map.identify} are in ##' the same order as the points were clicked. Also, multiple clicks on the same point are returned ##' as multiple entries with the same index. -##' +##' ##' \code{map.identify} uses option \code{debuglevel} similar to \code{\link{spc.identify}}: ##' \code{debuglevel == 1} will plot the tolerance window if no data point was inside (and ##' additionally labels the point) while \code{debuglevel == 2} will always plot the tolerance ##' window. -##' +##' ##' The \code{map.sel.*} functions offer further interactive selection, see ##' \code{\link{map.sel.poly}}. ##' @@ -66,53 +66,55 @@ ##' to \code{\link[lattice]{levelplot}} ##' @return \code{map.identify} returns a vector of row indices into ##' \code{object} of the clicked points. -##' +##' ##' The other functions return a lattice object. ##' @author C. Beleites ##' @seealso \code{vignette (plotting)}, \code{vignette (hyperspec)} -##' +##' ##' \code{\link{plot}} ##' @export ##' @keywords hplot ##' @examples -##' +##' ##' \dontrun{ ##' vignette (plotting) ##' vignette (hyperspec) ##' } -##' +##' ##' levelplot (spc ~ y * x, chondro [,,1003]) # properly rotated ##' plotmap (chondro [,,1003]) -##' +##' ##' # plot spectra matrix ##' levelplot (spc ~ .wavelength * t, laser, contour = TRUE, col = "#00000080") ##' # see also plotmat -##' +##' ##' plotmap (chondro, clusters ~ x * y) -##' +##' ##' # Voronoi plots ##' smpl <- sample (chondro, 300) ##' plotmap (smpl, clusters ~ x * y) -##' if (require (tripack)) +##' if (require (tripack)) ##' plotvoronoi (smpl, clusters ~ x * y) -##' if (require (deldir)) +##' if (require (deldir)) ##' plotvoronoi (smpl, clusters ~ x * y, ##' use.tripack = FALSE) -##' +##' ##' @importFrom utils modifyList -plotmap <- function (object, model = spc ~ x * y, - func = mean, func.args = list (), ...){ - chk.hy (object) - validObject (object) +plotmap <- function(object, model = spc ~ x * y, + func = mean, func.args = list(), ...) { + chk.hy(object) + validObject(object) + + if (!is.null(func) & !any(grepl("[.]wavelength", model))) { + object <- do.call(apply, c(list(object, 1, func), func.args)) + } - if (! is.null (func) & ! any (grepl ("[.]wavelength", model))) - object <- do.call (apply, c (list (object, 1, func), func.args)) - - dots <- modifyList (list (aspect = "iso"), - list (...)) - - dots <- c (list (x = model, data = object), dots) + dots <- modifyList( + list(aspect = "iso"), + list(...) + ) + + dots <- c(list(x = model, data = object), dots) do.call(.levelplot, dots) } - diff --git a/hyperSpec/R/plotmat.R b/hyperSpec/R/plotmat.R index 726e368fb..495be61f2 100644 --- a/hyperSpec/R/plotmat.R +++ b/hyperSpec/R/plotmat.R @@ -29,81 +29,82 @@ ##' ##' plotmat (laser, laser$t / 3600, ylab = "t / h") ##' @importFrom utils modifyList -plotmat <- function (object, y = ".row", ylab, col = alois.palette (20), ..., - contour = FALSE){ - - chk.hy (object) - validObject (object) - object <- orderwl (object) - - if (is.character (y)) { - if (missing (ylab)) - ylab <- switch (y, - .row = "row", - labels (object, y)) +plotmat <- function(object, y = ".row", ylab, col = alois.palette(20), ..., + contour = FALSE) { + chk.hy(object) + validObject(object) + object <- orderwl(object) + + if (is.character(y)) { + if (missing(ylab)) { + ylab <- switch(y, + .row = "row", + labels(object, y) + ) + } - y <- switch (y, - .row = seq_len (nrow (object)), - object@data [[y]]) + y <- switch(y, + .row = seq_len(nrow(object)), + object@data [[y]] + ) } - dots <- modifyList (list (x = wl (object), - y = y, - z = t (object [[]]), - xlab = labels (object, ".wavelength"), - ylab = ylab, - col = col - ), - list (...)) - - - if (contour) - do.call ("contour", dots) - else { + dots <- modifyList( + list( + x = wl(object), + y = y, + z = t(object [[]]), + xlab = labels(object, ".wavelength"), + ylab = ylab, + col = col + ), + list(...) + ) + + + if (contour) { + do.call("contour", dots) + } else { ## leave at least 4 lines right margin mar <- par()$ mar - if (mar [4] < 5) - par (mar = c (mar [1 : 3], 5)) + if (mar [4] < 5) { + par(mar = c(mar [1:3], 5)) + } - do.call ("image", dots) - par (mar = mar) + do.call("image", dots) + par(mar = mar) ## color legend - if (requireNamespace ("plotrix", quietly = TRUE)){ - + if (requireNamespace("plotrix", quietly = TRUE)) { usr <- par()$usr - dx <- diff (usr [1 : 2]) + dx <- diff(usr [1:2]) - plotrix::color.legend (usr [2] + 0.05 * dx, - usr [3], - usr [2] + 0.10 * dx, - usr [4], - pretty (range (object, na.rm = TRUE)), - col, - align="rb",gradient="y") + plotrix::color.legend(usr [2] + 0.05 * dx, + usr [3], + usr [2] + 0.10 * dx, + usr [4], + pretty(range(object, na.rm = TRUE)), + col, + align = "rb", gradient = "y" + ) } else { - warning ("package 'plotrix' not available: omitting legend.") + warning("package 'plotrix' not available: omitting legend.") } - } - - } ##' @include unittest.R -.test (plotmat) <- function (){ - context ("plotmat") +.test(plotmat) <- function() { + context("plotmat") - test_that ("non-increasing wavelength axis", { + test_that("non-increasing wavelength axis", { tmp <- flu - tmp [[]] <- tmp [[,, max ~ min]] - tmp@wavelength <- rev (tmp@wavelength) + tmp [[]] <- tmp [[, , max ~ min]] + tmp@wavelength <- rev(tmp@wavelength) - expect_silent (plotmat (tmp)) + expect_silent(plotmat(tmp)) }) ## TODO vdiffr - - } diff --git a/hyperSpec/R/plotspc.R b/hyperSpec/R/plotspc.R index 8a48fc8cf..19512cd04 100644 --- a/hyperSpec/R/plotspc.R +++ b/hyperSpec/R/plotspc.R @@ -1,4 +1,4 @@ -###-------------------------------------------------------------------------------------------------- +### -------------------------------------------------------------------------------------------------- ### ### plotspc - Plots spectra of hyperSpec object ### @@ -157,341 +157,386 @@ ##' ##' @importFrom utils modifyList relist head tail ##' @importFrom grDevices rgb col2rgb -plotspc <- function (object, - ## what wavelengths to plot - wl.range = TRUE, wl.index = FALSE, wl.reverse = FALSE, - ## what spectra to plot - spc.nmax = hy.getOption("plot.spc.nmax"), - func = NULL, func.args = list (), - stacked = NULL, stacked.args = list (), - ## plot area - add = FALSE, bty = "l", plot.args = list(), - ## lines - col = "black", lines.args = list (), - ## axes - xoffset = 0, yoffset = 0, nxticks = 10, axis.args = list (), - break.args = list (), - ## title (axis labels) - title.args = list (), - ## parameters for filled regions - fill = NULL, fill.col = NULL, border = NA, polygon.args = list (), - ## line indicating zero intensity - zeroline = list (lty = 2, col = col), - debuglevel = hy.getOption("debuglevel")){ - force (zeroline) # otherwise stacking messes up colors - - chk.hy (object) - validObject (object) - if (nrow (object) == 0) stop ("No spectra.") +plotspc <- function(object, + ## what wavelengths to plot + wl.range = TRUE, wl.index = FALSE, wl.reverse = FALSE, + ## what spectra to plot + spc.nmax = hy.getOption("plot.spc.nmax"), + func = NULL, func.args = list(), + stacked = NULL, stacked.args = list(), + ## plot area + add = FALSE, bty = "l", plot.args = list(), + ## lines + col = "black", lines.args = list(), + ## axes + xoffset = 0, yoffset = 0, nxticks = 10, axis.args = list(), + break.args = list(), + ## title (axis labels) + title.args = list(), + ## parameters for filled regions + fill = NULL, fill.col = NULL, border = NA, polygon.args = list(), + ## line indicating zero intensity + zeroline = list(lty = 2, col = col), + debuglevel = hy.getOption("debuglevel")) { + force(zeroline) # otherwise stacking messes up colors + + chk.hy(object) + validObject(object) + if (nrow(object) == 0) stop("No spectra.") ## prepare wavelengths ............................................................................ ## somewhat more complicated here because of plotting with cut wavelength axis -# wl.range <- lazy (wl.range) -# browser () -# if (is.null (wl.range$expr)) { -# wl.range <- seq_along (object@wavelength) -# wl.index <- TRUE -# } - -# if (!is.list (wl.range$expr)) -# wl.range <- list (wl.range) - - if (!wl.index){ - wl.range <- wl2i (object, wl.range, unlist = FALSE) - wl.range <- lapply (wl.range, function (r) r [! is.na (r)]) - } + # wl.range <- lazy (wl.range) + # browser () + # if (is.null (wl.range$expr)) { + # wl.range <- seq_along (object@wavelength) + # wl.index <- TRUE + # } + + # if (!is.list (wl.range$expr)) + # wl.range <- list (wl.range) + + if (!wl.index) { + wl.range <- wl2i(object, wl.range, unlist = FALSE) + wl.range <- lapply(wl.range, function(r) r [!is.na(r)]) + } ## xoffset ........................................................................................ ## may be ## - one number for all wl.ranges ## - a number for each wl.range ## - one less than wl.ranges: first will be 0 - if (length (xoffset) == length (wl.range) - 1) - xoffset = c (0, xoffset) - else if (length (xoffset) == 1) - xoffset = rep (xoffset, times = length (wl.range)) - if (!is.numeric(xoffset) || (length (xoffset) != length (wl.range))) - stop ("xoffset must be a numeric vector of the same length (or one less) as the list with", - "wavenumber ranges.") - xoffset <- cumsum (xoffset) + if (length(xoffset) == length(wl.range) - 1) { + xoffset <- c(0, xoffset) + } else if (length(xoffset) == 1) { + xoffset <- rep(xoffset, times = length(wl.range)) + } + if (!is.numeric(xoffset) || (length(xoffset) != length(wl.range))) { + stop( + "xoffset must be a numeric vector of the same length (or one less) as the list with", + "wavenumber ranges." + ) + } + xoffset <- cumsum(xoffset) ## for indexing wavelength.range is needed unlisted - u.wl.range <- unlist (wl.range) + u.wl.range <- unlist(wl.range) ## wavelengths are the numbers to print at the x axis - wavelengths <- relist (object@wavelength [u.wl.range], wl.range) + wavelengths <- relist(object@wavelength [u.wl.range], wl.range) ## x are the actual x coordinates x <- wavelengths - for (i in seq_along(x)) + for (i in seq_along(x)) { x [[i]] <- x [[i]] - xoffset[i] + } ## prepare spectra ................................................................................ ## indices into columns of spectra matrix spc - ispc <- relist (seq_along (u.wl.range), wl.range) + ispc <- relist(seq_along(u.wl.range), wl.range) - rm (wl.range) - spc <- object[[,, u.wl.range, drop = FALSE, wl.index = TRUE]] - rm (u.wl.range) + rm(wl.range) + spc <- object[[, , u.wl.range, drop = FALSE, wl.index = TRUE]] + rm(u.wl.range) ## summary statistics: apply function func to spc - if (!is.null (func)){ - if (!is.function (func)) - stop ("func needs to be a function."); - - apply.args <- c (list (X = spc, MARGIN = 2, FUN = func), func.args) - spc <- matrix (do.call (apply, apply.args), #apply (spc, 2, func), - ncol = ncol (spc) - ) - if (nrow (spc) == 0) - stop ("No spectra after", func, "was applied.") + if (!is.null(func)) { + if (!is.function(func)) { + stop("func needs to be a function.") + } + + apply.args <- c(list(X = spc, MARGIN = 2, FUN = func), func.args) + spc <- matrix(do.call(apply, apply.args), # apply (spc, 2, func), + ncol = ncol(spc) + ) + if (nrow(spc) == 0) { + stop("No spectra after", func, "was applied.") + } } ## do not plot too many spectra by default: can take very long and there is most probably nothing ## visible on the resulting picture - if (nrow (spc) > spc.nmax){ - if (debuglevel >= 1L) - message ("Number of spectra exceeds spc.nmax. Only the first", spc.nmax, "are plotted.") + if (nrow(spc) > spc.nmax) { + if (debuglevel >= 1L) { + message("Number of spectra exceeds spc.nmax. Only the first", spc.nmax, "are plotted.") + } - spc <- spc [seq_len (spc.nmax), , drop = FALSE] + spc <- spc [seq_len(spc.nmax), , drop = FALSE] } ## stacked plot - if (!is.null (stacked)){ - stacked.args <- modifyList (stacked.args, - list (x = object, stacked = stacked, .spc = spc)) + if (!is.null(stacked)) { + stacked.args <- modifyList( + stacked.args, + list(x = object, stacked = stacked, .spc = spc) + ) - if (! is.null (lines.args$type) && lines.args$type == "h") - stacked.args <- modifyList (stacked.args, list (min.zero = TRUE)) + if (!is.null(lines.args$type) && lines.args$type == "h") { + stacked.args <- modifyList(stacked.args, list(min.zero = TRUE)) + } - stacked <- do.call (stacked.offsets, stacked.args) - if (all (yoffset == 0)) + stacked <- do.call(stacked.offsets, stacked.args) + if (all(yoffset == 0)) { yoffset <- stacked$offsets [stacked$groups] - else if (length (yoffset) == length (unique (stacked$groups))) + } else if (length(yoffset) == length(unique(stacked$groups))) { yoffset <- yoffset [stacked$groups] + } } ## yoffset ........................................................................................ ## either one value for all spectra ## or one per spectrum or one per group - if (length (yoffset) != nrow (spc)){ - if (length (yoffset) == 1) - yoffset <- rep (yoffset, nrow (spc)) - else if (length (yoffset) > nrow (spc)) - yoffset <- yoffset [seq_len (nrow (spc))] - else - stop ("yoffset must be single number or one number for each spectrum (or stacking group).") + if (length(yoffset) != nrow(spc)) { + if (length(yoffset) == 1) { + yoffset <- rep(yoffset, nrow(spc)) + } else if (length(yoffset) > nrow(spc)) { + yoffset <- yoffset [seq_len(nrow(spc))] + } else { + stop("yoffset must be single number or one number for each spectrum (or stacking group).") + } } - spc <- sweep (spc, 1, yoffset, "+") + spc <- sweep(spc, 1, yoffset, "+") ## plot area -------------------------------------------------------------------------------------- ## should a new plot be set up? - if (! add){ + if (!add) { ## set default plot args - plot.args <- modifyList (list (xlim = range (unlist (x), na.rm = TRUE), - ylim = range (spc, na.rm = TRUE)), - plot.args) + plot.args <- modifyList( + list( + xlim = range(unlist(x), na.rm = TRUE), + ylim = range(spc, na.rm = TRUE) + ), + plot.args + ) ## the actual spectra are plotted below, so we do not need any line parametrers here ## reverse x axis ? - if (wl.reverse) + if (wl.reverse) { plot.args$xlim <- rev(plot.args$xlim) + } ## some arguments must be overwritten if given: - plot.args <- modifyList (plot.args, - list (x = unlist (x), y = spc[1,,drop=FALSE], - type = "n", bty = "n", - xaxt = "n", yaxt = "n", # axes and title are called separately - xlab = NA, ylab = NA)) # for finer control - - do.call (plot, plot.args) - - ## reversed x axis leads to trouble with tick positions - ## - if (diff (plot.args$xlim) < 0) + plot.args <- modifyList( + plot.args, + list( + x = unlist(x), y = spc[1, , drop = FALSE], + type = "n", bty = "n", + xaxt = "n", yaxt = "n", # axes and title are called separately + xlab = NA, ylab = NA + ) + ) # for finer control + + do.call(plot, plot.args) + + ## reversed x axis leads to trouble with tick positions + ## + if (diff(plot.args$xlim) < 0) { plot.args$xlim <- rev(plot.args$xlim) + } ## Axes ----------------------------------------------------------------------------------------- - axis.args <- modifyList (list (x = list (), y = list ()), axis.args) + axis.args <- modifyList(list(x = list(), y = list()), axis.args) ## x-axis labels & ticks - if (bty %in% c("o", "l", "c", "u", "]", "x") ){ - cuts <- .cut.ticks (sapply (wavelengths, min), sapply (wavelengths, max), xoffset, nxticks) - - axis.args$x <- modifyList (axis.args [! names (axis.args) %in% c ("x", "y")], - axis.args$x) - if (is.null (axis.args$x$labels) & ! is.null (axis.args$x$at)) + if (bty %in% c("o", "l", "c", "u", "]", "x")) { + cuts <- .cut.ticks(sapply(wavelengths, min), sapply(wavelengths, max), xoffset, nxticks) + + axis.args$x <- modifyList( + axis.args [!names(axis.args) %in% c("x", "y")], + axis.args$x + ) + if (is.null(axis.args$x$labels) & !is.null(axis.args$x$at)) { axis.args$x$labels <- axis.args$x$at - axis.args$x <- modifyList (list (side = 1, at = cuts$at, labels = cuts$labels), - axis.args$x) + } + axis.args$x <- modifyList( + list(side = 1, at = cuts$at, labels = cuts$labels), + axis.args$x + ) - axis (side = 1, at = max (abs (plot.args$xlim)) * c(-1.1, 1.1)) - do.call (axis, axis.args$x) + axis(side = 1, at = max(abs(plot.args$xlim)) * c(-1.1, 1.1)) + do.call(axis, axis.args$x) ## plot cut marks for x axis - break.args <- modifyList (list (style = "zigzag"), break.args) + break.args <- modifyList(list(style = "zigzag"), break.args) break.args$axis <- NULL break.args$breakpos <- NULL - if (length (cuts$cut) > 0) { - if (! requireNamespace ("plotrix")){ - cat ("hyperSpec will use its own replacement for plotrix' axis.break\n\n") + if (length(cuts$cut) > 0) { + if (!requireNamespace("plotrix")) { + cat("hyperSpec will use its own replacement for plotrix' axis.break\n\n") break.fun <- .axis.break } else { break.fun <- plotrix::axis.break } - for (i in cuts$cut) - do.call (break.fun, c (list (axis = 1, breakpos = i), break.args)) + for (i in cuts$cut) { + do.call(break.fun, c(list(axis = 1, breakpos = i), break.args)) + } } } ## y-axis labels & ticks - if (bty %in% c("o", "l", "c", "u", "y")){ - axis.args$y <- modifyList (axis.args [! names (axis.args) %in% c ("x", "y", "main", "sub")], - axis.args$y) + if (bty %in% c("o", "l", "c", "u", "y")) { + axis.args$y <- modifyList( + axis.args [!names(axis.args) %in% c("x", "y", "main", "sub")], + axis.args$y + ) ## default for stacked plots is marking the groups - if (!is.null (stacked)){ - if (! is.null (stacked.args$min.zero) && stacked.args$min.zero) + if (!is.null(stacked)) { + if (!is.null(stacked.args$min.zero) && stacked.args$min.zero) { group.mins <- stacked$offsets - else - group.mins <- apply (spc[!duplicated (stacked$groups),, drop = FALSE], 1, min, na.rm = TRUE) + } else { + group.mins <- apply(spc[!duplicated(stacked$groups), , drop = FALSE], 1, min, na.rm = TRUE) + } - axis.args$y <- modifyList (list (at = stacked$offsets, - labels = stacked$levels [!duplicated (stacked$levels)]), - axis.args$y) + axis.args$y <- modifyList( + list( + at = stacked$offsets, + labels = stacked$levels [!duplicated(stacked$levels)] + ), + axis.args$y + ) } - axis.args$y <- modifyList (list (side = 2), axis.args$y) - axis (side = 2, at = max (abs (plot.args$ylim)) * c(-1.1, 1.1)) - do.call (axis, axis.args$y) + axis.args$y <- modifyList(list(side = 2), axis.args$y) + axis(side = 2, at = max(abs(plot.args$ylim)) * c(-1.1, 1.1)) + do.call(axis, axis.args$y) } ## Title: axis labels --------------------------------------------------------------------------- - tmp <- title.args [! names (title.args) %in% c ("x","y", "ylab", "main", "sub")] - tmp <- modifyList (tmp, as.list (title.args$x)) - - tmp <- modifyList (list (xlab = object@label$.wavelength, line = 2.5), tmp) - do.call (title, tmp) + tmp <- title.args [!names(title.args) %in% c("x", "y", "ylab", "main", "sub")] + tmp <- modifyList(tmp, as.list(title.args$x)) + + tmp <- modifyList(list(xlab = object@label$.wavelength, line = 2.5), tmp) + do.call(title, tmp) tmp$xlab <- NULL - tmp <- title.args [! names (title.args) %in% c ("x","y", "xlab", "main", "sub")] - tmp <- modifyList (tmp, as.list (title.args$y)) - tmp <- modifyList (list (ylab = object@label$spc), tmp) - do.call (title, tmp) + tmp <- title.args [!names(title.args) %in% c("x", "y", "xlab", "main", "sub")] + tmp <- modifyList(tmp, as.list(title.args$y)) + tmp <- modifyList(list(ylab = object@label$spc), tmp) + do.call(title, tmp) tmp$ylab <- NULL - - tmp <- title.args [! names (title.args) %in% c ("x","y", "xlab", "ylab")] - tmp <- modifyList (tmp, as.list (title.args [c ("main", "sub")])) - do.call (title, tmp) + + tmp <- title.args [!names(title.args) %in% c("x", "y", "xlab", "ylab")] + tmp <- modifyList(tmp, as.list(title.args [c("main", "sub")])) + do.call(title, tmp) } ## plot the spectra ------------------------------------------------------------------------------- ## if necessary, recycle colors - col <- rep (col, each = ceiling (nrow (spc) / length (col)), length.out = nrow (spc)) + col <- rep(col, each = ceiling(nrow(spc) / length(col)), length.out = nrow(spc)) ## should the intensity zero be marked? - if (!(is.logical (zeroline) && is.na (zeroline))){ - zeroline <- modifyList (list (h = unique (yoffset)), as.list (zeroline)) - do.call (abline, zeroline) + if (!(is.logical(zeroline) && is.na(zeroline))) { + zeroline <- modifyList(list(h = unique(yoffset)), as.list(zeroline)) + do.call(abline, zeroline) } ## start loop over wavelength ranges - for (i in seq_along (x)){ + for (i in seq_along(x)) { ## filling for polygons ........................................................................ ## groupings for upper and lower bound of the bands - if (!is.null (fill)){ - if (is.character (fill) && length (fill) == 1) - fill <- unlist (object [[, fill]]) - else if (isTRUE (fill)){ - fill <- seq_len (nrow (spc) / 2) - if (nrow (spc) %% 2 == 1) # odd number of spectra - fill <- c (fill, NA, rev (fill)) - else - fill <- c (fill, rev (fill)) - } else if (is.factor (fill)) - fill <- as.numeric (fill) - else if (!is.numeric (fill)) - stop ("fill must be either TRUE, the name of the extra data column to use for grouping,", - "a factor or a numeric.") - - groups = unique (fill) - groups = groups [!is.na (groups)] - - - polygon.args <- modifyList (list (x = NULL, y = NULL), - polygon.args) + if (!is.null(fill)) { + if (is.character(fill) && length(fill) == 1) { + fill <- unlist(object [[, fill]]) + } else if (isTRUE(fill)) { + fill <- seq_len(nrow(spc) / 2) + if (nrow(spc) %% 2 == 1) { # odd number of spectra + fill <- c(fill, NA, rev(fill)) + } else { + fill <- c(fill, rev(fill)) + } + } else if (is.factor(fill)) { + fill <- as.numeric(fill) + } else if (!is.numeric(fill)) { + stop( + "fill must be either TRUE, the name of the extra data column to use for grouping,", + "a factor or a numeric." + ) + } + + groups <- unique(fill) + groups <- groups [!is.na(groups)] + + + polygon.args <- modifyList( + list(x = NULL, y = NULL), + polygon.args + ) ## fill color - if (is.null (fill.col)){ - fill.col <- character (length (groups)) + if (is.null(fill.col)) { + fill.col <- character(length(groups)) - for (j in seq_along (groups)){ - tmp <- which (fill == groups [j]) - fill.col [j] <- rgb( t (col2rgb (col [tmp[1]]) / 255) / 3 + 2/3) + for (j in seq_along(groups)) { + tmp <- which(fill == groups [j]) + fill.col [j] <- rgb(t(col2rgb(col [tmp[1]]) / 255) / 3 + 2 / 3) } } else { - fill.col <- rep (fill.col, length.out = length (groups)) + fill.col <- rep(fill.col, length.out = length(groups)) } - border <- rep (border, length.out = length (groups)) + border <- rep(border, length.out = length(groups)) - polygon.args$x <- c (x [[i]], rev (x [[i]])) + polygon.args$x <- c(x [[i]], rev(x [[i]])) - for (j in seq_along (groups)){ - tmp <- which (fill == groups [j]) - polygon.args$y <- c (spc[head(tmp, 1), ispc[[i]]], rev (spc [tail (tmp, 1), ispc[[i]]])) - polygon.args$col = fill.col [groups [j]] + for (j in seq_along(groups)) { + tmp <- which(fill == groups [j]) + polygon.args$y <- c(spc[head(tmp, 1), ispc[[i]]], rev(spc [tail(tmp, 1), ispc[[i]]])) + polygon.args$col <- fill.col [groups [j]] polygon.args$border <- border [groups [j]] - do.call (polygon, polygon.args) + do.call(polygon, polygon.args) } } ## lines ........................................................................................ - lines.args <- modifyList (list (x = NULL, y = NULL, type = "l"), lines.args) - - if (lines.args$type == "h" && is.list (stacked)) { - ## specialty: lines from the stacked zero line on! - for (j in seq_len (nrow (spc))){ - keep <- ! is.na (spc [j, ispc[[i]]]) - lines.args$x <- rep (x[[i]] [keep], each = 3) - lines.args$y <- as.numeric (matrix (c (rep (yoffset [j], sum (keep)), - spc [j, ispc[[i]]] [keep], - rep (NA, sum (keep))), - byrow = TRUE, nrow = 3)) - lines.args$type = "l" + lines.args <- modifyList(list(x = NULL, y = NULL, type = "l"), lines.args) + + if (lines.args$type == "h" && is.list(stacked)) { + ## specialty: lines from the stacked zero line on! + for (j in seq_len(nrow(spc))) { + keep <- !is.na(spc [j, ispc[[i]]]) + lines.args$x <- rep(x[[i]] [keep], each = 3) + lines.args$y <- as.numeric(matrix(c( + rep(yoffset [j], sum(keep)), + spc [j, ispc[[i]]] [keep], + rep(NA, sum(keep)) + ), + byrow = TRUE, nrow = 3 + )) + lines.args$type <- "l" lines.args$col <- col [j] - do.call (lines, lines.args) + do.call(lines, lines.args) } } else { - for (j in seq_len (nrow (spc))){ - keep <- ! is.na (spc [j, ispc[[i]]]) + for (j in seq_len(nrow(spc))) { + keep <- !is.na(spc [j, ispc[[i]]]) lines.args$x <- x[[i]][keep] lines.args$y <- spc [j, ispc[[i]]] [keep] lines.args$col <- col [j] - do.call (lines, lines.args) + do.call(lines, lines.args) } } } ## return some values that are needed by spc.identify - invisible (list (x = rep (unlist (x), each = nrow (spc)) , - y = spc, - wavelengths = rep (unlist (wavelengths), each = nrow (spc)) - ) - ) + invisible(list( + x = rep(unlist(x), each = nrow(spc)), + y = spc, + wavelengths = rep(unlist(wavelengths), each = nrow(spc)) + )) } @@ -534,181 +579,197 @@ plotspc <- function (object, ##' stacked.args = list (add.factor = .2)) ##' ##' -stacked.offsets <- function (x, stacked = TRUE, - min.zero = FALSE, add.factor = 0.05, add.sum = 0, - #tight = FALSE, TODO - .spc = NULL, debuglevel = hy.getOption("debuglevel")){ +stacked.offsets <- function(x, stacked = TRUE, + min.zero = FALSE, add.factor = 0.05, add.sum = 0, + # tight = FALSE, TODO + .spc = NULL, debuglevel = hy.getOption("debuglevel")) { lvl <- NULL - if (is.null (.spc)) + if (is.null(.spc)) { .spc <- x@data$spc + } - if (is.character (stacked)) - stacked <- unlist (x [[, stacked]]) - else if (isTRUE (stacked)) - stacked <- row.seq (x) + if (is.character(stacked)) { + stacked <- unlist(x [[, stacked]]) + } else if (isTRUE(stacked)) { + stacked <- row.seq(x) + } ## cut stacked if necessary - if (length (stacked) != nrow (.spc)){ - stacked <- rep (stacked, length.out = nrow (.spc)) - if (debuglevel >= 1L) - message ("stacking variable recycled to ", nrow (.spc), " values.") + if (length(stacked) != nrow(.spc)) { + stacked <- rep(stacked, length.out = nrow(.spc)) + if (debuglevel >= 1L) { + message("stacking variable recycled to ", nrow(.spc), " values.") + } + } + if (is.numeric(stacked)) { + stacked <- as.factor(stacked) + } else if (!is.factor(stacked)) { + stop("stacked must be either TRUE, the name of the extra data column to use for grouping, a factor or a numeric.") } - if (is.numeric (stacked)) - stacked <- as.factor (stacked) - else if (!is.factor (stacked)) - stop ("stacked must be either TRUE, the name of the extra data column to use for grouping, a factor or a numeric.") - stacked <- droplevels (stacked) - lvl <- levels (stacked) - groups <- seq_along (levels (stacked)) - stacked <- as.numeric (stacked) + stacked <- droplevels(stacked) + lvl <- levels(stacked) + groups <- seq_along(levels(stacked)) + stacked <- as.numeric(stacked) - offset <- matrix (nrow = 2, ncol = length (groups)) + offset <- matrix(nrow = 2, ncol = length(groups)) - for (i in groups) - offset[, i] <- range (.spc [stacked == groups [i], ], na.rm = TRUE) + for (i in groups) { + offset[, i] <- range(.spc [stacked == groups [i], ], na.rm = TRUE) + } ## should the minimum be at zero (or less)? - if (min.zero) - offset [1, ] <- sapply (offset [1, ], min, 0, na.rm = TRUE) + if (min.zero) { + offset [1, ] <- sapply(offset [1, ], min, 0, na.rm = TRUE) + } - offset [2,] <- offset[2,] - offset [1,] + offset [2, ] <- offset[2, ] - offset [1, ] ## add some extra space - offset [2,] <- offset [2, ] * (1 + add.factor) + add.sum + offset [2, ] <- offset [2, ] * (1 + add.factor) + add.sum - offset <- c(-offset[1,], 0) + c (0, cumsum (offset[2,])) + offset <- c(-offset[1, ], 0) + c(0, cumsum(offset[2, ])) - list (offsets = offset [seq_along (groups)], - groups = stacked, - levels = if (is.null (lvl)) stacked else lvl - ) + list( + offsets = offset [seq_along(groups)], + groups = stacked, + levels = if (is.null(lvl)) stacked else lvl + ) } ##' @include unittest.R -.test (stacked.offsets) <- function (){ - context ("stacked.offsets") +.test(stacked.offsets) <- function() { + context("stacked.offsets") test_that("ranges do not overlap", { - spc <- do.call (collapse, barbiturates [1:3]) - ofs <- stacked.offsets (spc) + spc <- do.call(collapse, barbiturates [1:3]) + ofs <- stacked.offsets(spc) spc <- spc + ofs$offsets - rngs <- apply (spc [[]], 1, range, na.rm = TRUE) + rngs <- apply(spc [[]], 1, range, na.rm = TRUE) - expect_equal (as.numeric (rngs), sort (rngs)) + expect_equal(as.numeric(rngs), sort(rngs)) }) test_that("extra space", { - spc <- new ("hyperSpec", spc = matrix (c (0, 0, 2, 1 : 3), nrow = 3)) + spc <- new("hyperSpec", spc = matrix(c(0, 0, 2, 1:3), nrow = 3)) - expect_equal (stacked.offsets (spc, add.factor = 0)$offsets, c (0, 1, 1)) - expect_equal (stacked.offsets (spc, add.factor = 1)$offsets, c (0, 2, 4)) - expect_equal (stacked.offsets (spc, add.factor = 0, add.sum = 1)$offsets, c (0, 2, 3)) + expect_equal(stacked.offsets(spc, add.factor = 0)$offsets, c(0, 1, 1)) + expect_equal(stacked.offsets(spc, add.factor = 1)$offsets, c(0, 2, 4)) + expect_equal(stacked.offsets(spc, add.factor = 0, add.sum = 1)$offsets, c(0, 2, 3)) }) test_that("min.zero", { - ofs <- stacked.offsets (flu, min.zero = TRUE, add.factor = 0) - expect_equal (ofs$offsets, - c (0, cumsum (apply (flu [[- nrow (flu)]], 1, max)))) + ofs <- stacked.offsets(flu, min.zero = TRUE, add.factor = 0) + expect_equal( + ofs$offsets, + c(0, cumsum(apply(flu [[-nrow(flu)]], 1, max))) + ) }) - - - } ### .axis.break - poor man's version of axis.break -.axis.break <- function (axis = 1,breakpos = NULL, ...) +.axis.break <- function(axis = 1, breakpos = NULL, ...) { mtext("//", at = breakpos, side = axis, padj = -1, adj = 0.5) +} -###.cut.ticks - pretty tick marks for cut axes +### .cut.ticks - pretty tick marks for cut axes ##' @importFrom utils head -.cut.ticks <- function (start.ranges, +.cut.ticks <- function(start.ranges, end.ranges, offsets, - nticks){ - stopifnot (length (start.ranges) == length (end.ranges) & - length (start.ranges) == length (offsets)) + nticks) { + stopifnot(length(start.ranges) == length(end.ranges) & + length(start.ranges) == length(offsets)) ## if (length (start.ranges) == 1) ## what part of the plot is occupied by each range? - part <- abs (end.ranges - start.ranges) / (max (end.ranges) - min (start.ranges) - max (offsets)) + part <- abs(end.ranges - start.ranges) / (max(end.ranges) - min(start.ranges) - max(offsets)) ## nice labels - labels <- mapply (function (start, end, part) pretty (c (start, end), part * nticks + 1), - start.ranges, end.ranges, part, - SIMPLIFY = FALSE) + labels <- mapply(function(start, end, part) pretty(c(start, end), part * nticks + 1), + start.ranges, end.ranges, part, + SIMPLIFY = FALSE + ) ## user coordinates - at <- mapply (`-`, labels, offsets, SIMPLIFY = FALSE) + at <- mapply(`-`, labels, offsets, SIMPLIFY = FALSE) ## cut marks ## convert to device x in user coordinates start.ranges <- start.ranges - offsets - end.ranges <- end.ranges - offsets + end.ranges <- end.ranges - offsets - delta <- start.ranges [-1] - head (end.ranges, -1) + delta <- start.ranges [-1] - head(end.ranges, -1) - cutmarks <- head (end.ranges, -1) + delta / 2 + cutmarks <- head(end.ranges, -1) + delta / 2 ## make sure that the ticks are not too close - for (i in seq_along (delta)) { - keep <- at [[i]] < end.ranges [i] + delta [i] / 4 - at [[i]] <- at [[i]][keep] + for (i in seq_along(delta)) { + keep <- at [[i]] < end.ranges [i] + delta [i] / 4 + at [[i]] <- at [[i]][keep] labels [[i]] <- labels [[i]][keep] - keep <- at [[i + 1]] > start.ranges [i + 1] - delta [i] / 4 - at [[i + 1]] <- at [[i + 1]][keep] + keep <- at [[i + 1]] > start.ranges [i + 1] - delta [i] / 4 + at [[i + 1]] <- at [[i + 1]][keep] labels [[i + 1]] <- labels [[i + 1]][keep] } - list (labels = as.numeric (unlist (labels)), - at = as.numeric (unlist (at)), - cut = cutmarks) + list( + labels = as.numeric(unlist(labels)), + at = as.numeric(unlist(at)), + cut = cutmarks + ) } ##' @include unittest.R -.test (.cut.ticks) <- function (){ - context (".cut.ticks") +.test(.cut.ticks) <- function() { + context(".cut.ticks") ## bugfix: ## plotspc (paracetamol, wl.range = c (min ~ 1800, 2800 ~ max), xoffset = 900) ## had 2600 1/cm label printed in low wavelength range - test_that("labels not too far outside wl.range",{ - expect_equal (.cut.ticks (start.ranges = c (96.7865, 2799.86), - end.ranges = c(1799.95, 3200.07), - offsets = c (0, 900), - nticks = 10)$labels, - c (seq (0, 1800, 200), seq (2800, 3400, 200)) + test_that("labels not too far outside wl.range", { + expect_equal( + .cut.ticks( + start.ranges = c(96.7865, 2799.86), + end.ranges = c(1799.95, 3200.07), + offsets = c(0, 900), + nticks = 10 + )$labels, + c(seq(0, 1800, 200), seq(2800, 3400, 200)) ) }) - test_that ("correct calculations",{ - - labels = c(seq (1, 2, 0.5), - seq (3, 4, 0.5), - seq (7, 9, 0.5)) - - expect_equal( - .cut.ticks(start.ranges = c (1, 3, 7), - end.ranges = c (2, 4, 9), - nticks = 10, - offsets = c (0, 0, 1)), - list (labels = labels, - at = labels - c (0, 0, 0, - 0, 0, 0, - 1, 1, 1, 1, 1), - cut = c (mean (c (3, 2)), - mean (c (7 - 1, 4))) + test_that("correct calculations", { + labels <- c( + seq(1, 2, 0.5), + seq(3, 4, 0.5), + seq(7, 9, 0.5) + ) + + expect_equal( + .cut.ticks( + start.ranges = c(1, 3, 7), + end.ranges = c(2, 4, 9), + nticks = 10, + offsets = c(0, 0, 1) + ), + list( + labels = labels, + at = labels - c( + 0, 0, 0, + 0, 0, 0, + 1, 1, 1, 1, 1 + ), + cut = c( + mean(c(3, 2)), + mean(c(7 - 1, 4)) + ) + ) ) - ) }) - - } - - - diff --git a/hyperSpec/R/plotvoronoi.R b/hyperSpec/R/plotvoronoi.R index 17f3fea58..b2cb2dacd 100644 --- a/hyperSpec/R/plotvoronoi.R +++ b/hyperSpec/R/plotvoronoi.R @@ -1,7 +1,7 @@ ################################################################################# ### ### plotvoronoi - plot spectral maps with irregular point pattern -### +### ### plots intensity or extra data column over 2 extra data columns ##' @param use.tripack Whether package tripack should be used for calculating @@ -17,30 +17,38 @@ ##' @importFrom latticeExtra panel.voronoi ##' @importFrom lattice prepanel.default.levelplot ##' @importFrom utils modifyList -plotvoronoi <- function (object, model = spc ~ x * y, - use.tripack = FALSE, mix = FALSE, ...){ - if (!requireNamespace ("latticeExtra")) - stop ("package latticeExtra is needed for Voronoi plots.") +plotvoronoi <- function(object, model = spc ~ x * y, + use.tripack = FALSE, mix = FALSE, ...) { + if (!requireNamespace("latticeExtra")) { + stop("package latticeExtra is needed for Voronoi plots.") + } - if (use.tripack){ - if (!requireNamespace ("tripack")) - stop ("package tripack requested but not available.") + if (use.tripack) { + if (!requireNamespace("tripack")) { + stop("package tripack requested but not available.") + } } else { - if (!requireNamespace ("deldir")) - stop ("package deldir requested but not available.") + if (!requireNamespace("deldir")) { + stop("package deldir requested but not available.") + } + } + + if (use.tripack && mix) { + object@data <- object@data [sample(nrow(object)), ] } - - if (use.tripack && mix) - object@data <- object@data [sample (nrow (object)),] - dots <- modifyList (list (object = object, - model = model, - panel = panel.voronoi, - prepanel = prepanel.default.levelplot, - pch = 19, cex = .25, - col.symbol = "#00000020", - border = "#00000020", - use.tripack = use.tripack), - list (...)) - do.call (plotmap, dots) + dots <- modifyList( + list( + object = object, + model = model, + panel = panel.voronoi, + prepanel = prepanel.default.levelplot, + pch = 19, cex = .25, + col.symbol = "#00000020", + border = "#00000020", + use.tripack = use.tripack + ), + list(...) + ) + do.call(plotmap, dots) } diff --git a/hyperSpec/R/qplot.R b/hyperSpec/R/qplot.R index 222f80ca4..39af9d8fc 100644 --- a/hyperSpec/R/qplot.R +++ b/hyperSpec/R/qplot.R @@ -29,51 +29,58 @@ ##' qplotspc (aggregate (chondro, chondro$clusters, mean_pm_sd), ##' mapping = aes (x = .wavelength, y = spc, colour = clusters, group = .rownames)) + ##' facet_grid (clusters ~ .) -qplotspc <- function (x, - wl.range = TRUE, ..., - mapping = aes_string (x = ".wavelength", y = "spc", group = ".rownames"), - spc.nmax = hy.getOption("ggplot.spc.nmax"), - map.lineonly = FALSE, - debuglevel = hy.getOption("debuglevel")){ - chk.hy (x) - validObject (x) +qplotspc <- function(x, + wl.range = TRUE, ..., + mapping = aes_string(x = ".wavelength", y = "spc", group = ".rownames"), + spc.nmax = hy.getOption("ggplot.spc.nmax"), + map.lineonly = FALSE, + debuglevel = hy.getOption("debuglevel")) { + chk.hy(x) + validObject(x) ## cut away everything that isn't asked for _before_ transforming to data.frame - if (nrow (x) > spc.nmax) { - if (debuglevel >= 1L) - message ("Number of spectra exceeds spc.nmax. Only the first ", spc.nmax, " are plotted.") - x <- x [seq_len (spc.nmax)] + if (nrow(x) > spc.nmax) { + if (debuglevel >= 1L) { + message("Number of spectra exceeds spc.nmax. Only the first ", spc.nmax, " are plotted.") + } + x <- x [seq_len(spc.nmax)] } - wl.range <- wl2i (x, wl.range, unlist = FALSE) - - x <- x [,, unlist (wl.range), wl.index = TRUE] - - df <- as.long.df (x, rownames = TRUE, na.rm = FALSE) # with na.rm trouble with wl.range + wl.range <- wl2i(x, wl.range, unlist = FALSE) + + x <- x [, , unlist(wl.range), wl.index = TRUE] + + df <- as.long.df(x, rownames = TRUE, na.rm = FALSE) # with na.rm trouble with wl.range ## ranges go into facets - if (length (wl.range) > 1L){ + if (length(wl.range) > 1L) { tmp <- wl.range - for (r in seq_along(tmp)) + for (r in seq_along(tmp)) { tmp [[r]][TRUE] <- r - - df$.wl.range <- rep (unlist (tmp), each = nrow (x)) + } + + df$.wl.range <- rep(unlist(tmp), each = nrow(x)) + } + + + df <- df [!is.na(df$spc), , drop = FALSE] + if (map.lineonly) { + p <- ggplot(df) + + geom_line(mapping = mapping, ...) + } else { + p <- ggplot(df, mapping = mapping) + + geom_line(...) } - - - df <- df [! is.na (df$spc),, drop = FALSE] - if (map.lineonly) - p <- ggplot (df) + geom_line (mapping = mapping, ...) - else - p <- ggplot (df, mapping = mapping) + geom_line (...) - p <- p + xlab (labels (x, ".wavelength")) + ylab (labels (x, "spc")) + p <- p + xlab(labels(x, ".wavelength")) + ylab(labels(x, "spc")) - if (! is.null (df$.wl.range)) - p <- p + facet_grid (. ~ .wl.range, - labeller = as_labeller (rep (NA, nlevels (df$.wl.range))), - scales = "free", space = "free") + - theme (strip.text.x = element_text (size = 0)) + if (!is.null(df$.wl.range)) { + p <- p + facet_grid(. ~ .wl.range, + labeller = as_labeller(rep(NA, nlevels(df$.wl.range))), + scales = "free", space = "free" + ) + + theme(strip.text.x = element_text(size = 0)) + } p } @@ -102,48 +109,54 @@ qplotspc <- function (x, ##' qplotmap (chondro) ##' qplotmap (chondro) + scale_fill_gradientn (colours = alois.palette ()) ##' @importFrom utils tail -qplotmap <- function (object, mapping = aes_string (x = "x", y = "y", fill = "spc"), ..., - func = mean, func.args = list (), - map.tileonly = FALSE){ - chk.hy (object) - validObject (object) - - if (nwl (object) > 1 & ! is.null (func)) - object <- do.call (apply, c (list (object, 1, func), func.args)) +qplotmap <- function(object, mapping = aes_string(x = "x", y = "y", fill = "spc"), ..., + func = mean, func.args = list(), + map.tileonly = FALSE) { + chk.hy(object) + validObject(object) + + if (nwl(object) > 1 & !is.null(func)) { + object <- do.call(apply, c(list(object, 1, func), func.args)) + } - if (map.tileonly) - p <- ggplot (as.long.df (object)) + geom_tile (mapping = mapping) - else - p <- ggplot (as.long.df (object), mapping = mapping) + geom_tile () + if (map.tileonly) { + p <- ggplot(as.long.df(object)) + + geom_tile(mapping = mapping) + } else { + p <- ggplot(as.long.df(object), mapping = mapping) + + geom_tile() + } - p <- p + coord_equal () + p <- p + coord_equal() ## set expand to c(0, 0) to suppress the gray backgroud - if (is.factor (with (p$data, eval (p$mapping$x)))) - p <- p + scale_x_discrete (expand = c(0, 0)) - else - p <- p + scale_x_continuous (expand = c(0, 0)) + if (is.factor(with(p$data, eval(p$mapping$x)))) { + p <- p + scale_x_discrete(expand = c(0, 0)) + } else { + p <- p + scale_x_continuous(expand = c(0, 0)) + } - if (is.factor (with (p$data, eval (p$mapping$y)))) - p <- p + scale_y_discrete (expand = c(0, 0)) - else - p <- p + scale_y_continuous (expand = c(0, 0)) + if (is.factor(with(p$data, eval(p$mapping$y)))) { + p <- p + scale_y_discrete(expand = c(0, 0)) + } else { + p <- p + scale_y_continuous(expand = c(0, 0)) + } ## generate axis/scale labels ## TODO: own function - x <- as.character (mapping$x) - xlabel <- labels (object)[[tail (x, 1)]] - if (is.null (xlabel)) xlabel <- x + x <- as.character(mapping$x) + xlabel <- labels(object)[[tail(x, 1)]] + if (is.null(xlabel)) xlabel <- x - y <- as.character (mapping$y) - ylabel <- labels (object)[[tail (y, 1)]] - if (is.null (ylabel)) ylabel <- y + y <- as.character(mapping$y) + ylabel <- labels(object)[[tail(y, 1)]] + if (is.null(ylabel)) ylabel <- y - f <- as.character (mapping$fill) - flabel <- labels (object)[[tail (f, 1)]] - if (is.null (flabel)) flabel <- f + f <- as.character(mapping$fill) + flabel <- labels(object)[[tail(f, 1)]] + if (is.null(flabel)) flabel <- f - p + labs (x = xlabel, y = ylabel, fill = flabel) + p + labs(x = xlabel, y = ylabel, fill = flabel) } @@ -167,72 +180,82 @@ qplotmap <- function (object, mapping = aes_string (x = "x", y = "y", fill = "sp ##' @examples ##' qplotc (flu) ##' qplotc (flu) + geom_smooth (method = "lm") -qplotc <- function (object, mapping = aes_string(x = "c", y = "spc"), ..., - func = NULL, func.args = list (), - map.pointonly = FALSE){ - chk.hy (object) - validObject (object) +qplotc <- function(object, mapping = aes_string(x = "c", y = "spc"), ..., + func = NULL, func.args = list(), + map.pointonly = FALSE) { + chk.hy(object) + validObject(object) - dots <- list (...) + dots <- list(...) - if (! is.null (func)) - object <- do.call (apply, c (list (object, 1, func), func.args)) + if (!is.null(func)) { + object <- do.call(apply, c(list(object, 1, func), func.args)) + } ## allow to plot against the row number - object$.row <- seq (object, index = TRUE) + object$.row <- seq(object, index = TRUE) ## find out whether the wavelengths are needed individually, ## if not, use only the first wavelength and issue a warning - if (any (grepl ("spc", as.character (mapping))) && # use intensities - nwl (object) > 1 && # has > 1 wavelength - is.null (func) && # no stats function - ! any (grepl ("[.]wavelength", as.character (mapping)))) { - object <- object [,, 1, wl.index = TRUE] - warning ("Intensity at first wavelengh only is used.") + if (any(grepl("spc", as.character(mapping))) && # use intensities + nwl(object) > 1 && # has > 1 wavelength + is.null(func) && # no stats function + !any(grepl("[.]wavelength", as.character(mapping)))) { + object <- object [, , 1, wl.index = TRUE] + warning("Intensity at first wavelengh only is used.") } ## produce fancy y label - ylab <- labels (object, as.character (mapping$y)) - if (! is.null (func)) - ylab <- make.fn.expr (substitute (func), c (ylab, func.args)) - ylab <- as.expression (ylab) + ylab <- labels(object, as.character(mapping$y)) + if (!is.null(func)) { + ylab <- make.fn.expr(substitute(func), c(ylab, func.args)) + } + ylab <- as.expression(ylab) ## expand the data.frame - df <- as.long.df (object, rownames = TRUE, wl.factor = TRUE) + df <- as.long.df(object, rownames = TRUE, wl.factor = TRUE) ## if plots should be grouped, faceted, etc. by wavelength, it is better to have a factor - if (any (grepl ("[.]wavelength", mapping [! names (mapping) %in% c("x", "y")]))) - df$.wavelength <- as.factor (df$.wavelength) + if (any(grepl("[.]wavelength", mapping [!names(mapping) %in% c("x", "y")]))) { + df$.wavelength <- as.factor(df$.wavelength) + } - if (map.pointonly) - p <- ggplot (df) + geom_point (mapping = mapping) - else - p <- ggplot (df, mapping = mapping) + geom_point () + if (map.pointonly) { + p <- ggplot(df) + + geom_point(mapping = mapping) + } else { + p <- ggplot(df, mapping = mapping) + + geom_point() + } - p + ylab (ylab) + - xlab (labels (object, as.character (mapping$x))) + p + ylab(ylab) + + xlab(labels(object, as.character(mapping$x))) } -make.fn.expr <- function (fn, l = list ()){ - - if (length (fn) > 1L) +make.fn.expr <- function(fn, l = list()) { + if (length(fn) > 1L) { fn <- "f" + } - l <- lapply (l, function (x) if (is.logical (x)) as.character (x) else x) + l <- lapply(l, function(x) if (is.logical(x)) as.character(x) else x) - if (is.null (names (l))) - names (l) <- rep ("", length (l)) + if (is.null(names(l))) { + names(l) <- rep("", length(l)) + } - tmp <- mapply (function (x, y) if (nzchar (x) > 0L) bquote (.(x) == .(y)) else y, - names (l), l) + tmp <- mapply( + function(x, y) if (nzchar(x) > 0L) bquote(.(x) == .(y)) else y, + names(l), l + ) - e <- expression (f (x)) + e <- expression(f(x)) e [[1]][[1]] <- fn - if (length (tmp) > 0L) - e [[1]][seq_along (tmp) + 1] <- tmp - else + if (length(tmp) > 0L) { + e [[1]][seq_along(tmp) + 1] <- tmp + } else { e [[1]][2] <- NULL + } e } diff --git a/hyperSpec/R/qplotmixmap.R b/hyperSpec/R/qplotmixmap.R index aaf915de4..91b27704e 100644 --- a/hyperSpec/R/qplotmixmap.R +++ b/hyperSpec/R/qplotmixmap.R @@ -1,6 +1,6 @@ ##' map plot with colour overlay. ##' -##' +##' ##' @title qplotmap with colour mixing for multivariate overlay ##' @param object hyperSpec object ##' @param ... handed over to \code{\link[hyperSpec]{qmixlegend}} and \code{\link[hyperSpec]{qmixtile}} @@ -14,31 +14,31 @@ ##' chondro <- chondro - spc.fit.poly.below (chondro) ##' chondro <- sweep (chondro, 1, apply (chondro, 1, mean), "/") ##' chondro <- sweep (chondro, 2, apply (chondro, 2, quantile, 0.05), "-") -##' +##' ##' qplotmixmap (chondro [,,c (940, 1002, 1440)], ##' purecol = c (colg = "red", Phe = "green", Lipid = "blue")) -##' +##' ##' @importFrom lazyeval f_rhs -qplotmixmap <- function (object, ...){ - - p <- qmixtile (object@data, ...) + - coord_equal () - - ## ggplot2 transition to lazyeval of mappings. Use `tmp.cnv` conversion function depending on ggplot2 behaviour - if (is.name (p$mapping$x)) # old ggplot2 - tmp.cnv <- as.character - else # new ggplot2 -> lazyeval - tmp.cnv <- f_rhs - +qplotmixmap <- function(object, ...) { + p <- qmixtile(object@data, ...) + + coord_equal() + + ## ggplot2 transition to lazyeval of mappings. Use `tmp.cnv` conversion function depending on ggplot2 behaviour + if (is.name(p$mapping$x)) { # old ggplot2 + tmp.cnv <- as.character + } else { # new ggplot2 -> lazyeval + tmp.cnv <- f_rhs + } + p <- p + - xlab (labels (object)[[tmp.cnv (p$mapping$x)]]) + - ylab (labels (object)[[tmp.cnv (p$mapping$y)]]) + xlab(labels(object)[[tmp.cnv(p$mapping$x)]]) + + ylab(labels(object)[[tmp.cnv(p$mapping$y)]]) - l <- qmixlegend (object@data$spc, ...) + l <- qmixlegend(object@data$spc, ...) - legendright (p, l) + legendright(p, l) - invisible (list (map = p, legend = l)) + invisible(list(map = p, legend = l)) } ##' Plot multivariate data into colour channels @@ -51,17 +51,17 @@ qplotmixmap <- function (object, ...){ ##' @return invisible \code{NULL} ##' @author Claudia Beleites ##' @rdname qplotmix -##' @export -legendright <- function (p, l, legend.width = 8, legend.unit = "lines") { - plot.new () - pushViewport (viewport (layout = grid.layout (1, 2, - widths = unit (c (1, legend.width), c("null", legend.unit)) - ))) - print (p, viewport (layout.pos.col = 1), newpage = FALSE) - print (l, viewport (layout.pos.col = 2), newpage = FALSE) - popViewport () +##' @export +legendright <- function(p, l, legend.width = 8, legend.unit = "lines") { + plot.new() + pushViewport(viewport(layout = grid.layout(1, 2, + widths = unit(c(1, legend.width), c("null", legend.unit)) + ))) + print(p, viewport(layout.pos.col = 1), newpage = FALSE) + print(l, viewport(layout.pos.col = 2), newpage = FALSE) + popViewport() } - + ##' plot multivariate data into colour channels using \code{\link[ggplot2]{geom_tile}} ##' @rdname qplotmix ##' @param object matrix to be plotted with mixed colour channels @@ -72,88 +72,98 @@ legendright <- function (p, l, legend.width = 8, legend.unit = "lines") { ##' \code{qmixlegend} and \code{colmix.rgb} hand further arguments to the \code{normalize} function ##' @param map.tileonly if \code{TRUE}, \code{mapping} will be handed to ##' \code{\link[ggplot2]{geom_tile}} instead of \code{\link[ggplot2]{ggplot}}. -##' -qmixtile <- function (object, - purecol = stop ("pure component colors needed."), - mapping = aes_string (x = "x", y = "y", fill = "spc"), - ..., - map.tileonly = FALSE) { +##' +qmixtile <- function(object, + purecol = stop("pure component colors needed."), + mapping = aes_string(x = "x", y = "y", fill = "spc"), + ..., + map.tileonly = FALSE) { ## ggplot2 transition to lazyeval of mappings. Use `tmp.cnv` conversion function depending on ggplot2 behaviour - if (is.name (mapping$fill)) # old ggplot2 + if (is.name(mapping$fill)) { # old ggplot2 tmp.cnv <- as.character - else # new ggplot2 -> lazyeval - tmp.cnv <- f_rhs - - + } else { # new ggplot2 -> lazyeval + tmp.cnv <- f_rhs + } + + ## calculate fill colours - fill <- colmix.rgb (object [[tmp.cnv (mapping$fill)]], purecol, ...) - object [[tmp.cnv (mapping$fill)]] <- fill + fill <- colmix.rgb(object [[tmp.cnv(mapping$fill)]], purecol, ...) + object [[tmp.cnv(mapping$fill)]] <- fill - if (map.tileonly) - p <- ggplot (object) + geom_tile (mapping = mapping, data = object) - else - p <- ggplot (object, mapping = mapping) + geom_tile () + if (map.tileonly) { + p <- ggplot(object) + + geom_tile(mapping = mapping, data = object) + } else { + p <- ggplot(object, mapping = mapping) + + geom_tile() + } - p + scale_fill_identity () + theme (legend.position = "none") + p + scale_fill_identity() + theme(legend.position = "none") } ##' \code{normalize.colrange} normalizes the range of each column to [0, 1] ##' @rdname qplotmix ##' @export -##' +##' ##' @param na.rm see \code{link[base]{min}} ##' @param legend should a legend be produced instead of normalized values? ##' @param n of colours to produce in legend ##' @return list with components ymin, max and fill to specify value and fill colour value (still ##' numeric!) for the legend, otherwise the normalized values -normalize.colrange <- function (x, na.rm = TRUE, legend = FALSE, n = 100, ...){ +normalize.colrange <- function(x, na.rm = TRUE, legend = FALSE, n = 100, ...) { ## legend - if (legend){ - y <- apply (x, 2, function (x) seq (min (x), max (x), length.out = n)) - dy2 <- abs (y [2,] - y [1,]) / 2 + if (legend) { + y <- apply(x, 2, function(x) seq(min(x), max(x), length.out = n)) + dy2 <- abs(y [2, ] - y [1, ]) / 2 - list (ymin = sweep (y, 2, dy2, `-`), - ymax = sweep (y, 2, dy2, `+`), - fill = apply (x, 2, function (x) seq ( 0, 1, length.out = n))) + list( + ymin = sweep(y, 2, dy2, `-`), + ymax = sweep(y, 2, dy2, `+`), + fill = apply(x, 2, function(x) seq(0, 1, length.out = n)) + ) } else { ## normalized values - x <- sweep (x, 2, apply (x, 2, min, na.rm = na.rm), `-`) - sweep (x, 2, apply (x, 2, max, na.rm = na.rm), `/`) + x <- sweep(x, 2, apply(x, 2, min, na.rm = na.rm), `-`) + sweep(x, 2, apply(x, 2, max, na.rm = na.rm), `/`) } } ##' \code{normalize.range} normalizes the range of all columns to [0, 1] ##' @rdname qplotmix ##' @export -##' -normalize.range <- function (x, na.rm = TRUE, legend = FALSE, n = 100, ...){ - if (legend){ - y <- matrix (seq (min (x), max (x), length.out = n), nrow = n, ncol = ncol (x)) - dy2 <- abs (y [2,] - y [1,]) / 2 - - list (ymin = sweep (y, 2, dy2, `-`), - ymax = sweep (y, 2, dy2, `+`), - fill = apply (x, 2, function (x) seq ( 0, 1, length.out = n))) +##' +normalize.range <- function(x, na.rm = TRUE, legend = FALSE, n = 100, ...) { + if (legend) { + y <- matrix(seq(min(x), max(x), length.out = n), nrow = n, ncol = ncol(x)) + dy2 <- abs(y [2, ] - y [1, ]) / 2 + + list( + ymin = sweep(y, 2, dy2, `-`), + ymax = sweep(y, 2, dy2, `+`), + fill = apply(x, 2, function(x) seq(0, 1, length.out = n)) + ) } else { - x <- x - min (x, na.rm = na.rm) - x / max (x, na.rm = na.rm) + x <- x - min(x, na.rm = na.rm) + x / max(x, na.rm = na.rm) } } -##' \code{normalize.null} does not touch the values +##' \code{normalize.null} does not touch the values ##' @rdname qplotmix ##' @export -##' -normalize.null <- function (x, na.rm = TRUE, legend = FALSE, n = 100, ...){ - if (legend){ - y <- apply (x, 2, function (x) seq (min (x), max (x), length.out = n)) - - list (ymin = sweep (y, 2, min), - ymax = sweep (y, 2, max), - fill = apply (x, 2, function (x) seq ( 0, 1, length.out = n))) +##' +normalize.null <- function(x, na.rm = TRUE, legend = FALSE, n = 100, ...) { + if (legend) { + y <- apply(x, 2, function(x) seq(min(x), max(x), length.out = n)) + + list( + ymin = sweep(y, 2, min), + ymax = sweep(y, 2, max), + fill = apply(x, 2, function(x) seq(0, 1, length.out = n)) + ) } else { - x + x } } ##' \code{normalize.minmax} normalizes the range of each column j to [min_j, max_j] @@ -161,26 +171,28 @@ normalize.null <- function (x, na.rm = TRUE, legend = FALSE, n = 100, ...){ ##' @export ##' @param min numeric with value corresponding to "lowest" colour for each column ##' @param max numeric with value corresponding to "hightest" colour for each column -normalize.minmax <- function (x, min = 0, max = 1, legend = FALSE, n = 100, ...){ - if (legend){ - y <- matrix (seq (0, 1, length.out = n), nrow = n, ncol = ncol (x)) - y <- sweep (y, 2, max - min, `*`) - y <- sweep (y, 2, min, `+`) - - dy2 <- abs (y [2,] - y [1,]) / 2 - - l <- list (ymin = sweep (y, 2, dy2, `-`), - ymax = sweep (y, 2, dy2, `+`), - ymax = y + dy2, - fill = matrix (seq (0, 1, length.out = n), nrow = n, ncol = ncol (x))) - - l$ymin [1, ] <- pmin (l$ymin [1,], apply (x, 2, min, na.rm = TRUE)) - l$ymax [n, ] <- pmax (l$ymax [n,], apply (x, 2, max, na.rm = TRUE)) +normalize.minmax <- function(x, min = 0, max = 1, legend = FALSE, n = 100, ...) { + if (legend) { + y <- matrix(seq(0, 1, length.out = n), nrow = n, ncol = ncol(x)) + y <- sweep(y, 2, max - min, `*`) + y <- sweep(y, 2, min, `+`) + + dy2 <- abs(y [2, ] - y [1, ]) / 2 + + l <- list( + ymin = sweep(y, 2, dy2, `-`), + ymax = sweep(y, 2, dy2, `+`), + ymax = y + dy2, + fill = matrix(seq(0, 1, length.out = n), nrow = n, ncol = ncol(x)) + ) + + l$ymin [1, ] <- pmin(l$ymin [1, ], apply(x, 2, min, na.rm = TRUE)) + l$ymax [n, ] <- pmax(l$ymax [n, ], apply(x, 2, max, na.rm = TRUE)) l } else { - x <- sweep (x, 2, min, `-`) - sweep (x, 2, max, `/`) + x <- sweep(x, 2, min, `-`) + sweep(x, 2, max, `/`) } } @@ -191,42 +203,51 @@ normalize.minmax <- function (x, min = 0, max = 1, legend = FALSE, n = 100, ...) ##' @param labels component names ##' @return ggplot object with legend ##' @author Claudia Beleites -##' @export -qmixlegend <- function (x, purecol, dx = 0.33, ny = 100, labels = names (purecol), - normalize = normalize.colrange, ...) { - if (! is.matrix (x)) - x <- matrix (x, ncol = 1) - - if (is.null (labels)) - labels <- colnames (x) - if (is.null (labels)) - labels <- seq_len (ncol (x)) - - if (! is.null (normalize)) - l <- normalize (x, ..., legend = TRUE) - else - l <- x - - df <- data.frame () - for (column in seq_along (purecol)){ - tmp <- colmix.rgb (l$fill [, column, drop = FALSE], purecol [column], normalize = NULL, ...) - df <- rbind (df, data.frame (column = labels [column], - col = tmp, - ymin = l$ymin [, column], - ymax = l$ymax [, column]) - ) +##' @export +qmixlegend <- function(x, purecol, dx = 0.33, ny = 100, labels = names(purecol), + normalize = normalize.colrange, ...) { + if (!is.matrix(x)) { + x <- matrix(x, ncol = 1) } - df$column <- as.factor (df$column) - df$xmin <- as.numeric (df$column) - dx - df$xmax <- as.numeric (df$column) + dx - l <- ggplot (df, aes (x = column), col = col) + - geom_point (aes (x=column, y = 1), col = NA) + ylab ("") + xlab ("") - l <- l + geom_rect (aes_string (xmin = "xmin", xmax = "xmax", ymin = "ymin", ymax = "ymax", - fill = "col", colour = "col")) + if (is.null(labels)) { + labels <- colnames(x) + } + if (is.null(labels)) { + labels <- seq_len(ncol(x)) + } - l <- l + theme (plot.margin = unit(c(0.5, 0, 0 ,0), "lines"), legend.position = "none") + - scale_fill_identity () + scale_colour_identity () + if (!is.null(normalize)) { + l <- normalize(x, ..., legend = TRUE) + } else { + l <- x + } + + df <- data.frame() + for (column in seq_along(purecol)) { + tmp <- colmix.rgb(l$fill [, column, drop = FALSE], purecol [column], normalize = NULL, ...) + df <- rbind(df, data.frame( + column = labels [column], + col = tmp, + ymin = l$ymin [, column], + ymax = l$ymax [, column] + )) + } + df$column <- as.factor(df$column) + df$xmin <- as.numeric(df$column) - dx + df$xmax <- as.numeric(df$column) + dx + + l <- ggplot(df, aes(x = column), col = col) + + geom_point(aes(x = column, y = 1), col = NA) + + ylab("") + + xlab("") + l <- l + geom_rect(aes_string( + xmin = "xmin", xmax = "xmax", ymin = "ymin", ymax = "ymax", + fill = "col", colour = "col" + )) + + l <- l + theme(plot.margin = unit(c(0.5, 0, 0, 0), "lines"), legend.position = "none") + + scale_fill_identity() + scale_colour_identity() l } @@ -241,24 +262,27 @@ qmixlegend <- function (x, purecol, dx = 0.33, ny = 100, labels = names (purecol ##' @author Claudia Beleites ##' @export ##' @importFrom grDevices col2rgb rgb -colmix.rgb <- function (x, purecol, against = 1, sub = TRUE, - normalize = normalize.colrange, ...){ - if (! is.null (normalize)) - x <- normalize (x, ...) +colmix.rgb <- function(x, purecol, against = 1, sub = TRUE, + normalize = normalize.colrange, ...) { + if (!is.null(normalize)) { + x <- normalize(x, ...) + } - if (is.character (purecol)) - purecol <- t (col2rgb (purecol)) / 255 + if (is.character(purecol)) { + purecol <- t(col2rgb(purecol)) / 255 + } - if (sub) + if (sub) { x <- against - x %*% (against - purecol) - else + } else { x <- x %*% purecol - + } + x [x < 0] <- 0 x [x > 1] <- 1 - cols <- rep (NA, nrow (x)) - cols [! is.na (x [,1])] <- rgb (x [!is.na (x [, 1]),]) + cols <- rep(NA, nrow(x)) + cols [!is.na(x [, 1])] <- rgb(x [!is.na(x [, 1]), ]) cols } diff --git a/hyperSpec/R/quantile.R b/hyperSpec/R/quantile.R index 348bb8c3e..fe9225066 100644 --- a/hyperSpec/R/quantile.R +++ b/hyperSpec/R/quantile.R @@ -1,17 +1,23 @@ -.quantile <- function (x, probs = seq(0, 1, 0.5), na.rm = TRUE, names = "num", ...){ - - x <- apply (x, 2, quantile, probs = probs, na.rm = na.rm, names = FALSE, ..., - long = list (probs = probs, na.rm = na.rm, names = names, ...)) - - if (names == "pretty") - rownames (x@data) <- paste (format (100 * probs, format = "fg", width = 1, - justify = "right", - digits = getOption ("digits")), - "%") - else if (names == "num") - rownames (x@data) <- probs - - x +.quantile <- function(x, probs = seq(0, 1, 0.5), na.rm = TRUE, names = "num", ...) { + x <- apply(x, 2, quantile, + probs = probs, na.rm = na.rm, names = FALSE, ..., + long = list(probs = probs, na.rm = na.rm, names = names, ...) + ) + + if (names == "pretty") { + rownames(x@data) <- paste( + format(100 * probs, + format = "fg", width = 1, + justify = "right", + digits = getOption("digits") + ), + "%" + ) + } else if (names == "num") { + rownames(x@data) <- probs + } + + x } ##' @rdname mean_sd @@ -24,6 +30,6 @@ ##' @seealso \code{\link[stats]{quantile}} ##' @export ##' @examples -##' +##' ##' plot (quantile (chondro)) -setMethod ("quantile", signature = signature (x = "hyperSpec"), .quantile) +setMethod("quantile", signature = signature(x = "hyperSpec"), .quantile) diff --git a/hyperSpec/R/rbind.fill.R b/hyperSpec/R/rbind.fill.R index 9aa30afb4..6b90b6c59 100644 --- a/hyperSpec/R/rbind.fill.R +++ b/hyperSpec/R/rbind.fill.R @@ -1,4 +1,4 @@ -### plyr has rbind.fill for matrices now. We keep with our version to avoid the +### plyr has rbind.fill for matrices now. We keep with our version to avoid the ### dependency, but do not export it anymore. @@ -10,14 +10,16 @@ ##' @param list list to convert to data frame ##' @keywords internal quickdf <- function(list) { - if (is.matrix (list [[1]])) - n <- nrow (list [[1]]) - else - n <- length (list [[1]]) - + if (is.matrix(list [[1]])) { + n <- nrow(list [[1]]) + } else { + n <- length(list [[1]]) + } + structure(list, class = "data.frame", - row.names = seq_len(n)) + row.names = seq_len(n) + ) } ##' Bind matrices by row, and fill missing columns with NA @@ -44,73 +46,77 @@ quickdf <- function(list) { ##' @seealso \code{\link[base]{rbind}}, \code{\link[base]{cbind}}, \code{\link[plyr]{rbind.fill}} ##' @keywords manip ##' @rdname rbind.fill -##' @examples +##' @examples ##' A <- matrix (1:4, 2) ##' B <- matrix (6:11, 2) ##' A ##' B ##' hyperSpec:::rbind.fill.matrix (A, B) -##' +##' ##' colnames (A) <- c (3, 1) ##' A ##' hyperSpec:::rbind.fill.matrix (A, B) ##' ##' hyperSpec:::rbind.fill.matrix (A, 99) -##' +##' ##' @return a matrix ##' @method rbind.fill matrix -rbind.fill.matrix <- function (...){ - matrices <- list (...) - +rbind.fill.matrix <- function(...) { + matrices <- list(...) + ## check the arguments - tmp <- unlist (lapply (matrices, is.factor)) - if (any (tmp)) - stop ("Input ", paste (which (tmp), collapse = ", "), - " is a factor and needs to be converted first to either numeric or character.") - - tmp <- ! unlist (lapply (matrices, is.matrix)) - matrices [tmp] <- lapply (matrices [tmp], as.matrix) - - ## if the matrices have column names, use them - lcols <- lapply (matrices, .cols) - cols <- unique (unlist (lcols)) + tmp <- unlist(lapply(matrices, is.factor)) + if (any(tmp)) { + stop( + "Input ", paste(which(tmp), collapse = ", "), + " is a factor and needs to be converted first to either numeric or character." + ) + } + + tmp <- !unlist(lapply(matrices, is.matrix)) + matrices [tmp] <- lapply(matrices [tmp], as.matrix) + + ## if the matrices have column names, use them + lcols <- lapply(matrices, .cols) + cols <- unique(unlist(lcols)) ## the new row positions - pos <- unlist (lapply (matrices, nrow)) # Hadley, for me nrow is about twice as fast as - # .row_names_info (for matrices), the other way round for - # data.frame + pos <- unlist(lapply(matrices, nrow)) # Hadley, for me nrow is about twice as fast as + # .row_names_info (for matrices), the other way round for + # data.frame ## preallocate the new spectra matrix - result <- matrix (NA, nrow = sum (pos), ncol = length (cols)) + result <- matrix(NA, nrow = sum(pos), ncol = length(cols)) ## make an index vector for the row positions - pos <- c (0, cumsum (pos)) + pos <- c(0, cumsum(pos)) - ## fill in the new matrix - for (i in seq_along (matrices)){ - icols <- match (lcols[[i]], cols) - result [(pos [i] + 1) : pos [i + 1], icols] <- matrices [[i]] + ## fill in the new matrix + for (i in seq_along(matrices)) { + icols <- match(lcols[[i]], cols) + result [(pos [i] + 1):pos [i + 1], icols] <- matrices [[i]] } - colnames (result) <- cols - + colnames(result) <- cols + result } -.cols <- function (x){ - cln <- colnames (x) - if (is.null (cln)) - cln <- make.names (seq_len (ncol (x)), unique = TRUE) +.cols <- function(x) { + cln <- colnames(x) + if (is.null(cln)) { + cln <- make.names(seq_len(ncol(x)), unique = TRUE) + } cln } ##' Combine objects by row, filling in missing columns. ##' \code{rbind}s a list of data frames filling missing columns with NA. -##' +##' ##' This is an enhancement to \code{\link{rbind}} which adds in columns -##' that are not present in all inputs, accepts a list of data frames, and +##' that are not present in all inputs, accepts a list of data frames, and ##' operates substantially faster -##' +##' ##' @param ... data frames/matrices to row bind together ##' @keywords manip ##' @rdname rbind.fill @@ -118,38 +124,42 @@ rbind.fill.matrix <- function (...){ ##' #' rbind.fill(mtcars[c("mpg", "wt")], mtcars[c("wt", "cyl")]) rbind.fill <- function(...) { dfs <- list(...) - if (length(dfs) == 0) return(list()) + if (length(dfs) == 0) { + return(list()) + } if (is.list(dfs[[1]]) && !is.data.frame(dfs[[1]])) { dfs <- dfs[[1]] } - dfs <- dfs [!sapply (dfs, is.null)] # compact(dfs) -> dependency plyr. - - if (length(dfs) == 1) return(dfs[[1]]) - + dfs <- dfs [!sapply(dfs, is.null)] # compact(dfs) -> dependency plyr. + + if (length(dfs) == 1) { + return(dfs[[1]]) + } + # About 6 times faster than using nrow rows <- unlist(lapply(dfs, .row_names_info, 2L)) nrows <- sum(rows) - + # Build up output template ------------------------------------------------- - vars <- unique(unlist(lapply(dfs, base::names))) # ~ 125,000/s - output <- rep(list(rep(NA, nrows)), length(vars)) # ~ 70,000,000/s + vars <- unique(unlist(lapply(dfs, base::names))) # ~ 125,000/s + output <- rep(list(rep(NA, nrows)), length(vars)) # ~ 70,000,000/s names(output) <- vars - + seen <- rep(FALSE, length(output)) names(seen) <- vars - ## find which cols contain matrices - matrixcols <- unique (unlist (lapply (dfs, function (x) - names (x) [sapply (x, is.matrix)]) - )) - seen [matrixcols] <- TRUE # class<- will fail if the matrix is not protected by I - # because 2 dims are needed - - for(df in dfs) { - if (all(seen)) break # Quit as soon as all done + ## find which cols contain matrices + matrixcols <- unique(unlist(lapply(dfs, function(x) { + names(x) [sapply(x, is.matrix)] + }))) + seen [matrixcols] <- TRUE # class<- will fail if the matrix is not protected by I + # because 2 dims are needed + + for (df in dfs) { + if (all(seen)) break # Quit as soon as all done matching <- intersect(names(df), vars[!seen]) - for(var in matching) { + for (var in matching) { value <- df[[var]] if (is.factor(value)) { output[[var]] <- factor(output[[var]]) @@ -159,41 +169,40 @@ rbind.fill <- function(...) { } seen[matching] <- TRUE } - + # Set up factors factors <- names(output)[unlist(lapply(output, is.factor))] - for(var in factors) { - all <- unique(lapply(dfs, function(df) levels(df[[var]]))) # is that unique needed? + for (var in factors) { + all <- unique(lapply(dfs, function(df) levels(df[[var]]))) # is that unique needed? levels(output[[var]]) <- unique(unlist(all)) } # care about matrices # the trick is to supply a n by 0 matrix for input without column of that name - for (var in matrixcols){ - df <- lapply (dfs, .get.or.make.matrix, var) - output [[var]] <- I (do.call (rbind.fill.matrix, df)) + for (var in matrixcols) { + df <- lapply(dfs, .get.or.make.matrix, var) + output [[var]] <- I(do.call(rbind.fill.matrix, df)) } - + # Compute start and end positions for each data frame pos <- matrix(cumsum(rbind(1, rows - 1)), ncol = 2, byrow = TRUE) - - for(i in seq_along(rows)) { + + for (i in seq_along(rows)) { rng <- pos[i, 1]:pos[i, 2] df <- dfs[[i]] - - for(var in setdiff (names (df), matrixcols)) { + + for (var in setdiff(names(df), matrixcols)) { output[[var]][rng] <- df[[var]] } - } - + } + quickdf(output) } -.get.or.make.matrix <- function (df, var){ +.get.or.make.matrix <- function(df, var) { tmp <- df [[var]] - if (is.null (tmp)) - tmp <- I (matrix (integer (), nrow = nrow (df))) + if (is.null(tmp)) { + tmp <- I(matrix(integer(), nrow = nrow(df))) + } tmp } - - diff --git a/hyperSpec/R/read.ENVI.HySpex.R b/hyperSpec/R/read.ENVI.HySpex.R index b835308d9..ce562e43f 100644 --- a/hyperSpec/R/read.ENVI.HySpex.R +++ b/hyperSpec/R/read.ENVI.HySpex.R @@ -1,34 +1,35 @@ ##' @describeIn read.ENVI ##' @include read.ENVI.R ##' @export -read.ENVI.HySpex <- function (file = stop ("read.ENVI.HySpex: file name needed"), - headerfile = NULL, header = list (), keys.hdr2data = NULL, ...) { +read.ENVI.HySpex <- function(file = stop("read.ENVI.HySpex: file name needed"), + headerfile = NULL, header = list(), keys.hdr2data = NULL, ...) { + headerfile <- .find.ENVI.header(file, headerfile) + keys <- readLines(headerfile) + keys <- .read.ENVI.split.header(keys) + keys <- keys [c("pixelsize x", "pixelsize y", "wavelength units")] - headerfile <- .find.ENVI.header (file, headerfile) - keys <- readLines (headerfile) - keys <- .read.ENVI.split.header (keys) - keys <- keys [c ("pixelsize x", "pixelsize y", "wavelength units")] - - header <- modifyList (keys, header) + header <- modifyList(keys, header) ## most work is done by read.ENVI - spc <- read.ENVI (file = file, headerfile = headerfile, header = header, ..., pull.header.lines = FALSE) + spc <- read.ENVI(file = file, headerfile = headerfile, header = header, ..., pull.header.lines = FALSE) - label <- list (x = "x / pixel", - y = "y / pixel", - spc = 'I / a.u.', - .wavelength = as.expression (bquote (lambda / .(u), list (u = keys$`wavelength units`)))) + label <- list( + x = "x / pixel", + y = "y / pixel", + spc = "I / a.u.", + .wavelength = as.expression(bquote(lambda / .(u), list(u = keys$`wavelength units`))) + ) - labels (spc) <- label + labels(spc) <- label spc } -.test (read.ENVI.HySpex) <- function (){ - context ("read.ENVI.HySpex") - - test_that ("Hyspex ENVI file", { - skip_if_not_fileio_available () +.test(read.ENVI.HySpex) <- function() { + context("read.ENVI.HySpex") + + test_that("Hyspex ENVI file", { + skip_if_not_fileio_available() expect_known_hash(read.ENVI.HySpex("fileio/ENVI/HySpexNIR.hyspex"), "cf35ba92334f22513486f25c5d8ebe32") }) -} \ No newline at end of file +} diff --git a/hyperSpec/R/read.ENVI.Nicolet.R b/hyperSpec/R/read.ENVI.Nicolet.R index e484fbf40..07dc3adb9 100644 --- a/hyperSpec/R/read.ENVI.Nicolet.R +++ b/hyperSpec/R/read.ENVI.Nicolet.R @@ -18,92 +18,100 @@ ##' @describeIn read.ENVI ##' @export ##' @importFrom utils modifyList -read.ENVI.Nicolet <- function (file = stop ("read.ENVI: file name needed"), - headerfile = NULL, header = list (), ..., - x = NA, y = NA, - nicolet.correction = FALSE) { - - ## the additional keywords to interprete must be read from headerfile - headerfile <- .find.ENVI.header (file, headerfile) - keys <- readLines (headerfile) - keys <- .read.ENVI.split.header (keys) - keys <- keys [c ("description", "z plot titles", "pixel size")] - - header <- modifyList (keys, header) - - ## most work is done by read.ENVI - spc <- read.ENVI (file = file, headerfile = headerfile, header = header, ..., - x = if (is.na (x)) 0 : 1 else x, - y = if (is.na (y)) 0 : 1 else y) - - ### From here on processing the additional keywords in Nicolet's ENVI header * - - ## z plot titles ------------------------------------------------------------- - ## default labels - label <- list (x = expression (`/` (x, micro * m)), - y = expression (`/` (y, micro * m)), - spc = 'I / a.u.', - .wavelength = expression (tilde (nu) / cm^-1)) - - ## get labels from header information - if (!is.null (header$'z plot titles')){ - pattern <- "^[[:blank:]]*([[:print:]^,]+)[[:blank:]]*,.*$" - tmp <- sub (pattern, "\\1", header$'z plot titles') - - if (grepl ("Wavenumbers (cm-1)", tmp, ignore.case = TRUE)) - label$.wavelength <- expression (tilde (nu) / cm^(-1)) - else - label$.wavelength <- tmp - - pattern <- "^[[:blank:]]*[[:print:]^,]+,[[:blank:]]*([[:print:]^,]+).*$" - tmp <- sub (pattern, "\\1", header$'z plot titles') - if (grepl ("Unknown", tmp, ignore.case = TRUE)) - label$spc <- "I / a.u." - else - label$spc <- tmp - } - - ## modify the labels accordingly - spc@label <- modifyList (label, spc@label) - - ## set up spatial coordinates ------------------------------------------------ - ## look for x and y in the header only if x and y are NULL - ## they are in `description` and `pixel size` - - ## set up regular expressions to extract the values - p.description <- paste ("^Spectrum position [[:digit:]]+ of [[:digit:]]+ positions,", - "X = ([[:digit:].-]+), Y = ([[:digit:].-]+)$") - p.pixel.size <- "^[[:blank:]]*([[:digit:].-]+),[[:blank:]]*([[:digit:].-]+).*$" - - if (is.na (x) && is.na (y) && - ! is.null (header$description) && grepl (p.description, header$description ) && - ! is.null (header$'pixel size') && grepl (p.pixel.size, header$'pixel size')) { - - x [1] <- as.numeric (sub (p.description, "\\1", header$description)) - y [1] <- as.numeric (sub (p.description, "\\2", header$description)) - - x [2] <- as.numeric (sub (p.pixel.size, "\\1", header$'pixel size')) - y [2] <- as.numeric (sub (p.pixel.size, "\\2", header$'pixel size')) - - ## it seems that the step size is given in mm while the offset is in micron - if (nicolet.correction) { - x [2] <- x [2] * 1000 - y [2] <- y [2] * 1000 - } - - ## now calculate and set the x and y coordinates - x <- x [2] * spc$x + x [1] - if (! any (is.na (x))) - spc@data$x <- x - - y <- y [2] * spc$y + y [1] - if (! any (is.na (y))) - spc@data$y <- y - } - - ## consistent file import behaviour across import functions - ## .fileio.optional is called already by read.ENVI - - spc +read.ENVI.Nicolet <- function(file = stop("read.ENVI: file name needed"), + headerfile = NULL, header = list(), ..., + x = NA, y = NA, + nicolet.correction = FALSE) { + + ## the additional keywords to interprete must be read from headerfile + headerfile <- .find.ENVI.header(file, headerfile) + keys <- readLines(headerfile) + keys <- .read.ENVI.split.header(keys) + keys <- keys [c("description", "z plot titles", "pixel size")] + + header <- modifyList(keys, header) + + ## most work is done by read.ENVI + spc <- read.ENVI( + file = file, headerfile = headerfile, header = header, ..., + x = if (is.na(x)) 0:1 else x, + y = if (is.na(y)) 0:1 else y + ) + + ### From here on processing the additional keywords in Nicolet's ENVI header * + + ## z plot titles ------------------------------------------------------------- + ## default labels + label <- list( + x = expression(`/`(x, micro * m)), + y = expression(`/`(y, micro * m)), + spc = "I / a.u.", + .wavelength = expression(tilde(nu) / cm^-1) + ) + + ## get labels from header information + if (!is.null(header$"z plot titles")) { + pattern <- "^[[:blank:]]*([[:print:]^,]+)[[:blank:]]*,.*$" + tmp <- sub(pattern, "\\1", header$"z plot titles") + + if (grepl("Wavenumbers (cm-1)", tmp, ignore.case = TRUE)) { + label$.wavelength <- expression(tilde(nu) / cm^(-1)) + } else { + label$.wavelength <- tmp + } + + pattern <- "^[[:blank:]]*[[:print:]^,]+,[[:blank:]]*([[:print:]^,]+).*$" + tmp <- sub(pattern, "\\1", header$"z plot titles") + if (grepl("Unknown", tmp, ignore.case = TRUE)) { + label$spc <- "I / a.u." + } else { + label$spc <- tmp + } + } + + ## modify the labels accordingly + spc@label <- modifyList(label, spc@label) + + ## set up spatial coordinates ------------------------------------------------ + ## look for x and y in the header only if x and y are NULL + ## they are in `description` and `pixel size` + + ## set up regular expressions to extract the values + p.description <- paste( + "^Spectrum position [[:digit:]]+ of [[:digit:]]+ positions,", + "X = ([[:digit:].-]+), Y = ([[:digit:].-]+)$" + ) + p.pixel.size <- "^[[:blank:]]*([[:digit:].-]+),[[:blank:]]*([[:digit:].-]+).*$" + + if (is.na(x) && is.na(y) && + !is.null(header$description) && grepl(p.description, header$description) && + !is.null(header$"pixel size") && grepl(p.pixel.size, header$"pixel size")) { + x [1] <- as.numeric(sub(p.description, "\\1", header$description)) + y [1] <- as.numeric(sub(p.description, "\\2", header$description)) + + x [2] <- as.numeric(sub(p.pixel.size, "\\1", header$"pixel size")) + y [2] <- as.numeric(sub(p.pixel.size, "\\2", header$"pixel size")) + + ## it seems that the step size is given in mm while the offset is in micron + if (nicolet.correction) { + x [2] <- x [2] * 1000 + y [2] <- y [2] * 1000 + } + + ## now calculate and set the x and y coordinates + x <- x [2] * spc$x + x [1] + if (!any(is.na(x))) { + spc@data$x <- x + } + + y <- y [2] * spc$y + y [1] + if (!any(is.na(y))) { + spc@data$y <- y + } + } + + ## consistent file import behaviour across import functions + ## .fileio.optional is called already by read.ENVI + + spc } - diff --git a/hyperSpec/R/read.ENVI.R b/hyperSpec/R/read.ENVI.R index f04bd9ff4..82b9faf69 100644 --- a/hyperSpec/R/read.ENVI.R +++ b/hyperSpec/R/read.ENVI.R @@ -11,26 +11,26 @@ ### some general helper functions .................................................................. -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### split.line - split line into list of key-value pairs ### ### -split.line <- function (x, separator, trim.blank = TRUE) { - tmp <- regexpr (separator, x) +split.line <- function(x, separator, trim.blank = TRUE) { + tmp <- regexpr(separator, x) - key <- substr (x, 1, tmp - 1) - value <- substr (x, tmp + 1, nchar (x)) + key <- substr(x, 1, tmp - 1) + value <- substr(x, tmp + 1, nchar(x)) - if (trim.blank){ + if (trim.blank) { blank.pattern <- "^[[:blank:]]*([^[:blank:]]+.*[^[:blank:]]+)[[:blank:]]*$" - key <- sub (blank.pattern, "\\1", key) - value <- sub (blank.pattern, "\\1", value) + key <- sub(blank.pattern, "\\1", key) + value <- sub(blank.pattern, "\\1", value) } - value <- as.list (value) - names (value) <- key + value <- as.list(value) + names(value) <- key value } @@ -39,183 +39,210 @@ split.line <- function (x, separator, trim.blank = TRUE) { ### some ENVI-specific helper functions ............................................................. ### guesses ENVI header file name -.find.ENVI.header <- function (file, headerfilename) { - if (is.null (headerfilename)) { - headerfilename <- paste (dirname (file), - sub ("[.][^.]+$", ".*", basename (file)), sep = "/") - - tmp <- Sys.glob (headerfilename) +.find.ENVI.header <- function(file, headerfilename) { + if (is.null(headerfilename)) { + headerfilename <- paste(dirname(file), + sub("[.][^.]+$", ".*", basename(file)), + sep = "/" + ) - headerfilename <- tmp [! grepl (file, tmp)] + tmp <- Sys.glob(headerfilename) - if (length (headerfilename) > 1L) { + headerfilename <- tmp [!grepl(file, tmp)] - headerfilename <- headerfilename [grepl ("[.][hH][dD][rR]$", headerfilename)] + if (length(headerfilename) > 1L) { + headerfilename <- headerfilename [grepl("[.][hH][dD][rR]$", headerfilename)] - if (length (headerfilename == 1L)) - message (".find.ENVI.header: Guessing header file name ", headerfilename) + if (length(headerfilename == 1L)) { + message(".find.ENVI.header: Guessing header file name ", headerfilename) + } } - if (length (headerfilename) != 1L) - stop ("Cannot guess header file name") + if (length(headerfilename) != 1L) { + stop("Cannot guess header file name") + } } - if (!file.exists(headerfilename)) + if (!file.exists(headerfilename)) { stop("ENVI header file: ", headerfilename, " not found.") + } headerfilename } # ................................................................................................... -.read.ENVI.split.header <- function (header, pull.lines = TRUE) { +.read.ENVI.split.header <- function(header, pull.lines = TRUE) { ## check ENVI at beginning of file - if (!grepl ("ENVI", header[1])) - stop ("Not an ENVI header (ENVI keyword missing)") - else + if (!grepl("ENVI", header[1])) { + stop("Not an ENVI header (ENVI keyword missing)") + } else { header <- header [-1] + } ## remove curly braces and put multi-line key-value-pairs into one line - header <- gsub ("\\{([^}]*)\\}", "\\1", header) + header <- gsub("\\{([^}]*)\\}", "\\1", header) - l <- grep ("\\{", header) - r <- grep ("\\}", header) + l <- grep("\\{", header) + r <- grep("\\}", header) - if (length (l) != length(r)) - stop ("Error matching curly braces in header (differing numbers).") + if (length(l) != length(r)) { + stop("Error matching curly braces in header (differing numbers).") + } - if (any (r <= l)) - stop ("Mismatch of curly braces in header.") + if (any(r <= l)) { + stop("Mismatch of curly braces in header.") + } - header[l] <- sub ("\\{", "", header[l]) - header[r] <- sub ("\\}", "", header[r]) + header[l] <- sub("\\{", "", header[l]) + header[r] <- sub("\\}", "", header[r]) - if (pull.lines) - for (i in rev (seq_along (l))) - header <- c (header [seq_len (l [i] - 1)], - paste (header [l [i] : r [i]], collapse = " "), - header [-seq_len (r [i])]) + if (pull.lines) { + for (i in rev(seq_along(l))) { + header <- c( + header [seq_len(l [i] - 1)], + paste(header [l [i]:r [i]], collapse = " "), + header [-seq_len(r [i])] + ) + } + } ## split key = value constructs into list with keys as names - header <- sapply (header, split.line, "=", USE.NAMES = FALSE) - names (header) <- tolower (names (header)) + header <- sapply(header, split.line, "=", USE.NAMES = FALSE) + names(header) <- tolower(names(header)) ## process numeric values - tmp <- names (header) %in% c("samples", "lines", "bands", "data type", "header offset") - header [tmp] <- lapply (header [tmp], as.numeric) + tmp <- names(header) %in% c("samples", "lines", "bands", "data type", "header offset") + header [tmp] <- lapply(header [tmp], as.numeric) header } ### ................................................................................................. -.read.ENVI.bin <- function (file, header, block.lines.skip = NULL, block.lines.size = NULL) { +.read.ENVI.bin <- function(file, header, block.lines.skip = NULL, block.lines.size = NULL) { + DATA_TYPE_SIZES <- as.integer(c(1, 2, 4, 4, 8, NA, NA, NA, 16, NA, NA, 2)) - DATA_TYPE_SIZES <- as.integer (c (1, 2, 4, 4, 8, NA, NA, NA, 16, NA, NA, 2)) - - if (is.null (header$interleave)) + if (is.null(header$interleave)) { header$interleave <- "bsq" + } - if (any (is.null (header [c ("samples", "lines", "bands", "data type")]) || - is.na (header [c ("samples", "lines", "bands", "data type")]) )) - stop("Error in ENVI header (required entry missing or incorrect)\n header: ", - paste (names (header), " = ", header, collapse = ", ")) + if (any(is.null(header [c("samples", "lines", "bands", "data type")]) || + is.na(header [c("samples", "lines", "bands", "data type")]))) { + stop( + "Error in ENVI header (required entry missing or incorrect)\n header: ", + paste(names(header), " = ", header, collapse = ", ") + ) + } - if (header$samples <= 0) - stop ("Error in ENVI header: incorrect data size (", header$samples, ")") - if (header$lines <= 0) - stop ("Error in ENVI header: incorrect data size (", header$lines, ")") - if (header$bands <= 0) - stop ("Error in ENVI header: incorrect data size (", header$bands, ")") + if (header$samples <= 0) { + stop("Error in ENVI header: incorrect data size (", header$samples, ")") + } + if (header$lines <= 0) { + stop("Error in ENVI header: incorrect data size (", header$lines, ")") + } + if (header$bands <= 0) { + stop("Error in ENVI header: incorrect data size (", header$bands, ")") + } - if (!(header$`data type` %in% c (1 : 5, 9, 12))) - stop ("Error in ENVI header: data type incorrect or unsupported (", header$`data type`,")") + if (!(header$`data type` %in% c(1:5, 9, 12))) { + stop("Error in ENVI header: data type incorrect or unsupported (", header$`data type`, ")") + } - if (is.null (header$`byte order`)){ + if (is.null(header$`byte order`)) { header$`byte order` <- .Platform$endian - message (".read.ENVI.bin: 'byte order' not given => Guessing '", - .Platform$endian, "'\n", sep = '') + message(".read.ENVI.bin: 'byte order' not given => Guessing '", + .Platform$endian, "'\n", + sep = "" + ) } - if (! header$`byte order` %in% c ("big", "little", "swap")) { - header$`byte order` <- as.numeric (header$`byte order`) - if (! header$`byte order` %in% 0 : 1) { + if (!header$`byte order` %in% c("big", "little", "swap")) { + header$`byte order` <- as.numeric(header$`byte order`) + if (!header$`byte order` %in% 0:1) { header$`byte order` <- .Platform$endian - warning ("byte order incorrect. Guessing '", .Platform$endian, "'") - } else if (header$`byte order` == 0) + warning("byte order incorrect. Guessing '", .Platform$endian, "'") + } else if (header$`byte order` == 0) { header$`byte order` <- "little" - else + } else { header$`byte order` <- "big" + } } - if (!file.exists (file)) + if (!file.exists(file)) { stop("Binary file not found: ", file) + } - f <- file (file, "rb") - if (! is.null (header$`header offset`)) - seek (f, where = header$`header offset`, origin = "start") + f <- file(file, "rb") + if (!is.null(header$`header offset`)) { + seek(f, where = header$`header offset`, origin = "start") + } ## size of data point in bytes size <- DATA_TYPE_SIZES [header$`data type`] ## read blocks of data if (block.lines.skip > 0) { - skip <- switch (tolower (header$interleave), - bil = header$samples * header$bands * block.lines.skip, - bip = header$bands * header$samples * block.lines.skip, - bsq = stop ('skipping of band sequential (BSQ) ENVI files not yet supported. Please contact the maintainer (', - maintainer (pkg = "hyperSpec"), ")."), - stop ("Unknown interleave (", header$interleave, ") - should be one of 'BSQ', 'BIL', 'BIP'.") + skip <- switch(tolower(header$interleave), + bil = header$samples * header$bands * block.lines.skip, + bip = header$bands * header$samples * block.lines.skip, + bsq = stop( + "skipping of band sequential (BSQ) ENVI files not yet supported. Please contact the maintainer (", + maintainer(pkg = "hyperSpec"), ")." + ), + stop("Unknown interleave (", header$interleave, ") - should be one of 'BSQ', 'BIL', 'BIP'.") ) skip <- skip * size - seek (f, where = skip, start = "current") + seek(f, where = skip, start = "current") } - if (!is.null (block.lines.size)) { - header$lines <- min (block.lines.size, header$lines - block.lines.skip) + if (!is.null(block.lines.size)) { + header$lines <- min(block.lines.size, header$lines - block.lines.skip) } ## number of data points to read n <- header$samples * header$lines * header$bands switch(header$`data type`, - spc <- readBin(f, integer (), n = n, size = size, signed = FALSE), - spc <- readBin(f, integer (), n = n, size = size, endian = header$`byte order`), - spc <- readBin(f, integer (), n = n, size = size, endian = header$`byte order`), - spc <- readBin(f, double (), n = n, size = size, endian = header$`byte order`), - spc <- readBin(f, double (), n = n, size = size, endian = header$`byte order`), - stop ("ENVI data type (", header$`data type`, ") unknown"), # 6 unused - stop ("ENVI data type (", header$`data type`, ") unknown"), # 7 unused - stop ("ENVI data type (", header$`data type`, ") unknown"), # 8 unused - spc <- readBin (f, complex(), n = n, size = size, endian = header$`byte order`), - stop ("ENVI data type (", header$`data type`, ") unknown"), # 10 unused - stop ("ENVI data type (", header$`data type`, ") unknown"), # 11 unused - spc <- readBin (f, integer(), n = n, size = size, endian = header$`byte order`, signed = FALSE) - ) + spc <- readBin(f, integer(), n = n, size = size, signed = FALSE), + spc <- readBin(f, integer(), n = n, size = size, endian = header$`byte order`), + spc <- readBin(f, integer(), n = n, size = size, endian = header$`byte order`), + spc <- readBin(f, double(), n = n, size = size, endian = header$`byte order`), + spc <- readBin(f, double(), n = n, size = size, endian = header$`byte order`), + stop("ENVI data type (", header$`data type`, ") unknown"), # 6 unused + stop("ENVI data type (", header$`data type`, ") unknown"), # 7 unused + stop("ENVI data type (", header$`data type`, ") unknown"), # 8 unused + spc <- readBin(f, complex(), n = n, size = size, endian = header$`byte order`), + stop("ENVI data type (", header$`data type`, ") unknown"), # 10 unused + stop("ENVI data type (", header$`data type`, ") unknown"), # 11 unused + spc <- readBin(f, integer(), n = n, size = size, endian = header$`byte order`, signed = FALSE) + ) close(f) - switch (tolower (header$interleave), - bil = { - dim (spc) <- c (header$samples, header$bands, header$lines); - spc <- aperm (spc, c(3, 1, 2)) - }, - bip = { - dim (spc) <- c (header$bands, header$samples, header$lines); - spc <- aperm (spc, c(3, 2, 1)) - }, - bsq = { - dim (spc) <- c (header$samples, header$lines, header$bands); - spc <- aperm (spc, c(2, 1, 3)) - }, - stop ("Unknown interleave (", - header$interleave, - ", should be one of 'BSQ', 'BIL', 'BIP')") - ) - - dim (spc) <- c (header$samples * header$lines, header$bands) + switch(tolower(header$interleave), + bil = { + dim(spc) <- c(header$samples, header$bands, header$lines) + spc <- aperm(spc, c(3, 1, 2)) + }, + bip = { + dim(spc) <- c(header$bands, header$samples, header$lines) + spc <- aperm(spc, c(3, 2, 1)) + }, + bsq = { + dim(spc) <- c(header$samples, header$lines, header$bands) + spc <- aperm(spc, c(2, 1, 3)) + }, + stop( + "Unknown interleave (", + header$interleave, + ", should be one of 'BSQ', 'BIL', 'BIP')" + ) + ) + + dim(spc) <- c(header$samples * header$lines, header$bands) spc } @@ -316,125 +343,129 @@ split.line <- function (x, separator, trim.blank = TRUE) { ##' @export ##' @keywords IO file ##' @importFrom utils modifyList -read.ENVI <- function (file = stop ("read.ENVI: file name needed"), headerfile = NULL, - header = list (), - keys.hdr2data = FALSE, - x = 0 : 1, y = x, - wavelength = NULL, label = list (), - block.lines.skip = 0, block.lines.size = NULL, ..., - pull.header.lines = TRUE) { - force (y) - - if (! file.exists (file)) - stop ("File not found:", file) - - if (! is.list (header)) # catch a common pitfall - if (is.character (header)) - stop ("header must be a list of parameters. Did you mean headerfile instead?") - else - stop ("header must be a list of parameters.") - - if (is.null (headerfile)) - headerfile <- .find.ENVI.header (file, headerfile) - - tmp <- readLines (headerfile) - tmp <- .read.ENVI.split.header (tmp, pull.lines = pull.header.lines) - header <- modifyList (tmp, header) +read.ENVI <- function(file = stop("read.ENVI: file name needed"), headerfile = NULL, + header = list(), + keys.hdr2data = FALSE, + x = 0:1, y = x, + wavelength = NULL, label = list(), + block.lines.skip = 0, block.lines.size = NULL, ..., + pull.header.lines = TRUE) { + force(y) + + if (!file.exists(file)) { + stop("File not found:", file) + } + + if (!is.list(header)) { # catch a common pitfall + if (is.character(header)) { + stop("header must be a list of parameters. Did you mean headerfile instead?") + } else { + stop("header must be a list of parameters.") + } + } + + if (is.null(headerfile)) { + headerfile <- .find.ENVI.header(file, headerfile) + } + + tmp <- readLines(headerfile) + tmp <- .read.ENVI.split.header(tmp, pull.lines = pull.header.lines) + header <- modifyList(tmp, header) ## read the binary file - spc <- .read.ENVI.bin (file, header, block.lines.skip = block.lines.skip, block.lines.size = block.lines.size) + spc <- .read.ENVI.bin(file, header, block.lines.skip = block.lines.skip, block.lines.size = block.lines.size) ## wavelength should contain the mean wavelength of the respective band - if (! is.null (header$wavelength)) { - header$wavelength <- as.numeric (unlist (strsplit (header$wavelength, "[,;[:blank:]]+"))) + if (!is.null(header$wavelength)) { + header$wavelength <- as.numeric(unlist(strsplit(header$wavelength, "[,;[:blank:]]+"))) - if (! any (is.na (header$wavelength)) && is.null (wavelength)) + if (!any(is.na(header$wavelength)) && is.null(wavelength)) { wavelength <- header$wavelength + } } ## set up spatial coordinates - x <- seq (0, header$samples - 1) * x [2] + x [1] - y <- seq (0, header$lines - 1) * y [2] + y [1] + x <- seq(0, header$samples - 1) * x [2] + x [1] + y <- seq(0, header$lines - 1) * y [2] + y [1] - block.lines.size <- min (block.lines.size, nrow (spc) / header$samples) - x <- rep (x, each = block.lines.size) + block.lines.size <- min(block.lines.size, nrow(spc) / header$samples) + x <- rep(x, each = block.lines.size) - y <- y [block.lines.skip + seq_len (block.lines.size)] - y <- rep (y, header$samples) + y <- y [block.lines.skip + seq_len(block.lines.size)] + y <- rep(y, header$samples) ## header lines => extra data columns extra.data <- header [keys.hdr2data] - if (.options$gc) gc () + if (.options$gc) gc() - if (length (extra.data) > 0) { - extra.data <- lapply (extra.data, rep, length.out = length (x)) - data <- data.frame (x = x, y = y, extra.data) + if (length(extra.data) > 0) { + extra.data <- lapply(extra.data, rep, length.out = length(x)) + data <- data.frame(x = x, y = y, extra.data) } else { - data <- data.frame (x = x, y = y) + data <- data.frame(x = x, y = y) } - if (.options$gc) gc () + if (.options$gc) gc() ## finally put together the hyperSpec object - spc <- new ("hyperSpec", data = data, spc = spc, wavelength = wavelength, labels = label) + spc <- new("hyperSpec", data = data, spc = spc, wavelength = wavelength, labels = label) ## consistent file import behaviour across import functions - .fileio.optional (spc, file) + .fileio.optional(spc, file) } -.test (read.ENVI) <- function (){ - context ("read.ENVI") +.test(read.ENVI) <- function() { + context("read.ENVI") - test_that ("full spectrum BIL", { - skip_if_not_fileio_available () - tmp <- read.ENVI ("fileio/ENVI/toy.bil") + test_that("full spectrum BIL", { + skip_if_not_fileio_available() + tmp <- read.ENVI("fileio/ENVI/toy.bil") expect_equal(tmp$filename [1], "fileio/ENVI/toy.bil") - expect_equal(nrow (tmp), 21913) - expect_equal(ncol (tmp), 4) - expect_equal(nwl (tmp), 4) - expect_equal(range (tmp$x), c (0, 149)) - expect_equal(range (tmp$y), c (0, 166)) + expect_equal(nrow(tmp), 21913) + expect_equal(ncol(tmp), 4) + expect_equal(nwl(tmp), 4) + expect_equal(range(tmp$x), c(0, 149)) + expect_equal(range(tmp$y), c(0, 166)) }) - test_that ("block reading BIL", { - skip_if_not_fileio_available () - tmp <- read.ENVI ("fileio/ENVI/toy.bil", block.lines.skip = 50, block.lines.size = 40) - expect_equal(nrow (tmp), 40*150) - expect_equal(ncol (tmp), 4) - expect_equal(nwl (tmp), 4) - expect_equal(range (tmp$x), c (0, 149)) - expect_equal(range (tmp$y), c (50, 89)) + test_that("block reading BIL", { + skip_if_not_fileio_available() + tmp <- read.ENVI("fileio/ENVI/toy.bil", block.lines.skip = 50, block.lines.size = 40) + expect_equal(nrow(tmp), 40 * 150) + expect_equal(ncol(tmp), 4) + expect_equal(nwl(tmp), 4) + expect_equal(range(tmp$x), c(0, 149)) + expect_equal(range(tmp$y), c(50, 89)) }) - test_that ("block reading BIL: block longer than file", { - skip_if_not_fileio_available () - tmp <- read.ENVI ("fileio/ENVI/toy.bil", block.lines.skip = 150, block.lines.size = 50) + test_that("block reading BIL: block longer than file", { + skip_if_not_fileio_available() + tmp <- read.ENVI("fileio/ENVI/toy.bil", block.lines.skip = 150, block.lines.size = 50) expect_equal(tmp$filename [1], "fileio/ENVI/toy.bil") - expect_equal(nrow (tmp), 870) # ! not simple lines x samples multiplication as empty spectra are removed ! - expect_equal(ncol (tmp), 4) - expect_equal(nwl (tmp), 4) - expect_equal(range (tmp$x), c (86, 149)) - expect_equal(range (tmp$y), c (150, 166)) + expect_equal(nrow(tmp), 870) # ! not simple lines x samples multiplication as empty spectra are removed ! + expect_equal(ncol(tmp), 4) + expect_equal(nwl(tmp), 4) + expect_equal(range(tmp$x), c(86, 149)) + expect_equal(range(tmp$y), c(150, 166)) }) - - test_that ("Guessing messages", { - skip_if_not_fileio_available () - expect_message(read.ENVI ("fileio/ENVI/example2.img"), ".read.ENVI.bin: 'byte order' not given => Guessing 'little'") + + test_that("Guessing messages", { + skip_if_not_fileio_available() + expect_message(read.ENVI("fileio/ENVI/example2.img"), ".read.ENVI.bin: 'byte order' not given => Guessing 'little'") }) - - test_that ("empty spectra", { - skip_if_not_fileio_available () + + test_that("empty spectra", { + skip_if_not_fileio_available() old <- hy.getOption("file.remove.emptyspc") on.exit(hy.setOptions(file.remove.emptyspc = old)) - + hy.setOptions(file.remove.emptyspc = TRUE) - expect_known_hash(read.ENVI ("fileio/ENVI/example2.img"), "e987ac694ac1d6b81cd070f2f1680887") - + expect_known_hash(read.ENVI("fileio/ENVI/example2.img"), "e987ac694ac1d6b81cd070f2f1680887") + hy.setOptions(file.remove.emptyspc = FALSE) - expect_known_hash(read.ENVI ("fileio/ENVI/example2.img"), "9911a87b8c29c6d23af41a8de5a2508a") - + expect_known_hash(read.ENVI("fileio/ENVI/example2.img"), "9911a87b8c29c6d23af41a8de5a2508a") + hy.setOptions(file.remove.emptyspc = old) }) - } diff --git a/hyperSpec/R/read.asc.Andor.R b/hyperSpec/R/read.asc.Andor.R index f9a167ac5..2c58773f7 100644 --- a/hyperSpec/R/read.asc.Andor.R +++ b/hyperSpec/R/read.asc.Andor.R @@ -14,33 +14,34 @@ ##' @include read.txt.Witec.R ##' @include fileio.optional.R ##' @export -read.asc.Andor <- function (file = stop ("filename or connection needed"), - ..., quiet = TRUE, dec = ".", sep = ","){ +read.asc.Andor <- function(file = stop("filename or connection needed"), + ..., quiet = TRUE, dec = ".", sep = ",") { ## check for valid data connection - .check.con (file = file) + .check.con(file = file) ## read spectra - tmp <- readLines (file) - nwl <- length (tmp) - txt <- scan (text = tmp, dec = dec, sep = sep, quiet = quiet, ...) + tmp <- readLines(file) + nwl <- length(tmp) + txt <- scan(text = tmp, dec = dec, sep = sep, quiet = quiet, ...) - dim (txt) <- c (length (txt) / nwl, nwl) + dim(txt) <- c(length(txt) / nwl, nwl) ## fix: Andor Solis may have final comma without values - if (all (is.na (txt [nrow (txt), ]))) - txt <- txt [- nrow (txt), ] + if (all(is.na(txt [nrow(txt), ]))) { + txt <- txt [-nrow(txt), ] + } - spc <- new ("hyperSpec", wavelength = txt [1, ], spc = txt [-1, ]) + spc <- new("hyperSpec", wavelength = txt [1, ], spc = txt [-1, ]) - ## consistent file import behaviour across import functions - .fileio.optional (spc, file) + ## consistent file import behaviour across import functions + .fileio.optional(spc, file) } -.test (read.asc.Andor) <- function (){ - context ("read.asc.Andor") +.test(read.asc.Andor) <- function() { + context("read.asc.Andor") test_that("Andor Solis .asc text files", { skip_if_not_fileio_available() - expect_known_hash (read.asc.Andor("fileio/asc.Andor/ASCII-Andor-Solis.asc"), "9ead937f51") + expect_known_hash(read.asc.Andor("fileio/asc.Andor/ASCII-Andor-Solis.asc"), "9ead937f51") }) } diff --git a/hyperSpec/R/read.asc.PerkinElmer.R b/hyperSpec/R/read.asc.PerkinElmer.R index bfe9e4a2c..5c829ad6e 100644 --- a/hyperSpec/R/read.asc.PerkinElmer.R +++ b/hyperSpec/R/read.asc.PerkinElmer.R @@ -9,28 +9,33 @@ #' @importFrom utils packageDescription #' @export #' -read.asc.PerkinElmer <- function (file = stop ("filename or connection needed"), ...){ +read.asc.PerkinElmer <- function(file = stop("filename or connection needed"), ...) { content <- readLines(con = file) - message ("read.asc.PerkinElmer is experimental, hyperSpec so far has no test data for PE .asc files.", - " Please consider submitting your spectrum in an enhancement request to ", packageDescription("hyperSpec")$BugReports, - " in order to help the development of hyperSpec.") + message( + "read.asc.PerkinElmer is experimental, hyperSpec so far has no test data for PE .asc files.", + " Please consider submitting your spectrum in an enhancement request to ", packageDescription("hyperSpec")$BugReports, + " in order to help the development of hyperSpec." + ) ## find beginning of DATA section - startDATA <- grep ("DATA", content) + startDATA <- grep("DATA", content) - if (length (startDATA) != 1L) - stop ("read.asc.PerkinElmer so far can deal with single spectra files only.", - " Please file an enhancement request at", packageDescription("hyperSpec")$BugReports, - " with your file as an example or contact the maintainer (", - maintainer ("hyperSpec"), ").") + if (length(startDATA) != 1L) { + stop( + "read.asc.PerkinElmer so far can deal with single spectra files only.", + " Please file an enhancement request at", packageDescription("hyperSpec")$BugReports, + " with your file as an example or contact the maintainer (", + maintainer("hyperSpec"), ")." + ) + } ## Spectra values are stored - content <- content [- seq_len(startDATA)] + content <- content [-seq_len(startDATA)] - spc <- read.txt.long (textConnection(content), header = FALSE, sep = "\t", ...) + spc <- read.txt.long(textConnection(content), header = FALSE, sep = "\t", ...) spc$filename <- NULL # not meaningful due to textConnection use ## consistent file import behaviour across import functions - .fileio.optional (spc, file) + .fileio.optional(spc, file) } diff --git a/hyperSpec/R/read.ini.R b/hyperSpec/R/read.ini.R index a7b311b24..4fc99420f 100644 --- a/hyperSpec/R/read.ini.R +++ b/hyperSpec/R/read.ini.R @@ -19,34 +19,35 @@ ##' for the key-value-pairs. ##' @keywords IO file -read.ini <- function (con = stop ("Connection con needed."), skip = NULL, encoding = "unknown"){ - Lines <- readLines (con, encoding = encoding) +read.ini <- function(con = stop("Connection con needed."), skip = NULL, encoding = "unknown") { + Lines <- readLines(con, encoding = encoding) ## remove leading lines, if they are not a section - if (!is.null (skip)) - Lines <- Lines [-seq_len (skip)] + if (!is.null(skip)) { + Lines <- Lines [-seq_len(skip)] + } - sections <- grep ("[[].*[]]", Lines) + sections <- grep("[[].*[]]", Lines) - content <- Lines [- sections] - ini <- as.list (gsub ("^.*=[[:blank:]]*", "", content)) # removes blanks behind equal sign - names (ini) <- .sanitize.name (gsub ("[[:blank:]]*=.*$", "", content)) # see above: removes in front of equal sign + content <- Lines [-sections] + ini <- as.list(gsub("^.*=[[:blank:]]*", "", content)) # removes blanks behind equal sign + names(ini) <- .sanitize.name(gsub("[[:blank:]]*=.*$", "", content)) # see above: removes in front of equal sign # try converting to numeric - tmp <- lapply (ini, function (x) strsplit (x, ",") [[1]]) - tmp <- suppressWarnings (lapply (tmp, as.numeric)) - numbers <- ! sapply (tmp, function (x) any (is.na (x))) + tmp <- lapply(ini, function(x) strsplit(x, ",") [[1]]) + tmp <- suppressWarnings(lapply(tmp, as.numeric)) + numbers <- !sapply(tmp, function(x) any(is.na(x))) ini [numbers] <- tmp [numbers] - tmp <- rep.int (seq_along (sections), diff (c (sections, length (Lines) + 1)) - 1) - ini <- split (ini, tmp) + tmp <- rep.int(seq_along(sections), diff(c(sections, length(Lines) + 1)) - 1) + ini <- split(ini, tmp) sections <- Lines [sections] - sections <- .sanitize.name (gsub ("^.(.*).$", "\\1", sections)) - names (ini) <- sections + sections <- .sanitize.name(gsub("^.(.*).$", "\\1", sections)) + names(ini) <- sections ini } -.sanitize.name <- function (name){ - gsub ("[^a-zA-Z0-9._]", ".", name) +.sanitize.name <- function(name) { + gsub("[^a-zA-Z0-9._]", ".", name) } diff --git a/hyperSpec/R/read.jdx.R b/hyperSpec/R/read.jdx.R index ade61dc67..bb8a39cdc 100644 --- a/hyperSpec/R/read.jdx.R +++ b/hyperSpec/R/read.jdx.R @@ -17,12 +17,12 @@ ##' extra data. Usually a character vector of labels (lowercase, without and dashes, blanks, ##' underscores). If `TRUE`, all header entries are read. ##' @param ... further parameters handed to the data import function, e.g. -##' +##' ##' | parameter | meaning | default | ##' | --------- | ----------------------------------------------------------------------------------- | ------- | ##' | `xtol` | tolerance for checking calculated x values against checkpoints at beginning of line | XFACTOR | ##' | `ytol` | tolerance for checking Y values against MINY and MAXY | YFACTOR | -##' +##' ##' @param NA.symbols character vector of text values that should be converted to `NA` ##' @param collapse.multi should hyperSpec objects from multispectra files be collapsed into one ##' hyperSpec object (if `FALSE`, a list of hyperSpec objects is returned). @@ -32,355 +32,388 @@ ##' @md ##' @export ##' @importFrom utils head modifyList maintainer -read.jdx <- function(filename = stop ("filename is needed"), encoding = "", - header = list (), keys.hdr2data = FALSE, ..., - NA.symbols = c ("NA", "N/A", "N.A."), - collapse.multi = TRUE, - wl.tolerance = hy.getOption("wl.tolerance"), collapse.equal = TRUE){ +read.jdx <- function(filename = stop("filename is needed"), encoding = "", + header = list(), keys.hdr2data = FALSE, ..., + NA.symbols = c("NA", "N/A", "N.A."), + collapse.multi = TRUE, + wl.tolerance = hy.getOption("wl.tolerance"), collapse.equal = TRUE) { ## see readLines help: this way, encoding is translated to standard encoding on current system. - file <- file (filename, "r", encoding = encoding, blocking = FALSE) - jdx <- readLines (file) - close (file) + file <- file(filename, "r", encoding = encoding, blocking = FALSE) + jdx <- readLines(file) + close(file) ## start & end of spectra header and data - hdrstart <- grep ("^[[:blank:]]*##TITLE=", jdx) - if (length (hdrstart) == 0L) stop ("No spectra found.") + hdrstart <- grep("^[[:blank:]]*##TITLE=", jdx) + if (length(hdrstart) == 0L) stop("No spectra found.") - datastart <- grep (sprintf ("^[[:blank:]]*##(%s)=", paste (.DATA.START, collapse = "|")), jdx) + 1 - # V 4.24 uses ##XYDATA= - # V 5.00 uses ##DATA TABLE= ..., XYDATA - # V 5.01 MPI Golm files use ##PEAK TABLE= + datastart <- grep(sprintf("^[[:blank:]]*##(%s)=", paste(.DATA.START, collapse = "|")), jdx) + 1 + # V 4.24 uses ##XYDATA= + # V 5.00 uses ##DATA TABLE= ..., XYDATA + # V 5.01 MPI Golm files use ##PEAK TABLE= - if (length (datastart) == 0L) stop ("No data found: unsupported data type.") + if (length(datastart) == 0L) stop("No data found: unsupported data type.") - dataend <- grep ("^[[:blank:]]*##", jdx) - dataend <- sapply (datastart, function (s) dataend [which (dataend > s)[1]]) - 1 + dataend <- grep("^[[:blank:]]*##", jdx) + dataend <- sapply(datastart, function(s) dataend [which(dataend > s)[1]]) - 1 - spcend <- grep ("^[[:blank:]]*##END=[[:blank:]]*$", jdx) - 1 + spcend <- grep("^[[:blank:]]*##END=[[:blank:]]*$", jdx) - 1 ## some checks - stopifnot (length (datastart) >= length (hdrstart)) - stopifnot (length (datastart) == length (dataend)) - stopifnot (all (hdrstart < spcend)) - stopifnot (all (datastart < dataend)) + stopifnot(length(datastart) >= length(hdrstart)) + stopifnot(length(datastart) == length(dataend)) + stopifnot(all(hdrstart < spcend)) + stopifnot(all(datastart < dataend)) - spc <- vector ("list", length (datastart)) + spc <- vector("list", length(datastart)) - for (s in seq_along (datastart)){ + for (s in seq_along(datastart)) { ## look for header data - hdr <- modifyList (header, .jdx.readhdr (jdx [hdrstart [s] : (datastart [s] - 1)])) + hdr <- modifyList(header, .jdx.readhdr(jdx [hdrstart [s]:(datastart [s] - 1)])) - if (! is.null (hdr$page) || ! is.null (hdr$ntuples)) - stop ("NTUPLES / PAGEs are not yet supported.") + if (!is.null(hdr$page) || !is.null(hdr$ntuples)) { + stop("NTUPLES / PAGEs are not yet supported.") + } if (s == 1L) { ## file header may contain overall settings - hdr <- modifyList (list (file = as.character (filename)), hdr) - header <- hdr [! names (hdr) %in% .key2names (.DATA.START)] - } + hdr <- modifyList(list(file = as.character(filename)), hdr) + header <- hdr [!names(hdr) %in% .key2names(.DATA.START)] + } ## evaluate data block - if (grepl ("[A-DF-Za-df-z%@]", jdx[datastart [s]])) - stop ("SQZ, DIF, and DIFDUP forms are not yet supported.") + if (grepl("[A-DF-Za-df-z%@]", jdx[datastart [s]])) { + stop("SQZ, DIF, and DIFDUP forms are not yet supported.") + } - spc [[s]] <- switch (hdr$.format, - `(X++(Y..Y))`= .jdx.TABULAR.PAC (hdr, jdx [datastart [s] : spcend [s]], ...), - `(XY..XY)` = .jdx.TABULAR.AFFN (hdr, jdx [datastart [s] : spcend [s]], ...), + spc [[s]] <- switch(hdr$.format, + `(X++(Y..Y))` = .jdx.TABULAR.PAC(hdr, jdx [datastart [s]:spcend [s]], ...), + `(XY..XY)` = .jdx.TABULAR.AFFN(hdr, jdx [datastart [s]:spcend [s]], ...), - stop ("unknown JCAMP-DX data format: ", hdr$xydata) - ) + stop("unknown JCAMP-DX data format: ", hdr$xydata) + ) ## process according to header entries - spc [[s]] <- .jdx.processhdr (spc [[s]], hdr, keys.hdr2data, ..., NA.symbols = NA.symbols) + spc [[s]] <- .jdx.processhdr(spc [[s]], hdr, keys.hdr2data, ..., NA.symbols = NA.symbols) } - - if (length (spc) == 1L) + + if (length(spc) == 1L) { spc <- spc [[1]] - else if (collapse.multi) - spc <- collapse (spc, wl.tolerance = wl.tolerance, collapse.equal = collapse.equal) + } else if (collapse.multi) { + spc <- collapse(spc, wl.tolerance = wl.tolerance, collapse.equal = collapse.equal) + } ## consistent file import behaviour across import functions - .fileio.optional (spc, filename) + .fileio.optional(spc, filename) } ### HEADER ------------------------------------------------------------------------------------------ -.jdx.readhdr <- function (hdr){ +.jdx.readhdr <- function(hdr) { ## get rid of comments. JCAMP-DX comments start with $$ and go to the end of the line. - hdr <- hdr [! grepl ("^[[:blank:]]*[$][$]", hdr)] - hdr <- gsub ("([[:blank:]][$][$].*)$", "", hdr) + hdr <- hdr [!grepl("^[[:blank:]]*[$][$]", hdr)] + hdr <- gsub("([[:blank:]][$][$].*)$", "", hdr) ## now join lines that are not starting with ##KEY= with the KEYed line before - nokey <- grep ("^[[:blank:]]*##.*=", hdr, invert = TRUE) - if (length (nokey) > 0) { - for (l in rev (nokey)) # these are few, so no optimization needed - hdr [l - 1] <- paste (hdr [(l - 1) : l], collapse = " ") + nokey <- grep("^[[:blank:]]*##.*=", hdr, invert = TRUE) + if (length(nokey) > 0) { + for (l in rev(nokey)) { # these are few, so no optimization needed + hdr [l - 1] <- paste(hdr [(l - 1):l], collapse = " ") + } hdr <- hdr [-nokey] } - names <- .key2names (sub ("^[[:blank:]]*##(.*)=.*$", "\\1", hdr)) + names <- .key2names(sub("^[[:blank:]]*##(.*)=.*$", "\\1", hdr)) - hdr <- sub ("^[[:blank:]]*##.*=[[:blank:]]*(.*)[[:blank:]]*$", "\\1", hdr) - hdr <- gsub ("^[\"'[:blank:]]*([^\"'[:blank:]].*[^\"'[:blank:]])[\"'[:blank:]]*$", "\\1", hdr) - i <- grepl ("^[[:blank:]]*[-+]?[.[:digit:]]*[eE]?[-+]?[.[:digit:]]*[[:blank:]]*$", hdr) & - ! names %in% c ("title", "datatype", "owner") - hdr <- as.list (hdr) - hdr [i] <- as.numeric (hdr [i]) - names (hdr) <- names + hdr <- sub("^[[:blank:]]*##.*=[[:blank:]]*(.*)[[:blank:]]*$", "\\1", hdr) + hdr <- gsub("^[\"'[:blank:]]*([^\"'[:blank:]].*[^\"'[:blank:]])[\"'[:blank:]]*$", "\\1", hdr) + i <- grepl("^[[:blank:]]*[-+]?[.[:digit:]]*[eE]?[-+]?[.[:digit:]]*[[:blank:]]*$", hdr) & + !names %in% c("title", "datatype", "owner") + hdr <- as.list(hdr) + hdr [i] <- as.numeric(hdr [i]) + names(hdr) <- names ## e.g. Shimadzu does not always save XFACTOR and YFACTOR - if (is.null (hdr$yfactor)) hdr$yfactor <- 1 - if (is.null (hdr$xfactor)) hdr$xfactor <- 1 + if (is.null(hdr$yfactor)) hdr$yfactor <- 1 + if (is.null(hdr$xfactor)) hdr$xfactor <- 1 ## we treat XYDATA and PEAK TABLEs the same way - format <- hdr [names (hdr) %in% .key2names (.DATA.START)] - format <- format [! sapply (format, is.null)] - if (length (format) != 1) - stop ("contradicting format specification: please contact the maintainer (", - maintainer ("hyperSpec"), - "supplying the file you just tried to load.") + format <- hdr [names(hdr) %in% .key2names(.DATA.START)] + format <- format [!sapply(format, is.null)] + if (length(format) != 1) { + stop( + "contradicting format specification: please contact the maintainer (", + maintainer("hyperSpec"), + "supplying the file you just tried to load." + ) + } hdr$.format <- format [[1]] hdr } -.jdx.processhdr <- function (spc, hdr, keys, ..., ytol = abs (hdr$yfactor), NA.symbols){ +.jdx.processhdr <- function(spc, hdr, keys, ..., ytol = abs(hdr$yfactor), NA.symbols) { ## hdr$xfactor and $yfactor applied by individual reading functions ## check Y values - miny <- min (spc@data$spc) - if (! is.null (hdr$miny) && abs (hdr$miny - miny) > ytol) - message (sprintf ("JDX file inconsistency: Minimum of spectrum != MINY: difference = %0.3g (%0.3g * YFACTOR)", - miny - hdr$miny, - (miny - hdr$miny) / hdr$yfactor)) + miny <- min(spc@data$spc) + if (!is.null(hdr$miny) && abs(hdr$miny - miny) > ytol) { + message(sprintf( + "JDX file inconsistency: Minimum of spectrum != MINY: difference = %0.3g (%0.3g * YFACTOR)", + miny - hdr$miny, + (miny - hdr$miny) / hdr$yfactor + )) + } - maxy <- max (spc@data$spc) - if (! is.null (hdr$maxy) && abs (hdr$maxy - maxy) > ytol) - message (sprintf ("JDX file inconsistency: Maximum of spectrum != MAXY: difference = %0.3g (%0.3g * YFACTOR)", - maxy - hdr$maxy, - (maxy - hdr$maxy) / hdr$yfactor)) + maxy <- max(spc@data$spc) + if (!is.null(hdr$maxy) && abs(hdr$maxy - maxy) > ytol) { + message(sprintf( + "JDX file inconsistency: Maximum of spectrum != MAXY: difference = %0.3g (%0.3g * YFACTOR)", + maxy - hdr$maxy, + (maxy - hdr$maxy) / hdr$yfactor + )) + } - spc@label$.wavelength <- .jdx.xunits (hdr$xunits) - spc@label$spc <- .jdx.yunits (hdr$yunits) + spc@label$.wavelength <- .jdx.xunits(hdr$xunits) + spc@label$spc <- .jdx.yunits(hdr$yunits) ## CONCENTRATIONS - if ("concentrations" %in% keys) - spc <- .jdx.hdr.concentrations (spc, hdr, NA.symbols = NA.symbols) + if ("concentrations" %in% keys) { + spc <- .jdx.hdr.concentrations(spc, hdr, NA.symbols = NA.symbols) + } # delete header lines already processed - hdr[c ("jcampdx", "xunits", "yunits", "xfactor", "yfactor", "firstx", "lastx", "npoints", - "firsty", "xydata", "end", "deltax", "maxy", "miny", - "concentrations")] <- NULL - if (is.character (keys)) - keys <- keys [keys %in% names (hdr)] + hdr[c( + "jcampdx", "xunits", "yunits", "xfactor", "yfactor", "firstx", "lastx", "npoints", + "firsty", "xydata", "end", "deltax", "maxy", "miny", + "concentrations" + )] <- NULL + if (is.character(keys)) { + keys <- keys [keys %in% names(hdr)] + } hdr <- hdr [keys] - if (length (hdr) > 0L) - spc@data <- cbind (spc@data, hdr) + if (length(hdr) > 0L) { + spc@data <- cbind(spc@data, hdr) + } spc } ### DATA FORMATS ------------------------------------------------------------------------------------ -.jdx.TABULAR.PAC <- function (hdr, data, ..., xtol = hdr$xfactor){ +.jdx.TABULAR.PAC <- function(hdr, data, ..., xtol = hdr$xfactor) { ## regexp for numbers including scientific notation .PATTERN.number <- "[-+]?[0-9]*[.]?[0-9]*([eE][-+]?[0-9]+)?" - if (is.null (hdr$firstx)) stop ("##FIRSTX= missing.") - if (is.null (hdr$lastx)) stop ("##LASTX= missing.") - if (is.null (hdr$npoints)) stop ("##NPOINTS= missing.") + if (is.null(hdr$firstx)) stop("##FIRSTX= missing.") + if (is.null(hdr$lastx)) stop("##LASTX= missing.") + if (is.null(hdr$npoints)) stop("##NPOINTS= missing.") - wl <- seq (hdr$firstx, hdr$lastx, length.out = hdr$npoints) + wl <- seq(hdr$firstx, hdr$lastx, length.out = hdr$npoints) ## remove starting X - y <- sub (paste0 ("^[[:blank:]]*", .PATTERN.number, "[[:blank:]]*(.*)$"), "\\2", data) + y <- sub(paste0("^[[:blank:]]*", .PATTERN.number, "[[:blank:]]*(.*)$"), "\\2", data) ## add spaces between numbers if necessary - y <- gsub ("([0-9.])([+-])", "\\1 \\2", y) + y <- gsub("([0-9.])([+-])", "\\1 \\2", y) - y <- strsplit (y, "[[:blank:]]+") - ny <- sapply (y, length) + y <- strsplit(y, "[[:blank:]]+") + ny <- sapply(y, length) - y <- as.numeric (unlist (y)) + y <- as.numeric(unlist(y)) - if (length (y) != hdr$npoints) - stop ("mismatch between ##NPOINTS and length of Y data.") + if (length(y) != hdr$npoints) { + stop("mismatch between ##NPOINTS and length of Y data.") + } ## X checkpoints - x <- sub (paste0 ("^[[:blank:]]*(", .PATTERN.number, ")[[:blank:]]*.*$"), "\\1", data) - x <- as.numeric (x) * hdr$xfactor - diffx <- abs (wl [c (1, head (cumsum (ny) + 1, -1))] - x) - if (any (diffx > xtol)) - message ("JDX file inconsistency: X axis differs from checkpoints. ", - sprintf ("Maximum difference = %0.2g (%0.2g * XFACTOR)", - max (diffx), max (diffx) / hdr$xfactor)) + x <- sub(paste0("^[[:blank:]]*(", .PATTERN.number, ")[[:blank:]]*.*$"), "\\1", data) + x <- as.numeric(x) * hdr$xfactor + diffx <- abs(wl [c(1, head(cumsum(ny) + 1, -1))] - x) + if (any(diffx > xtol)) { + message( + "JDX file inconsistency: X axis differs from checkpoints. ", + sprintf( + "Maximum difference = %0.2g (%0.2g * XFACTOR)", + max(diffx), max(diffx) / hdr$xfactor + ) + ) + } y <- y * hdr$yfactor - new ("hyperSpec", spc = y, wavelength = wl) + new("hyperSpec", spc = y, wavelength = wl) } -.jdx.TABULAR.AFFN <- function (hdr, data, ...){ - - data <- strsplit (data, "[,;[:blank:]]+") - data <- unlist (data) - data <- matrix (as.numeric (data), nrow = 2) +.jdx.TABULAR.AFFN <- function(hdr, data, ...) { + data <- strsplit(data, "[,;[:blank:]]+") + data <- unlist(data) + data <- matrix(as.numeric(data), nrow = 2) - new ("hyperSpec", wavelength = data [1,] * hdr$xfactor, spc = data [2,]*hdr$yfactor) + new("hyperSpec", wavelength = data [1, ] * hdr$xfactor, spc = data [2, ] * hdr$yfactor) } ### UNITS ------------------------------------------------------------------------------------------- -.jdx.xunits <- function (xunits){ - if (is.null (xunits)) - NULL - else - switch (tolower (xunits), - `1/cm` = expression (tilde (nu) / cm^-1), - micrometers = expression (`/` (lambda, micro * m)), - nanometers = expression (lambda / nm), - seconds = expression (t / s), - xunits) +.jdx.xunits <- function(xunits) { + if (is.null(xunits)) { + NULL + } else { + switch(tolower(xunits), + `1/cm` = expression(tilde(nu) / cm^-1), + micrometers = expression(`/`(lambda, micro * m)), + nanometers = expression(lambda / nm), + seconds = expression(t / s), + xunits + ) + } } -.jdx.yunits <- function (yunits){ - if (is.null (yunits)) - NULL - - else - switch (tolower (yunits), - transmittance = "T", - reflectance = "R", - absorbance = "A", - `kubelka-munk` = expression (`/` (1 - R^2, 2*R)), - `arbitrary units` = "I / a.u.", - yunits) +.jdx.yunits <- function(yunits) { + if (is.null(yunits)) { + NULL + } else { + switch(tolower(yunits), + transmittance = "T", + reflectance = "R", + absorbance = "A", + `kubelka-munk` = expression(`/`(1 - R^2, 2 * R)), + `arbitrary units` = "I / a.u.", + yunits + ) + } } ## HDR processing functions -.jdx.hdr.concentrations <- function (spc, hdr, NA.symbols){ - - hdr <- strsplit (hdr$concentrations, "[)][[:blank:]]*[(]")[[1]] - hdr [length (hdr)] <- gsub (")$", "", hdr [length (hdr)]) - if (hdr [1] == "(NCU") - hdr <- hdr [-1] - else - message ("Unknown type of concentration specification in JDX file: ", hdr [1], ")") +.jdx.hdr.concentrations <- function(spc, hdr, NA.symbols) { + hdr <- strsplit(hdr$concentrations, "[)][[:blank:]]*[(]")[[1]] + hdr [length(hdr)] <- gsub(")$", "", hdr [length(hdr)]) + if (hdr [1] == "(NCU") { + hdr <- hdr [-1] + } else { + message("Unknown type of concentration specification in JDX file: ", hdr [1], ")") + } - hdr <- simplify2array (strsplit (hdr, ",")) + hdr <- simplify2array(strsplit(hdr, ",")) hdr [hdr %in% NA.symbols] <- NA ## names - N <- hdr [1,] - N <- sub ("^([^[:alpha:]]*)", "", N) - N <- sub ("([^[:alpha:]]*)$", "", N) - N <- gsub ("([^[:alnum:]_-])", ".", N) + N <- hdr [1, ] + N <- sub("^([^[:alpha:]]*)", "", N) + N <- sub("([^[:alpha:]]*)$", "", N) + N <- gsub("([^[:alnum:]_-])", ".", N) ## concentrations - C <- t (as.numeric (hdr [2,])) - colnames (C) <- N - C <- as.data.frame (C) - spc@data <- cbind (spc@data, C) + C <- t(as.numeric(hdr [2, ])) + colnames(C) <- N + C <- as.data.frame(C) + spc@data <- cbind(spc@data, C) ## units - U <- as.list (hdr [3,]) - names (U) <- N + U <- as.list(hdr [3, ]) + names(U) <- N - spc@label <- modifyList (spc@label, U) + spc@label <- modifyList(spc@label, U) spc } ## helpers -.DATA.START <- c ("XYDATA", "DATA TABLE", "PEAK TABLE") +.DATA.START <- c("XYDATA", "DATA TABLE", "PEAK TABLE") -.key2names <- function (key){ - gsub ("[[:blank:]_-]", "", tolower (key)) +.key2names <- function(key) { + gsub("[[:blank:]_-]", "", tolower(key)) } -.test (read.jdx) <- function (){ - context ("test-read.jdx") - - files <- c (Sys.glob ("fileio/jcamp-dx/*.DX"), Sys.glob ("fileio/jcamp-dx/*.dx"), - Sys.glob ("fileio/jcamp-dx/*.jdx"), Sys.glob ("fileio/jcamp-dx/*.JCM"), - Sys.glob ("fileio/jcamp-dx/PE-IR/*.DX"), - "fileio/jcamp-dx/GMD_20111121_MDN35_ALK_JCAMP-shortened.txt" # MPI Golm, long version one is *slow* to read and exceeds memory limit +.test(read.jdx) <- function() { + context("test-read.jdx") + + files <- c( + Sys.glob("fileio/jcamp-dx/*.DX"), Sys.glob("fileio/jcamp-dx/*.dx"), + Sys.glob("fileio/jcamp-dx/*.jdx"), Sys.glob("fileio/jcamp-dx/*.JCM"), + Sys.glob("fileio/jcamp-dx/PE-IR/*.DX"), + "fileio/jcamp-dx/GMD_20111121_MDN35_ALK_JCAMP-shortened.txt" # MPI Golm, long version one is *slow* to read and exceeds memory limit ) - + ## these files need special parameters: - files <- setdiff (files, c ("fileio/jcamp-dx/shimadzu.jdx", "fileio/jcamp-dx/virgilio.jdx")) - - test_that ("JCAMP-DX examples that need particular parameter sets",{ - skip_if_not_fileio_available () - - expect_known_hash(read.jdx ("fileio/jcamp-dx/shimadzu.jdx", encoding = "latin1", keys.hdr2data=TRUE), - "55c392d767f7a7f268e55540d4496fb1") - expect_known_hash(read.jdx ("fileio/jcamp-dx/virgilio.jdx", ytol = 1e-9), - "da4a725d23efe4a1888496f1739294c2") + files <- setdiff(files, c("fileio/jcamp-dx/shimadzu.jdx", "fileio/jcamp-dx/virgilio.jdx")) + + test_that("JCAMP-DX examples that need particular parameter sets", { + skip_if_not_fileio_available() + + expect_known_hash( + read.jdx("fileio/jcamp-dx/shimadzu.jdx", encoding = "latin1", keys.hdr2data = TRUE), + "55c392d767f7a7f268e55540d4496fb1" + ) + expect_known_hash( + read.jdx("fileio/jcamp-dx/virgilio.jdx", ytol = 1e-9), + "da4a725d23efe4a1888496f1739294c2" + ) }) - - unsupported <- c ("fileio/jcamp-dx/BRUKER2.JCM", - "fileio/jcamp-dx/BRUKER1.JCM", - "fileio/jcamp-dx/TESTSPEC.DX", - "fileio/jcamp-dx/TEST32.DX", - "fileio/jcamp-dx/SPECFILE.DX", - "fileio/jcamp-dx/ISAS_MS2.DX", - "fileio/jcamp-dx/ISAS_MS3.DX", # NTUPLES - "fileio/jcamp-dx/BRUKSQZ.DX", - "fileio/jcamp-dx/BRUKDIF.DX", - "fileio/jcamp-dx/BRUKNTUP.DX", # NTUPLES - "fileio/jcamp-dx/ISAS_CDX.DX", # PEAK ASSIGNMENTS= (XYMA) - "fileio/jcamp-dx/TESTFID.DX", # NTUPLES - "fileio/jcamp-dx/TESTNTUP.DX" # NTUPLES + + unsupported <- c( + "fileio/jcamp-dx/BRUKER2.JCM", + "fileio/jcamp-dx/BRUKER1.JCM", + "fileio/jcamp-dx/TESTSPEC.DX", + "fileio/jcamp-dx/TEST32.DX", + "fileio/jcamp-dx/SPECFILE.DX", + "fileio/jcamp-dx/ISAS_MS2.DX", + "fileio/jcamp-dx/ISAS_MS3.DX", # NTUPLES + "fileio/jcamp-dx/BRUKSQZ.DX", + "fileio/jcamp-dx/BRUKDIF.DX", + "fileio/jcamp-dx/BRUKNTUP.DX", # NTUPLES + "fileio/jcamp-dx/ISAS_CDX.DX", # PEAK ASSIGNMENTS= (XYMA) + "fileio/jcamp-dx/TESTFID.DX", # NTUPLES + "fileio/jcamp-dx/TESTNTUP.DX" # NTUPLES + ) + + checksums <- c( + `fileio/jcamp-dx/AMA1.DX` = "5e8523b7022ec26cfb2541fdf929e997", + `fileio/jcamp-dx/AMA2.DX` = "b336f71c592bc81de04d27bbbb9ede52", + `fileio/jcamp-dx/AMA3.DX` = "34344a42a232227c14ab5de5dc04e096", + `fileio/jcamp-dx/br_154_1.DX` = "232ef45bf818221c05927e311ac407a3", + `fileio/jcamp-dx/BRUKAFFN.DX` = "2498cac17635ad21e4998a3e3e7eebfa", + `fileio/jcamp-dx/BRUKPAC.DX` = "401cbaa375b79323ed0dcc30a135d11d", + `fileio/jcamp-dx/IR_S_1.DX` = "8d7032508efaf79fcc955f888d60cd8f", + `fileio/jcamp-dx/ISAS_MS1.DX` = "43017647aa339d8e7aaf3fadbdbbf065", + `fileio/jcamp-dx/LABCALC.DX` = "55ffdb250279aee967b2f65bbbf7dd5e", + `fileio/jcamp-dx/PE1800.DX` = "31ac39a5db243c3aa01e1978b9ab1aa3", + `fileio/jcamp-dx/testjose.dx` = "3b229eb9b8f229acd57783328d36a697", + `fileio/jcamp-dx/sign-rustam.jdx` = "386bf0b94baa5007e11e6af294895012", + `fileio/jcamp-dx/PE-IR/br_1.DX` = "ab5fa92227625c287871d9e95091c364", + `fileio/jcamp-dx/PE-IR/br_2.DX` = "eff5a1b37121a8902c0e62ebb5de0013", + `fileio/jcamp-dx/PE-IR/br_3.DX` = "2762712b1317631d32969624c97fa940", + `fileio/jcamp-dx/PE-IR/br_4.DX` = "11ddb20e9f6676f709827ececda360ab", + `fileio/jcamp-dx/PE-IR/br_5.DX` = "ffa08204bfb2521dd8caa9d286eba519", + `fileio/jcamp-dx/PE-IR/fort_1.DX` = "e808e243ae646c0526ba009f3ac3f80a", + `fileio/jcamp-dx/PE-IR/fort_2.DX` = "df90e70f203294c8bfeac7a6141a552d", + `fileio/jcamp-dx/PE-IR/fort_3.DX` = "d43a2c4fbb2598a5028a1406f83e3c3d", + `fileio/jcamp-dx/PE-IR/fort_4.DX` = "5382afba5c8b7fffdc26f00e129035c7", + `fileio/jcamp-dx/PE-IR/fort_5.DX` = "745c8b0fdad48a945e084d6e6cb9f0c6", + `fileio/jcamp-dx/PE-IR/lp_1.DX` = "bcb0a1e1150bcd038a3e0e0e5a896b2b", + `fileio/jcamp-dx/PE-IR/lp_2.DX` = "7bc1c53f1363b2b02374442a1e8baa74", + `fileio/jcamp-dx/PE-IR/lp_3.DX` = "eaa58c46360be604169e979c0fe2caeb", + `fileio/jcamp-dx/PE-IR/lp_4.DX` = "3b8d54eca48095d3f6c3eafc7b903a25", + `fileio/jcamp-dx/PE-IR/lp_5.DX` = "a0eaa3ca11fb5a0dde83fa01296d72db", + `fileio/jcamp-dx/GMD_20111121_MDN35_ALK_JCAMP-shortened.txt` = "fd2e686f5dc78691c22033805ed56463" ) - - checksums <- c (`fileio/jcamp-dx/AMA1.DX` = '5e8523b7022ec26cfb2541fdf929e997', - `fileio/jcamp-dx/AMA2.DX` = 'b336f71c592bc81de04d27bbbb9ede52', - `fileio/jcamp-dx/AMA3.DX` = '34344a42a232227c14ab5de5dc04e096', - `fileio/jcamp-dx/br_154_1.DX` = '232ef45bf818221c05927e311ac407a3', - `fileio/jcamp-dx/BRUKAFFN.DX` = '2498cac17635ad21e4998a3e3e7eebfa', - `fileio/jcamp-dx/BRUKPAC.DX` = '401cbaa375b79323ed0dcc30a135d11d', - `fileio/jcamp-dx/IR_S_1.DX` = '8d7032508efaf79fcc955f888d60cd8f', - `fileio/jcamp-dx/ISAS_MS1.DX` = '43017647aa339d8e7aaf3fadbdbbf065', - `fileio/jcamp-dx/LABCALC.DX` = '55ffdb250279aee967b2f65bbbf7dd5e', - `fileio/jcamp-dx/PE1800.DX` = '31ac39a5db243c3aa01e1978b9ab1aa3', - `fileio/jcamp-dx/testjose.dx` = '3b229eb9b8f229acd57783328d36a697', - `fileio/jcamp-dx/sign-rustam.jdx` = '386bf0b94baa5007e11e6af294895012', - `fileio/jcamp-dx/PE-IR/br_1.DX` = 'ab5fa92227625c287871d9e95091c364', - `fileio/jcamp-dx/PE-IR/br_2.DX` = 'eff5a1b37121a8902c0e62ebb5de0013', - `fileio/jcamp-dx/PE-IR/br_3.DX` = '2762712b1317631d32969624c97fa940', - `fileio/jcamp-dx/PE-IR/br_4.DX` = '11ddb20e9f6676f709827ececda360ab', - `fileio/jcamp-dx/PE-IR/br_5.DX` = 'ffa08204bfb2521dd8caa9d286eba519', - `fileio/jcamp-dx/PE-IR/fort_1.DX` = 'e808e243ae646c0526ba009f3ac3f80a', - `fileio/jcamp-dx/PE-IR/fort_2.DX` = 'df90e70f203294c8bfeac7a6141a552d', - `fileio/jcamp-dx/PE-IR/fort_3.DX` = 'd43a2c4fbb2598a5028a1406f83e3c3d', - `fileio/jcamp-dx/PE-IR/fort_4.DX` = '5382afba5c8b7fffdc26f00e129035c7', - `fileio/jcamp-dx/PE-IR/fort_5.DX` = '745c8b0fdad48a945e084d6e6cb9f0c6', - `fileio/jcamp-dx/PE-IR/lp_1.DX` = 'bcb0a1e1150bcd038a3e0e0e5a896b2b', - `fileio/jcamp-dx/PE-IR/lp_2.DX` = '7bc1c53f1363b2b02374442a1e8baa74', - `fileio/jcamp-dx/PE-IR/lp_3.DX` = 'eaa58c46360be604169e979c0fe2caeb', - `fileio/jcamp-dx/PE-IR/lp_4.DX` = '3b8d54eca48095d3f6c3eafc7b903a25', - `fileio/jcamp-dx/PE-IR/lp_5.DX` = 'a0eaa3ca11fb5a0dde83fa01296d72db', - `fileio/jcamp-dx/GMD_20111121_MDN35_ALK_JCAMP-shortened.txt` = 'fd2e686f5dc78691c22033805ed56463' - ) - - + + test_that("JCAMP-DX example files", { - skip_if_not_fileio_available () - for (f in files [! files %in% unsupported]) { - spc <- read.jdx (f, ytol = 1e-6) - ## for wholesale updating of hashes (e.g. due to changes in initialize) + skip_if_not_fileio_available() + for (f in files [!files %in% unsupported]) { + spc <- read.jdx(f, ytol = 1e-6) + ## for wholesale updating of hashes (e.g. due to changes in initialize) ## output filename hash pairs: - #cat (sprintf ("`%s` = '%s',\n", f, digest (spc))) + # cat (sprintf ("`%s` = '%s',\n", f, digest (spc))) expect_known_hash(spc, checksums [f]) } }) -} \ No newline at end of file +} diff --git a/hyperSpec/R/read.mat.Cytospec.R b/hyperSpec/R/read.mat.Cytospec.R index 6ebd86906..4eb754521 100644 --- a/hyperSpec/R/read.mat.Cytospec.R +++ b/hyperSpec/R/read.mat.Cytospec.R @@ -19,47 +19,49 @@ ##' @seealso \code{R.matlab::readMat} ##' @export ##' @keywords IO file -read.mat.Cytospec <- function (file, keys2data = FALSE, blocks = TRUE) { - if (! requireNamespace ("R.matlab")) - stop ("package 'R.matlab' needed.") +read.mat.Cytospec <- function(file, keys2data = FALSE, blocks = TRUE) { + if (!requireNamespace("R.matlab")) { + stop("package 'R.matlab' needed.") + } tmp <- R.matlab::readMat(file) ## read spectra matrix spc <- tmp$C - d <- dim (spc) + d <- dim(spc) ## get wavelength information - fileinfo<-(tmp$Info[[1]]) - lwn <- as.numeric (fileinfo [grep ("LWN", fileinfo) - 1]) - hwn <- as.numeric (fileinfo [grep ("VWN", fileinfo) - 1]) - wn <- seq (lwn, hwn, length.out = dim (spc)[3]) + fileinfo <- (tmp$Info[[1]]) + lwn <- as.numeric(fileinfo [grep("LWN", fileinfo) - 1]) + hwn <- as.numeric(fileinfo [grep("VWN", fileinfo) - 1]) + wn <- seq(lwn, hwn, length.out = dim(spc)[3]) ## x + y coordinates - x <- rep (1 : d [1], d [2]) - y <- rep (1 : d [2], each = d [1]) + x <- rep(1:d [1], d [2]) + y <- rep(1:d [2], each = d [1]) - extra.data <- data.frame (x = x, y = y) + extra.data <- data.frame(x = x, y = y) nblocks <- d [4] - if (is.na (nblocks)) { # only one block => 3d array + if (is.na(nblocks)) { # only one block => 3d array nblocks <- 1 - dim (spc) <- c (dim (spc), 1L) + dim(spc) <- c(dim(spc), 1L) } - blocks <- seq (nblocks) [blocks] + blocks <- seq(nblocks) [blocks] - if (any (is.na (blocks))) { - warning ("Dropping requests to unavailable blocks.") - blocks <- blocks [! is.na (blocks)] + if (any(is.na(blocks))) { + warning("Dropping requests to unavailable blocks.") + blocks <- blocks [!is.na(blocks)] } - if (length (blocks) == 1L) { - result <- .block2hyperSpec (spc, extra.data, wn, blocks, file) + if (length(blocks) == 1L) { + result <- .block2hyperSpec(spc, extra.data, wn, blocks, file) } else { - result <- list () - for (b in blocks) - result [[b]] <- .block2hyperSpec (spc, extra.data, wn, b, file) + result <- list() + for (b in blocks) { + result [[b]] <- .block2hyperSpec(spc, extra.data, wn, b, file) + } } ## consistent file import behaviour across import functions @@ -68,16 +70,16 @@ read.mat.Cytospec <- function (file, keys2data = FALSE, blocks = TRUE) { result } -.block2hyperSpec <- function (spc, df, wn, block, file) { - spc <- spc [,,, block] +.block2hyperSpec <- function(spc, df, wn, block, file) { + spc <- spc [, , , block] - d <- dim (spc) - dim (spc) <- c (d [1] * d[2], d [3]) + d <- dim(spc) + dim(spc) <- c(d [1] * d[2], d [3]) df$block <- block ## consistent file import behaviour across import functions - .fileio.optional (new ("hyperSpec", spc = spc, wavelength = wn, data = df), - filename = file) + .fileio.optional(new("hyperSpec", spc = spc, wavelength = wn, data = df), + filename = file + ) } - diff --git a/hyperSpec/R/read.mat.Witec.R b/hyperSpec/R/read.mat.Witec.R index c27223793..74d307901 100644 --- a/hyperSpec/R/read.mat.Witec.R +++ b/hyperSpec/R/read.mat.Witec.R @@ -1,24 +1,28 @@ ## ' @export ##' @importFrom utils maintainer -read.mat.Witec <- function (file = stop ("filename or connection needed")){ - if (! requireNamespace ("R.matlab")) - stop ("package 'R.matlab' needed.") +read.mat.Witec <- function(file = stop("filename or connection needed")) { + if (!requireNamespace("R.matlab")) { + stop("package 'R.matlab' needed.") + } - data <- R.matlab::readMat (file) + data <- R.matlab::readMat(file) - if (length (data) > 1L) - stop ("Matlab file contains more than 1 object. This should not happen.\n", - "If it is nevertheless a WITec exported .mat file, please contact the ", - "maintainer (", maintainer("hyperSpec"), ") with\n", - "- output of `sessionInfo ()` and\n", - "- an example file") - spcname <- names (data) + if (length(data) > 1L) { + stop( + "Matlab file contains more than 1 object. This should not happen.\n", + "If it is nevertheless a WITec exported .mat file, please contact the ", + "maintainer (", maintainer("hyperSpec"), ") with\n", + "- output of `sessionInfo ()` and\n", + "- an example file" + ) + } + spcname <- names(data) data <- data [[1]] - spc <- new ("hyperSpec", spc = data$data) + spc <- new("hyperSpec", spc = data$data) spc$spcname <- spcname ## consistent file import behaviour across import functions - .fileio.optional (spc, file) + .fileio.optional(spc, file) } diff --git a/hyperSpec/R/read.spc.Kaiser.R b/hyperSpec/R/read.spc.Kaiser.R index 024f64e4a..074d8e8c4 100644 --- a/hyperSpec/R/read.spc.Kaiser.R +++ b/hyperSpec/R/read.spc.Kaiser.R @@ -17,58 +17,61 @@ ##' @examples ##' ## for examples, please see `vignette ("fileio", package = "hyperSpec")`. -read.spc.Kaiser <- function (files, ..., glob = TRUE) { +read.spc.Kaiser <- function(files, ..., glob = TRUE) { + if (glob) { + files <- Sys.glob(files) + } - if (glob) - files <- Sys.glob (files) + if (length(files) == 0) { + warning("No files found.") + return(new("hyperSpec")) + } - if (length (files) == 0){ - warning ("No files found.") - return (new ("hyperSpec")) - } + f <- files [1] - f <- files [1] + spc <- read.spc(f, no.object = TRUE, ...) - spc <- read.spc (f, no.object = TRUE, ...) + data <- spc$data [rep(1L, length(files)), , drop = FALSE] - data <- spc$data [rep (1L, length (files)),, drop = FALSE] + spc$spc <- spc$spc [rep(1L, length(files)), , drop = FALSE] - spc$spc <- spc$spc [rep (1L, length (files)), , drop = FALSE] + for (f in seq_along(files)) { + tmp <- read.spc(files [f], no.object = TRUE, ...) - for (f in seq_along (files)){ - tmp <- read.spc (files [f], no.object = TRUE, ...) + data [f, ] <- tmp$data + spc$spc [f, ] <- tmp$spc + } - data [f, ] <- tmp$data - spc$spc [f, ] <- tmp$spc - } + data$filename <- files - data$filename <- files - - spc <- new ("hyperSpec", wavelength = spc$wavelength, spc = spc$spc, data = data, - labels = tmp$label) - ## consistent file import behaviour across import functions - ## filenames already set - .fileio.optional(spc, file.keep.name = FALSE) + spc <- new("hyperSpec", + wavelength = spc$wavelength, spc = spc$spc, data = data, + labels = tmp$label + ) + ## consistent file import behaviour across import functions + ## filenames already set + .fileio.optional(spc, file.keep.name = FALSE) } ##' \code{read.spc.KaiserMap} is a wrapper for \code{read.spc.Kaiser} with predefined \code{log2data} ##' to fetch the stage position for each file. ##' @rdname read-spc-Kaiser ##' @export -read.spc.KaiserMap <- function (files, keys.log2data = NULL, ...) { - keys.log2data <- c ('Stage_X_Position','Stage_Y_Position','Stage_Z_Position', keys.log2data) +read.spc.KaiserMap <- function(files, keys.log2data = NULL, ...) { + keys.log2data <- c("Stage_X_Position", "Stage_Y_Position", "Stage_Z_Position", keys.log2data) - spc <- read.spc.Kaiser (files, keys.log2data = keys.log2data, ...) + spc <- read.spc.Kaiser(files, keys.log2data = keys.log2data, ...) - spc@data <- spc@data [, ! colnames (spc@data) %in% c ("z", "z.end"), drop = FALSE] + spc@data <- spc@data [, !colnames(spc@data) %in% c("z", "z.end"), drop = FALSE] - colnames (spc@data) <- gsub ("Stage_(.)_Position", "\\L\\1", colnames (spc@data), perl = TRUE) - for (cln in c ("x", "y", "z")) - spc@data [[cln]] <- as.numeric (spc@data [[cln]]) + colnames(spc@data) <- gsub("Stage_(.)_Position", "\\L\\1", colnames(spc@data), perl = TRUE) + for (cln in c("x", "y", "z")) { + spc@data [[cln]] <- as.numeric(spc@data [[cln]]) + } - spc@label$x <- expression (`/` (x, micro * m)) - spc@label$y <- expression (`/` (y, micro * m)) - spc@label$z <- expression (`/` (z, micro * m)) + spc@label$x <- expression(`/`(x, micro * m)) + spc@label$y <- expression(`/`(y, micro * m)) + spc@label$z <- expression(`/`(z, micro * m)) spc@label$z.end <- NULL spc @@ -82,21 +85,24 @@ read.spc.KaiserMap <- function (files, keys.log2data = NULL, ...) { ##' @param type what kind of measurement was done? If \code{"map"}, \code{read.spc.KaiserMap} is used ##' instead of \code{read.spc.Kaiser}. ##' @export -read.spc.KaiserLowHigh <- function (files = stop ("file names needed"), - type = c ("single", "map"), - ..., glob = TRUE) { - - if (glob) - files <- Sys.glob (files) - - files <- matrix (files, nrow = 2) - - type <- match.arg (type) - switch (type, - single = cbind (read.spc.Kaiser (files [1,], ..., glob = FALSE), - read.spc.Kaiser (files [2,], ..., glob = FALSE)), - map = cbind (read.spc.KaiserMap (files [1,], ..., glob = FALSE), - read.spc.KaiserMap (files [2,], ..., glob = FALSE)) - ) - +read.spc.KaiserLowHigh <- function(files = stop("file names needed"), + type = c("single", "map"), + ..., glob = TRUE) { + if (glob) { + files <- Sys.glob(files) + } + + files <- matrix(files, nrow = 2) + + type <- match.arg(type) + switch(type, + single = cbind( + read.spc.Kaiser(files [1, ], ..., glob = FALSE), + read.spc.Kaiser(files [2, ], ..., glob = FALSE) + ), + map = cbind( + read.spc.KaiserMap(files [1, ], ..., glob = FALSE), + read.spc.KaiserMap(files [2, ], ..., glob = FALSE) + ) + ) } diff --git a/hyperSpec/R/read.spc.R b/hyperSpec/R/read.spc.R index e3638df5c..883a066dd 100644 --- a/hyperSpec/R/read.spc.R +++ b/hyperSpec/R/read.spc.R @@ -6,147 +6,154 @@ ## Define constants --------------------------------------------------------------------------------- -.nul <- as.raw (0) +.nul <- as.raw(0) ## header sizes -.spc.size <- c (hdr = 512, subhdr = 32, subfiledir = 12, loghdr = 64) +.spc.size <- c(hdr = 512, subhdr = 32, subfiledir = 12, loghdr = 64) -.spc.default.keys.hdr2data <- c('fexper', 'fres', 'fsource') +.spc.default.keys.hdr2data <- c("fexper", "fres", "fsource") .spc.default.keys.log2data <- FALSE ## axis labeling ------------------------------------------------------------------------------------ ## x-axis units ..................................................................................... -.spc.FXTYPE <- c (expression (`/` (x, "a. u.")), #0 - expression (`/` (tilde (nu), cm^-1)), - expression (`/` (lambda, (mu * m))), - expression (`/` (lambda, nm)), - expression (`/` (t, s)), - expression (`/` (t, min)), - expression (`/` (f, Hz)), - expression (`/` (f, kHz)), - expression (`/` (f, MHz)), - expression (`/` (frac (m, z), frac (u, e))), - expression (`/` (delta, ppm)), # 10 - expression (`/` (t, d)), - expression (`/` (t, a)), - expression (`/` (Delta*tilde (nu), cm^-1)), - expression (`/` (E, eV)), - NA, # old version file uses label in gcatxt - 'Diode No', - 'Channel', - expression (`/` (x, degree)), - expression (`/` (T, degree*F)), - expression (`/` (T, degree*C)), # 20 - expression (`/` (T, K)), - 'Data Point', - expression (`/` (t, ms)), - expression (`/` (t, micro*s)), - expression (`/` (t, ns)), - expression (`/` (f, GHz)), - expression (`/` (lambda, cm)), - expression (`/` (lambda, m)), - expression (`/` (lambda, mm)), - expression (`/` (t, h)) # 30 +.spc.FXTYPE <- c( + expression(`/`(x, "a. u.")), # 0 + expression(`/`(tilde(nu), cm^-1)), + expression(`/`(lambda, (mu * m))), + expression(`/`(lambda, nm)), + expression(`/`(t, s)), + expression(`/`(t, min)), + expression(`/`(f, Hz)), + expression(`/`(f, kHz)), + expression(`/`(f, MHz)), + expression(`/`(frac(m, z), frac(u, e))), + expression(`/`(delta, ppm)), # 10 + expression(`/`(t, d)), + expression(`/`(t, a)), + expression(`/`(Delta * tilde(nu), cm^-1)), + expression(`/`(E, eV)), + NA, # old version file uses label in gcatxt + "Diode No", + "Channel", + expression(`/`(x, degree)), + expression(`/`(T, degree * F)), + expression(`/`(T, degree * C)), # 20 + expression(`/`(T, K)), + "Data Point", + expression(`/`(t, ms)), + expression(`/`(t, micro * s)), + expression(`/`(t, ns)), + expression(`/`(f, GHz)), + expression(`/`(lambda, cm)), + expression(`/`(lambda, m)), + expression(`/`(lambda, mm)), + expression(`/`(t, h)) # 30 ) -.spc.xlab <- function (x) { - if (is.character (x)) - x - else if (x <= length (.spc.FXTYPE) + 1) - .spc.FXTYPE [x + 1] - else - ## x = 255 is for double interferogram and supposed not to have a label. - ## Thus, returning NA is appropriate - NA +.spc.xlab <- function(x) { + if (is.character(x)) { + x + } else if (x <= length(.spc.FXTYPE) + 1) { + .spc.FXTYPE [x + 1] + } else { + ## x = 255 is for double interferogram and supposed not to have a label. + ## Thus, returning NA is appropriate + NA + } } ## y-axis units ..................................................................................... -.spc.FYTYPE <- c (expression (`/` (I[Ref], "a. u.")), # -1 - expression (`/` (I, "a. u.")), - expression (`/` (I[IGRM], "a. u.")), - 'A', - expression (frac ((1 - R)^2, 2 * R)), - 'Counts', - expression (`/` (U, V)), - expression (`/` (y, degree)), - expression (`/` (I, mA)), - expression (`/` (l, mm)), - expression (`/` (U, mV)), - expression (-log (R)), # 10 - expression (`/` (y, '%')), - expression (`/` (I, 'a. u.')), - expression (I / I[0]), - expression (`/` (E, J)), - NA, # old version file uses label in gcatxt - expression (`/` (G, dB)), - NA, # old version file uses label in gcatxt - NA, # old version file uses label in gcatxt - expression (`/` (T, degree*F)), - expression (`/` (T, degree*C)), # 20 - expression (`/` (T, K)), - 'n', - 'K', # extinction coeaffictient - expression (Re (y)), - expression (Im (y)), - 'y (complex)', # complex - 'T', - 'R', - expression (`/` (I, 'a. u.')), - expression (`/` (I[Emission], 'a. u.')) +.spc.FYTYPE <- c( + expression(`/`(I[Ref], "a. u.")), # -1 + expression(`/`(I, "a. u.")), + expression(`/`(I[IGRM], "a. u.")), + "A", + expression(frac((1 - R)^2, 2 * R)), + "Counts", + expression(`/`(U, V)), + expression(`/`(y, degree)), + expression(`/`(I, mA)), + expression(`/`(l, mm)), + expression(`/`(U, mV)), + expression(-log(R)), # 10 + expression(`/`(y, "%")), + expression(`/`(I, "a. u.")), + expression(I / I[0]), + expression(`/`(E, J)), + NA, # old version file uses label in gcatxt + expression(`/`(G, dB)), + NA, # old version file uses label in gcatxt + NA, # old version file uses label in gcatxt + expression(`/`(T, degree * F)), + expression(`/`(T, degree * C)), # 20 + expression(`/`(T, K)), + "n", + "K", # extinction coeaffictient + expression(Re(y)), + expression(Im(y)), + "y (complex)", # complex + "T", + "R", + expression(`/`(I, "a. u.")), + expression(`/`(I[Emission], "a. u.")) ) -.spc.ylab <- function(x){ - if (is.character (x)) - x - else if (x <= 26) - .spc.FYTYPE [x + 2] - else if (x %in% 128 : 131) - .spc.FYTYPE [x - 99] - else - NA +.spc.ylab <- function(x) { + if (is.character(x)) { + x + } else if (x <= 26) { + .spc.FYTYPE [x + 2] + } else if (x %in% 128:131) { + .spc.FYTYPE [x - 99] + } else { + NA + } } ## helper functions --------------------------------------------------------------------------------- ### raw.split.nul - rawToChar conversion, splitting at \0 ##' @importFrom utils tail -raw.split.nul <- function (raw, trunc = c (TRUE, TRUE), firstonly = FALSE, paste.collapse = NULL) { - # todo make better truncation - trunc <- rep (trunc, length.out = 2) - - if (trunc [1] && raw [1] == .nul) - raw <- raw [-1] - if (trunc [2]) { - tmp <- which (raw > .nul) - if (length (tmp) == 0) - return ("") - raw <- raw [1 : tail (tmp, 1)] - } - if (raw [length (raw)] != .nul) - raw <- c (raw , .nul) - - tmp <- c (0, which (raw == .nul)) - - out <- character (length (tmp) - 1) - for (i in 1 : (length (tmp) - 1)) - if (tmp [i] + 1 < tmp [i + 1] - 1) - out [i] <- rawToChar (raw [(tmp [i] + 1) : (tmp [i + 1] - 1)]) +raw.split.nul <- function(raw, trunc = c(TRUE, TRUE), firstonly = FALSE, paste.collapse = NULL) { + # todo make better truncation + trunc <- rep(trunc, length.out = 2) - if (length (out) > 1L){ - if (firstonly){ + if (trunc [1] && raw [1] == .nul) { + raw <- raw [-1] + } + if (trunc [2]) { + tmp <- which(raw > .nul) + if (length(tmp) == 0) { + return("") + } + raw <- raw [1:tail(tmp, 1)] + } + if (raw [length(raw)] != .nul) { + raw <- c(raw, .nul) + } - message ("multiple strings encountered in spc file ", paste (out, collapse = ", "), ": using only the first one.") - out <- out [1] + tmp <- c(0, which(raw == .nul)) - } else if (! is.null (paste.collapse)){ + out <- character(length(tmp) - 1) + for (i in 1:(length(tmp) - 1)) { + if (tmp [i] + 1 < tmp [i + 1] - 1) { + out [i] <- rawToChar(raw [(tmp [i] + 1):(tmp [i + 1] - 1)]) + } + } - if (hy.getOption ("debuglevel") > 2L) - message ("multiple strings encountered in spc file ", paste (out, collapse = ", "), " => pasting.") + if (length(out) > 1L) { + if (firstonly) { + message("multiple strings encountered in spc file ", paste(out, collapse = ", "), ": using only the first one.") + out <- out [1] + } else if (!is.null(paste.collapse)) { + if (hy.getOption("debuglevel") > 2L) { + message("multiple strings encountered in spc file ", paste(out, collapse = ", "), " => pasting.") + } - out <- paste (out, collapse = paste.collapse) - } - } + out <- paste(out, collapse = paste.collapse) + } + } - out + out } ## file part reading functions ---------------------------------------------------------------------- @@ -156,170 +163,196 @@ raw.split.nul <- function (raw, trunc = c (TRUE, TRUE), firstonly = FALSE, paste ## ##' @importFrom utils maintainer -.spc.filehdr <- function (raw.data) { - ## check file format +.spc.filehdr <- function(raw.data) { + ## check file format ## Detect Shimadzu SPC (which is effectively a variant of OLE CF format) - if (isTRUE (all.equal ( - raw.data[1:4], - as.raw(c('0xD0', '0xCF', '0x11', '0xE0')) - ))){ - stop ('Support for Shimadzu SPC file format (OLE CF) is not yet implemented') - } - - ## NEW.LSB = 75 supported, - ## NEW.MSB = 76 not supported (neither by many Grams software according to spc doc) - ## OLD = 77 not supported (replaced by new format in 1996) - if (raw.data [2] != 75) - stop ("Wrong spc file format version (or no spc file at all).\n", - "Only 'new' spc files (1996 file format) with LSB word order are supported.") - - hdr <- list (ftflgs = readBin (raw.data [ 1], "integer", 1, 1, signed = FALSE), - ## byte 2 is already interpreted - fexper = readBin (raw.data [ 3], "integer", 1, 1, signed = TRUE ), - fexp = readBin (raw.data [ 4], "integer", 1, 1, signed = TRUE ), - fnpts = readBin (raw.data [ 5 : 8], "integer", 1, 4 ), - ffirst = readBin (raw.data [ 9 : 16], "double", 1, 8 ), - flast = readBin (raw.data [ 17 : 24], "double", 1, 8 ), - fnsub = readBin (raw.data [ 25 : 28], "integer", 1, 4 ), - fxtype = readBin (raw.data [ 29], "integer", 1, 1, signed = FALSE), - fytype = readBin (raw.data [ 30], "integer", 1, 1, signed = FALSE), - fztype = readBin (raw.data [ 31], "integer", 1, 1, signed = FALSE), - fpost = readBin (raw.data [ 32], "integer", 1, 1, signed = TRUE ), - fdate = readBin (raw.data [ 33 : 36], "integer", 1, 4 ), - fres = raw.split.nul (raw.data [ 37 : 45], paste.collapse = "\r\n"), - fsource = raw.split.nul (raw.data [ 46 : 54], paste.collapse = "\r\n"), - fpeakpt = readBin (raw.data [ 55 : 56], "integer", 1, 2, signed = FALSE), - fspare = readBin (raw.data [ 57 : 88], "numeric", 8, 4 ), - fcmnt = raw.split.nul (raw.data [ 89 : 218], paste.collapse = "\r\n"), - fcatxt = raw.split.nul (raw.data [219 : 248], trunc = c (FALSE, TRUE) ), - flogoff = readBin (raw.data [249 : 252], "integer", 1, 4), #, signed = FALSE), - fmods = readBin (raw.data [253 : 256], "integer", 1, 4), #, signed = FALSE), - fprocs = readBin (raw.data [ 257], "integer", 1, 1, signed = TRUE ), - flevel = readBin (raw.data [ 258], "integer", 1, 1, signed = TRUE ), - fsampin = readBin (raw.data [259 : 260], "integer", 1, 2, signed = FALSE), - ffactor = readBin (raw.data [261 : 264], "numeric", 1, 4 ), - fmethod = raw.split.nul (raw.data [265 : 312]), - fzinc = readBin (raw.data [313 : 316], "numeric", 1, 4), #, signed = FALSE), - fwplanes = readBin (raw.data [317 : 320], "integer", 1, 4), #, signed = FALSE), - fwinc = readBin (raw.data [321 : 324], "numeric", 1, 4 ), - fwtype = readBin (raw.data [ 325], "integer", 1, 1, signed = TRUE ), - ## 187 bytes reserved - .last.read = .spc.size ['hdr'] - ) - - ## R doesn't have unsigned long int ................................. - if (any (unlist (hdr [c ("flogoff", "fmods", "fwplanes")]) < 0)) - stop ("error reading header: R does not support unsigned long integers.", - "Please contact the maintainer of the package.") - - - - ## do some post processing .......................................... - - experiments <- c ("General", "Gas Chromatogram", "General Chromatogram", "HPLC Chromatogram", - "NIR Spectrum", "UV-VIS Spectrum", "* reserved *", "X-ray diffraction spectrum", - "Mass Spectrum", "NMR Spectrum", "Raman Spectrum", "Fluorescence Spectrum", - "Atomic Spectrum", "Chroatography Diode Array Data") - hdr$fexper <- factor (hdr$fexper + 1, levels = seq_along (experiments)) - levels (hdr$fexper) <- experiments - - hdr$ftflgs <- .spc.ftflags (hdr$ftflgs) - - hdr$fdate <- ISOdate (year = hdr$fdate %/% 1048560, - month = hdr$fdate %/% 65536 %% 16, - day = hdr$fdate %/% 2048 %% 32, - hour = hdr$fdate %/% 64 %% 32, - min = hdr$fdate %% 64) - - ## interferogram ? - ## if not, hdr$fpeakpt is set to NULL - if (hdr$fytype == 1){ - if (hdr$fpeakpt != 0) - hdr$fpeakpt <- hdr$fpeakpt + 1 - } else { - hdr$fpeakpt <- NULL - } - - ## set the axis labels - if (hdr$ftflgs ['TALABS']) { - # TODO: find test data - tmp <- rep (0, 4) - tmp [seq_along (hdr$fcatxt)] <- nchar (hdr$fcatxt) - - if (tmp [1] > 0) hdr$fxtype <- hdr$fcatxt[1] - if (tmp [2] > 0) hdr$fytype <- hdr$fcatxt[2] - if (tmp [3] > 0) hdr$fztype <- hdr$fcatxt[3] - if (tmp [4] > 0) hdr$fwtype <- hdr$fcatxt[4] - } - hdr$fxtype <- .spc.xlab (hdr$fxtype) - hdr$fytype <- .spc.ylab (hdr$fytype) - hdr$fztype <- .spc.xlab (hdr$fztype) - hdr$fwtype <- .spc.xlab (hdr$fwtype) - - - ## File with subfiles with individual x axes? - ## Then there should be a subfile directory: - if (hdr$ftflgs ['TXYXYS'] && hdr$ftflgs ['TMULTI']){ - ## try to reject impossible values for the subfiledir offset - if (hdr$fnpts > length (raw.data) || - (hdr$fnpts > hdr$flogoff && hdr$flogoff > 0) || - hdr$fnpts < 512) - .spc.error (".spc.read.hdr", list (hdr = hdr), - "file header flags specify TXYXYS and TMULTI, ", - "but fnpts does not give a valid offset for the subfile directory.\n hdr$ftflgs = ", - paste (names (hdr$ftflgs)[hdr$ftflgs], collapse = " | "), - " (", sum (2^(0:7) [hdr$ftflgs]) , ")\n", - "You can try to read the file using hdr$ftflgs & ! TXYXYS (", - sum (2^(0 : 7) [hdr$ftflgs & c (TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE)]), - "). This assumes that all subfiles do have the same x axis.\n\n") - - hdr$subfiledir <- hdr$fnpts - hdr$fnpts <- 0 - } else { - hdr$subfiledir <- 0 - } - - - ## some checks ...................................................... - - if (hdr$ftflgs ['TMULTI']){ - ## multiple spectra in file - if (hdr$fnsub <= 1) - if (hy.getOption ("debuglevel") >= 2L) - message ("spc file header specifies multiple spectra but only zero or one subfile.") - } else { - ## single spectrum file - if (hdr$fnsub == 0) - hdr$fnsub <- 1 - - if (hdr$fnsub > 1) { - warning ("spc file header specifies single spectrum file but ", hdr$fnsub, - " subfiles (spectra).\nOnly first subfile will be read.") - hdr$fnsub <- 1 - } - - if (hdr$ftflgs ['TRANDM']) - message ("spc file header: file type flag TRANDM encountered => Enforcing TMULTI.") - - if (hdr$ftflgs ['TORDRD']) - message ("spc file header: file type flag TORDRD encountered => Enforcing TMULTI.") - - if ((hdr$ftflgs ['TRANDM'] || hdr$ftflgs ['TORDRD']) && hdr$fnsub > 1) - hdr$ftflgs ['TMULTI'] <- TRUE - } - - if (hdr$ftflgs ['TXYXYS'] && ! hdr$ftflgs ['TXVALS']) { - warning ("spc file header: file type flag TXYXYS encountered => Enforcing TXVALS.") - hdr$ftflgs ['TXVALS'] <- TRUE - } - - if (hdr$fwplanes > 0) - warning ("w planes found! This is not yet tested as the developer didn't have access to such files.\n", - "Please contact the package maintainer ", maintainer ("hyperSpec"), - " stating whether the file was imported successfully or not.") - - hdr + if (isTRUE(all.equal( + raw.data[1:4], + as.raw(c("0xD0", "0xCF", "0x11", "0xE0")) + ))) { + stop("Support for Shimadzu SPC file format (OLE CF) is not yet implemented") + } + + ## NEW.LSB = 75 supported, + ## NEW.MSB = 76 not supported (neither by many Grams software according to spc doc) + ## OLD = 77 not supported (replaced by new format in 1996) + if (raw.data [2] != 75) { + stop( + "Wrong spc file format version (or no spc file at all).\n", + "Only 'new' spc files (1996 file format) with LSB word order are supported." + ) + } + + hdr <- list( + ftflgs = readBin(raw.data [1], "integer", 1, 1, signed = FALSE), + ## byte 2 is already interpreted + fexper = readBin(raw.data [3], "integer", 1, 1, signed = TRUE), + fexp = readBin(raw.data [4], "integer", 1, 1, signed = TRUE), + fnpts = readBin(raw.data [5:8], "integer", 1, 4), + ffirst = readBin(raw.data [9:16], "double", 1, 8), + flast = readBin(raw.data [17:24], "double", 1, 8), + fnsub = readBin(raw.data [25:28], "integer", 1, 4), + fxtype = readBin(raw.data [29], "integer", 1, 1, signed = FALSE), + fytype = readBin(raw.data [30], "integer", 1, 1, signed = FALSE), + fztype = readBin(raw.data [31], "integer", 1, 1, signed = FALSE), + fpost = readBin(raw.data [32], "integer", 1, 1, signed = TRUE), + fdate = readBin(raw.data [33:36], "integer", 1, 4), + fres = raw.split.nul(raw.data [37:45], paste.collapse = "\r\n"), + fsource = raw.split.nul(raw.data [46:54], paste.collapse = "\r\n"), + fpeakpt = readBin(raw.data [55:56], "integer", 1, 2, signed = FALSE), + fspare = readBin(raw.data [57:88], "numeric", 8, 4), + fcmnt = raw.split.nul(raw.data [89:218], paste.collapse = "\r\n"), + fcatxt = raw.split.nul(raw.data [219:248], trunc = c(FALSE, TRUE)), + flogoff = readBin(raw.data [249:252], "integer", 1, 4), # , signed = FALSE), + fmods = readBin(raw.data [253:256], "integer", 1, 4), # , signed = FALSE), + fprocs = readBin(raw.data [257], "integer", 1, 1, signed = TRUE), + flevel = readBin(raw.data [258], "integer", 1, 1, signed = TRUE), + fsampin = readBin(raw.data [259:260], "integer", 1, 2, signed = FALSE), + ffactor = readBin(raw.data [261:264], "numeric", 1, 4), + fmethod = raw.split.nul(raw.data [265:312]), + fzinc = readBin(raw.data [313:316], "numeric", 1, 4), # , signed = FALSE), + fwplanes = readBin(raw.data [317:320], "integer", 1, 4), # , signed = FALSE), + fwinc = readBin(raw.data [321:324], "numeric", 1, 4), + fwtype = readBin(raw.data [325], "integer", 1, 1, signed = TRUE), + ## 187 bytes reserved + .last.read = .spc.size ["hdr"] + ) + + ## R doesn't have unsigned long int ................................. + if (any(unlist(hdr [c("flogoff", "fmods", "fwplanes")]) < 0)) { + stop( + "error reading header: R does not support unsigned long integers.", + "Please contact the maintainer of the package." + ) + } + + + + ## do some post processing .......................................... + + experiments <- c( + "General", "Gas Chromatogram", "General Chromatogram", "HPLC Chromatogram", + "NIR Spectrum", "UV-VIS Spectrum", "* reserved *", "X-ray diffraction spectrum", + "Mass Spectrum", "NMR Spectrum", "Raman Spectrum", "Fluorescence Spectrum", + "Atomic Spectrum", "Chroatography Diode Array Data" + ) + hdr$fexper <- factor(hdr$fexper + 1, levels = seq_along(experiments)) + levels(hdr$fexper) <- experiments + + hdr$ftflgs <- .spc.ftflags(hdr$ftflgs) + + hdr$fdate <- ISOdate( + year = hdr$fdate %/% 1048560, + month = hdr$fdate %/% 65536 %% 16, + day = hdr$fdate %/% 2048 %% 32, + hour = hdr$fdate %/% 64 %% 32, + min = hdr$fdate %% 64 + ) + + ## interferogram ? + ## if not, hdr$fpeakpt is set to NULL + if (hdr$fytype == 1) { + if (hdr$fpeakpt != 0) { + hdr$fpeakpt <- hdr$fpeakpt + 1 + } + } else { + hdr$fpeakpt <- NULL + } + + ## set the axis labels + if (hdr$ftflgs ["TALABS"]) { + # TODO: find test data + tmp <- rep(0, 4) + tmp [seq_along(hdr$fcatxt)] <- nchar(hdr$fcatxt) + + if (tmp [1] > 0) hdr$fxtype <- hdr$fcatxt[1] + if (tmp [2] > 0) hdr$fytype <- hdr$fcatxt[2] + if (tmp [3] > 0) hdr$fztype <- hdr$fcatxt[3] + if (tmp [4] > 0) hdr$fwtype <- hdr$fcatxt[4] + } + hdr$fxtype <- .spc.xlab(hdr$fxtype) + hdr$fytype <- .spc.ylab(hdr$fytype) + hdr$fztype <- .spc.xlab(hdr$fztype) + hdr$fwtype <- .spc.xlab(hdr$fwtype) + + + ## File with subfiles with individual x axes? + ## Then there should be a subfile directory: + if (hdr$ftflgs ["TXYXYS"] && hdr$ftflgs ["TMULTI"]) { + ## try to reject impossible values for the subfiledir offset + if (hdr$fnpts > length(raw.data) || + (hdr$fnpts > hdr$flogoff && hdr$flogoff > 0) || + hdr$fnpts < 512) { + .spc.error( + ".spc.read.hdr", list(hdr = hdr), + "file header flags specify TXYXYS and TMULTI, ", + "but fnpts does not give a valid offset for the subfile directory.\n hdr$ftflgs = ", + paste(names(hdr$ftflgs)[hdr$ftflgs], collapse = " | "), + " (", sum(2^(0:7) [hdr$ftflgs]), ")\n", + "You can try to read the file using hdr$ftflgs & ! TXYXYS (", + sum(2^(0:7) [hdr$ftflgs & c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE)]), + "). This assumes that all subfiles do have the same x axis.\n\n" + ) + } + + hdr$subfiledir <- hdr$fnpts + hdr$fnpts <- 0 + } else { + hdr$subfiledir <- 0 + } + + + ## some checks ...................................................... + + if (hdr$ftflgs ["TMULTI"]) { + ## multiple spectra in file + if (hdr$fnsub <= 1) { + if (hy.getOption("debuglevel") >= 2L) { + message("spc file header specifies multiple spectra but only zero or one subfile.") + } + } + } else { + ## single spectrum file + if (hdr$fnsub == 0) { + hdr$fnsub <- 1 + } + + if (hdr$fnsub > 1) { + warning( + "spc file header specifies single spectrum file but ", hdr$fnsub, + " subfiles (spectra).\nOnly first subfile will be read." + ) + hdr$fnsub <- 1 + } + + if (hdr$ftflgs ["TRANDM"]) { + message("spc file header: file type flag TRANDM encountered => Enforcing TMULTI.") + } + + if (hdr$ftflgs ["TORDRD"]) { + message("spc file header: file type flag TORDRD encountered => Enforcing TMULTI.") + } + + if ((hdr$ftflgs ["TRANDM"] || hdr$ftflgs ["TORDRD"]) && hdr$fnsub > 1) { + hdr$ftflgs ["TMULTI"] <- TRUE + } + } + + if (hdr$ftflgs ["TXYXYS"] && !hdr$ftflgs ["TXVALS"]) { + warning("spc file header: file type flag TXYXYS encountered => Enforcing TXVALS.") + hdr$ftflgs ["TXVALS"] <- TRUE + } + + if (hdr$fwplanes > 0) { + warning( + "w planes found! This is not yet tested as the developer didn't have access to such files.\n", + "Please contact the package maintainer ", maintainer("hyperSpec"), + " stating whether the file was imported successfully or not." + ) + } + + hdr } ## read sub file header ............................................................................. @@ -327,218 +360,263 @@ raw.split.nul <- function (raw, trunc = c (TRUE, TRUE), firstonly = FALSE, paste ## needs header for consistency checks ## -.spc.subhdr <- function (raw.data, pos, hdr) { - subhdr <- list (subflgs = raw.data [pos + ( 1)], - subexp = readBin (raw.data [pos + ( 2)], "integer", 1, 1, signed = TRUE), - subindx = readBin (raw.data [pos + ( 3 : 4)], "integer", 1, 2, signed = FALSE), - subtime = readBin (raw.data [pos + ( 5 : 8)], "numeric", 1, 4), - subnext = readBin (raw.data [pos + ( 9 : 12)], "numeric", 1, 4), - subnois = readBin (raw.data [pos + (13 : 16)], "numeric", 1, 4), - subnpts = readBin (raw.data [pos + (17 : 20)], "integer", 1, 4), #, signed = FALSE), - subscan = readBin (raw.data [pos + (21 : 24)], "integer", 1, 4), #, signed = FALSE), - subwlevel = readBin (raw.data [pos + (25 : 28)], "numeric", 1, 4)) - ## 4 bytes reserved - - ## R doesn't have unsigned long int ................................. - if (any (unlist (subhdr [c ("subnpts", "subscan")]) < 0)) - stop ("error reading subheader: R does not support unsigned long integers.", - "Please contact the maintainer of the package.") - - hdr$.last.read <- pos + .spc.size ['subhdr'] - - ## checking - if (subhdr$subexp == -128 && hdr$fexp != -128) - message ("subfile ", subhdr$subindx, " specifies data type float, but file header doesn't.", - "\n=> Data will be interpreted as float unless TMULTI is set.") - - if (subhdr$subnpts > 0 && subhdr$subnpts != hdr$fnpts && ! hdr$ftflgs ['TXYXYS']) - message ('subfile ', subhdr$subindx, ": number of points in file header and subfile header ", - "inconsistent. => Going to use subheader.") - - if (subhdr$subnpts == 0){ - if (hdr$ftflgs ['TXYXYS']) - message ('subfile ', subhdr$subindx, ': number of data points per spectrum not specified. ', - '=> Using file header information (', hdr$fnpts, ').') - subhdr$subnpts <- hdr$fnpts - } - - if (! hdr$ftflgs ['TXYXYS']) - if (hdr$fnpts != subhdr$subnpts) { - .spc.error (".spc.read.subhdr", list (hdr = hdr, subhdr = subhdr), - "hdr and subhdr differ in number of points per spectrum, ", - "but TXYXYS is not specified.\n hdr$ftflgs = ", - paste (names (hdr$ftflgs)[hdr$ftflgs], collapse = " | "), - " (", sum (2^(0:7) [hdr$ftflgs]) , ")\n", - "You can try to read the file using hdr$ftflgs | TMULTI | TXYXYS (", - sum (2^(0 : 7) [hdr$ftflgs | - c (FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE)]), - ").\n\n") - } - -# str (subhdr) - ## according to .spc file documentation: - if (! hdr$ftflgs ['TMULTI']) - subhdr$subexp <- hdr$fexp - else if (hdr$fexp == -128 && subhdr$subexp != -128) { - message ("Header file specifies float data format, but subfile uses integer exponent. ", - "=> Using file header settings.") - subhdr$subexp <- -128 - } - - ## the z values - if (hdr$fzinc == 0) # should only happen for the first subfile... - hdr$fzinc = subhdr$subnext - subhdr$subtime - - if (subhdr$subindx == 0) - hdr$firstz <- subhdr$subtime - - if (subhdr$subtime == 0) - subhdr$subtime = subhdr$subindx * hdr$fzinc + hdr$firstz - - ## the w values - if (hdr$fwplanes > 0) { - if (hdr$fwinc == 0) { ## unevenly spaced w planes - - } - - # if (subhdr$subwlevel != 0) { - # subhdr$w <- subhdr$subwlevel - # - # } else if (subhdr$subindx %% hdr$fwplanes == 1) - # subhdr$w <- hdr$subhdr$w + hdr$fwinc - # else - # subhdr$w <- hdr$subhdr$w - } - - - hdr$subhdr <- subhdr - - hdr +.spc.subhdr <- function(raw.data, pos, hdr) { + subhdr <- list( + subflgs = raw.data [pos + (1)], + subexp = readBin(raw.data [pos + (2)], "integer", 1, 1, signed = TRUE), + subindx = readBin(raw.data [pos + (3:4)], "integer", 1, 2, signed = FALSE), + subtime = readBin(raw.data [pos + (5:8)], "numeric", 1, 4), + subnext = readBin(raw.data [pos + (9:12)], "numeric", 1, 4), + subnois = readBin(raw.data [pos + (13:16)], "numeric", 1, 4), + subnpts = readBin(raw.data [pos + (17:20)], "integer", 1, 4), # , signed = FALSE), + subscan = readBin(raw.data [pos + (21:24)], "integer", 1, 4), # , signed = FALSE), + subwlevel = readBin(raw.data [pos + (25:28)], "numeric", 1, 4) + ) + ## 4 bytes reserved + + ## R doesn't have unsigned long int ................................. + if (any(unlist(subhdr [c("subnpts", "subscan")]) < 0)) { + stop( + "error reading subheader: R does not support unsigned long integers.", + "Please contact the maintainer of the package." + ) + } + + hdr$.last.read <- pos + .spc.size ["subhdr"] + + ## checking + if (subhdr$subexp == -128 && hdr$fexp != -128) { + message( + "subfile ", subhdr$subindx, " specifies data type float, but file header doesn't.", + "\n=> Data will be interpreted as float unless TMULTI is set." + ) + } + + if (subhdr$subnpts > 0 && subhdr$subnpts != hdr$fnpts && !hdr$ftflgs ["TXYXYS"]) { + message( + "subfile ", subhdr$subindx, ": number of points in file header and subfile header ", + "inconsistent. => Going to use subheader." + ) + } + + if (subhdr$subnpts == 0) { + if (hdr$ftflgs ["TXYXYS"]) { + message( + "subfile ", subhdr$subindx, ": number of data points per spectrum not specified. ", + "=> Using file header information (", hdr$fnpts, ")." + ) + } + subhdr$subnpts <- hdr$fnpts + } + + if (!hdr$ftflgs ["TXYXYS"]) { + if (hdr$fnpts != subhdr$subnpts) { + .spc.error( + ".spc.read.subhdr", list(hdr = hdr, subhdr = subhdr), + "hdr and subhdr differ in number of points per spectrum, ", + "but TXYXYS is not specified.\n hdr$ftflgs = ", + paste(names(hdr$ftflgs)[hdr$ftflgs], collapse = " | "), + " (", sum(2^(0:7) [hdr$ftflgs]), ")\n", + "You can try to read the file using hdr$ftflgs | TMULTI | TXYXYS (", + sum(2^(0:7) [hdr$ftflgs | + c(FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE)]), + ").\n\n" + ) + } + } + + # str (subhdr) + ## according to .spc file documentation: + if (!hdr$ftflgs ["TMULTI"]) { + subhdr$subexp <- hdr$fexp + } else if (hdr$fexp == -128 && subhdr$subexp != -128) { + message( + "Header file specifies float data format, but subfile uses integer exponent. ", + "=> Using file header settings." + ) + subhdr$subexp <- -128 + } + + ## the z values + if (hdr$fzinc == 0) { # should only happen for the first subfile... + hdr$fzinc <- subhdr$subnext - subhdr$subtime + } + + if (subhdr$subindx == 0) { + hdr$firstz <- subhdr$subtime + } + + if (subhdr$subtime == 0) { + subhdr$subtime <- subhdr$subindx * hdr$fzinc + hdr$firstz + } + + ## the w values + if (hdr$fwplanes > 0) { + if (hdr$fwinc == 0) { ## unevenly spaced w planes + } + + # if (subhdr$subwlevel != 0) { + # subhdr$w <- subhdr$subwlevel + # + # } else if (subhdr$subindx %% hdr$fwplanes == 1) + # subhdr$w <- hdr$subhdr$w + hdr$fwinc + # else + # subhdr$w <- hdr$subhdr$w + } + + + hdr$subhdr <- subhdr + + hdr } ## read subfile directory ........................................................................... ## -.spc.subfiledir <- function (raw.data, pos, nsub) { - dir <- data.frame (ssfposn = rep (NA, nsub), - ssfsize = rep (NA, nsub), - ssftime = rep (NA, nsub)) - - for (s in seq_len (nsub)){ - dir [s,] <- c (readBin (raw.data [pos + ( 1 : 4)], "integer", 1, 4), # , signed = FALSE), - readBin (raw.data [pos + ( 5 : 8)], "integer", 1, 4), # , signed = FALSE), - readBin (raw.data [pos + ( 9 : 12)], "numeric", 1, 4)) - pos <- pos + .spc.size ['subfiledir'] - } - - ## R doesn't have unsigned long int ................................. - if (any (dir [, 1:2] < 0)) - stop ("error reading subfiledir: R does not support unsigned long integers.", - "Please contact the maintainer of the package.") - -# dir$ssfposn <- dir$ssfposn - dir +.spc.subfiledir <- function(raw.data, pos, nsub) { + dir <- data.frame( + ssfposn = rep(NA, nsub), + ssfsize = rep(NA, nsub), + ssftime = rep(NA, nsub) + ) + + for (s in seq_len(nsub)) { + dir [s, ] <- c( + readBin(raw.data [pos + (1:4)], "integer", 1, 4), # , signed = FALSE), + readBin(raw.data [pos + (5:8)], "integer", 1, 4), # , signed = FALSE), + readBin(raw.data [pos + (9:12)], "numeric", 1, 4) + ) + pos <- pos + .spc.size ["subfiledir"] + } + + ## R doesn't have unsigned long int ................................. + if (any(dir [, 1:2] < 0)) { + stop( + "error reading subfiledir: R does not support unsigned long integers.", + "Please contact the maintainer of the package." + ) + } + + # dir$ssfposn <- dir$ssfposn + dir } ## read log block header ............................................................................ ## ##' @importFrom utils head tail -.spc.log <- function (raw.data, pos, log.bin, log.disk, log.txt, keys.log2data, - replace.nul = as.raw (255), iconv.from = "latin1", iconv.to = "utf8") { - - if (pos == 0) # no log block exists - return (list (data = list (), - log = list ())) - - loghdr <- list (logsizd = readBin (raw.data [pos + ( 1 : 4)], "integer", 1, 4), # , signed = FALSE), - logsizm = readBin (raw.data [pos + ( 5 : 8)], "integer", 1, 4), # , signed = FALSE), - logtxto = readBin (raw.data [pos + ( 9 : 12)], "integer", 1, 4), # , signed = FALSE), - logbins = readBin (raw.data [pos + (13 : 16)], "integer", 1, 4), # , signed = FALSE), - logdsks = readBin (raw.data [pos + (17 : 20)], "integer", 1, 4), # , signed = FALSE), - ## 44 bytes reserved - .last.read = pos + .spc.size ['loghdr'] - ) - - ## R doesn't have unsigned long int ................................. - if (any (unlist (loghdr) < 0)) - stop ("error reading log: R does not support unsigned long integers.", - "Please contact the maintainer of the package.") - - log <- list () - data <- list () - - ## read binary part of log - if (log.bin) - log$.log.bin <- raw.data [loghdr$.last.read + seq_len (loghdr$logbins)] - - ## read binary on-disk-only part of log - if (log.disk) - log$.log.disk <- raw.data [loghdr$.last.read + loghdr$logbins + seq_len (loghdr$logdsks)] - - ## read text part of log - if (log.txt & loghdr$logsizd > loghdr$logtxto) { - log.txt <- raw.data [pos + loghdr$logtxto + seq_len (loghdr$logsizd - loghdr$logtxto)] - if (tail (log.txt, 1) == .nul) # throw away nul at the end - log.txt <- head (log.txt, -1) - log.txt [log.txt == .nul] <- replace.nul - log.txt <- readChar (log.txt, length (log.txt), useBytes=T) - log.txt <- gsub (rawToChar (replace.nul), '\r\n', log.txt) - log.txt <- iconv (log.txt, iconv.from, iconv.to) - log.txt <- split.string (log.txt, "\r\n") ## spc file spec says \r\n regardless of OS - log.txt <- split.line (log.txt, "=") - data <- getbynames (log.txt, keys.log2data) - } - - list (log.long = log, extra.data = data) +.spc.log <- function(raw.data, pos, log.bin, log.disk, log.txt, keys.log2data, + replace.nul = as.raw(255), iconv.from = "latin1", iconv.to = "utf8") { + if (pos == 0) { # no log block exists + return(list( + data = list(), + log = list() + )) + } + + loghdr <- list( + logsizd = readBin(raw.data [pos + (1:4)], "integer", 1, 4), # , signed = FALSE), + logsizm = readBin(raw.data [pos + (5:8)], "integer", 1, 4), # , signed = FALSE), + logtxto = readBin(raw.data [pos + (9:12)], "integer", 1, 4), # , signed = FALSE), + logbins = readBin(raw.data [pos + (13:16)], "integer", 1, 4), # , signed = FALSE), + logdsks = readBin(raw.data [pos + (17:20)], "integer", 1, 4), # , signed = FALSE), + ## 44 bytes reserved + .last.read = pos + .spc.size ["loghdr"] + ) + + ## R doesn't have unsigned long int ................................. + if (any(unlist(loghdr) < 0)) { + stop( + "error reading log: R does not support unsigned long integers.", + "Please contact the maintainer of the package." + ) + } + + log <- list() + data <- list() + + ## read binary part of log + if (log.bin) { + log$.log.bin <- raw.data [loghdr$.last.read + seq_len(loghdr$logbins)] + } + + ## read binary on-disk-only part of log + if (log.disk) { + log$.log.disk <- raw.data [loghdr$.last.read + loghdr$logbins + seq_len(loghdr$logdsks)] + } + + ## read text part of log + if (log.txt & loghdr$logsizd > loghdr$logtxto) { + log.txt <- raw.data [pos + loghdr$logtxto + seq_len(loghdr$logsizd - loghdr$logtxto)] + if (tail(log.txt, 1) == .nul) { # throw away nul at the end + log.txt <- head(log.txt, -1) + } + log.txt [log.txt == .nul] <- replace.nul + log.txt <- readChar(log.txt, length(log.txt), useBytes = T) + log.txt <- gsub(rawToChar(replace.nul), "\r\n", log.txt) + log.txt <- iconv(log.txt, iconv.from, iconv.to) + log.txt <- split.string(log.txt, "\r\n") ## spc file spec says \r\n regardless of OS + log.txt <- split.line(log.txt, "=") + data <- getbynames(log.txt, keys.log2data) + } + + list(log.long = log, extra.data = data) } ## read y data ...................................................................................... ## -.spc.read.y <- function (raw.data, pos, npts, exponent, word) { - if (exponent == -128) { # 4 byte float - - list (y = readBin (raw.data [pos + seq_len (npts * 4)], "numeric", npts, 4), - .last.read = pos + npts * 4) +.spc.read.y <- function(raw.data, pos, npts, exponent, word) { + if (exponent == -128) { # 4 byte float - } else if (word) { # 2 byte fixed point integer = word - - list (y = readBin (raw.data [pos + seq_len (npts * 2)], "integer", npts, 2, signed = TRUE) * - 2 ^ (exponent - 16), - .last.read = pos + npts * 2) + list( + y = readBin(raw.data [pos + seq_len(npts * 4)], "numeric", npts, 4), + .last.read = pos + npts * 4 + ) + } else if (word) { # 2 byte fixed point integer = word - } else { # 4 byte fixed point integer = dword - list (y = readBin (raw.data [pos + seq_len (npts * 4)], "integer", npts, 4) * - 2 ^ (exponent - 32), - .last.read = pos + npts * 4) - } + list( + y = readBin(raw.data [pos + seq_len(npts * 2)], "integer", npts, 2, signed = TRUE) * + 2^(exponent - 16), + .last.read = pos + npts * 2 + ) + } else { # 4 byte fixed point integer = dword + list( + y = readBin(raw.data [pos + seq_len(npts * 4)], "integer", npts, 4) * + 2^(exponent - 32), + .last.read = pos + npts * 4 + ) + } } ## read x data ...................................................................................... ## -.spc.read.x <- function (raw.data, pos, npts) { - list (x = readBin (raw.data [pos + seq_len (npts * 4)], "numeric", npts, 4), - .last.read = pos + 4 * npts) +.spc.read.x <- function(raw.data, pos, npts) { + list( + x = readBin(raw.data [pos + seq_len(npts * 4)], "numeric", npts, 4), + .last.read = pos + 4 * npts + ) } ## error ............................................................................................. ##' @importFrom utils str -.spc.error <- function (fname, objects, ...) { - cat ('ERROR in read.spc function ', fname, '\n\n') - for (i in seq_along (objects)) { - cat (names (objects) [i], ":\n") - str (objects [[i]], vec.len = 20) - } - stop (...) +.spc.error <- function(fname, objects, ...) { + cat("ERROR in read.spc function ", fname, "\n\n") + for (i in seq_along(objects)) { + cat(names(objects) [i], ":\n") + str(objects [[i]], vec.len = 20) + } + stop(...) } -.spc.ftflags <- function (x) { - ftflgs <- as.logical (x %/% 2^(0 : 7) %% 2) - names (ftflgs) <- c ('TSPREC', 'TCGRAM', 'TMULTI', 'TRANDM', - 'TORDRD', 'TALABS', 'TXYXYS', 'TXVALS') - ftflgs +.spc.ftflags <- function(x) { + ftflgs <- as.logical(x %/% 2^(0:7) %% 2) + names(ftflgs) <- c( + "TSPREC", "TCGRAM", "TMULTI", "TRANDM", + "TORDRD", "TALABS", "TXYXYS", "TXVALS" + ) + ftflgs } ##################################################################################################### @@ -605,238 +683,259 @@ raw.split.nul <- function (raw, trunc = c (TRUE, TRUE), firstonly = FALSE, paste ##' } ##' ##' @importFrom utils modifyList -read.spc <- function (filename, - keys.hdr2data = FALSE, keys.log2data = FALSE, - log.txt = TRUE, log.bin = FALSE, log.disk = FALSE, - hdr = list (), - no.object = FALSE){ - - ## f contains the raw bytes of the file - - ## fpos marks the position of the last read byte - ## this is the same as the offset from beginning of the file (count 0) in the .spc definition - - f <- readBin (filename, "raw", file.info (filename)$size, 1) - - hdr <- modifyList (.spc.filehdr (f), hdr) - fpos <- hdr$.last.read - - if (! hdr$ftflgs ['TXYXYS']) { - if (! hdr$ftflgs ['TXVALS']) { - ## spectra with common evenly spaced wavelength axis - wavelength <- seq (hdr$ffirst, hdr$flast, length.out = hdr$fnpts) - } else { - ## spectra with common unevenly spaced wavelength axis - # if (! hdr$ftflgs ['TMULTI']) { # also for multifile with common wavelength axis - tmp <- .spc.read.x (f, fpos, hdr$fnpts) - wavelength <- tmp$x - fpos <- tmp$.last.read - } - #} - } - - ## otherwise (TXYXYS set) hdr$fnpts gives offset to subfile directory if that exists - - ## obtain labels from file hdr or from parameter - label <- list (.wavelength = hdr$fxtype, spc = hdr$fytype, - z = hdr$fztype, z.end = hdr$fztype) - - if (hdr$fwplanes > 0) - label$w <- hdr$fwtype - - ## prepare list for hyperSpec log and data.frame for extra data - - data <- list (z = NA, z.end = NA) - if (hdr$fwplanes > 0) - data <- c (data, w = NA) - - ## process the log block - tmp <- .spc.log (f, hdr$flogoff, - log.bin, log.disk, log.txt, - keys.log2data) - ## TODO: remove data2log - - data <- c (data, tmp$extra.data, getbynames (hdr, keys.hdr2data)) - - ## preallocate spectra matrix or list for multispectra file with separate wavelength axes - ## populate extra data - if (hdr$ftflgs ['TXYXYS'] && hdr$ftflgs ['TMULTI']) { - spc <- list () - data <- .prepare.hdr.df (data, nsubfiles = 1L) - } else { - spc <- matrix (NA, nrow = hdr$fnsub, ncol = hdr$fnpts) - data <- .prepare.hdr.df (data, nsubfiles = hdr$fnsub) - } - - ## read subfiles - if (hdr$subfiledir){ ## TXYXYS - hdr$subfiledir <- .spc.subfiledir (f, hdr$subfiledir, hdr$fnsub) - - for (s in seq_len (hdr$fnsub)) { - - hdr <- .spc.subhdr (f, hdr$subfiledir$ssfposn [s], hdr) - fpos <- hdr$.last.read - wavelength <- .spc.read.x (f, fpos, hdr$subhdr$subnpts) - fpos <- wavelength$.last.read - - y <- .spc.read.y (f, fpos, npts = hdr$subhdr$subnpts, exponent = hdr$subhdr$subexp, - word = hdr$ftflgs ['TSPREC']) - fpos <- y$.last.read - - data$z <- hdr$subhdr$subtime - data$z.end <- hdr$subhdr$subnext - - if (hdr$fwplanes > 0) - data$w <- hdr$subhdr$w - - if (! exists ('wavelength')) - .spc.error ("read.spc", list (hdr = hdr), - "wavelength not read. This may be caused by wrong header information.") - - spc [[s]] <- new ("hyperSpec", - spc = y$y, - wavelength = wavelength$x, - data = data, - labels = label) - } - - } else { ## multiple y data blocks behind each other - for (s in seq_len (hdr$fnsub)) { - hdr <- .spc.subhdr (f, fpos, hdr) - fpos <- hdr$.last.read - tmp <- .spc.read.y (f, fpos, npts = hdr$subhdr$subnpts, exponent = hdr$subhdr$subexp, - word = hdr$ftflgs ['TSPREC']) - fpos <- tmp$.last.read - - spc [s, ] <- tmp$y - - data [s, c('z', 'z.end')] <- unlist (hdr$subhdr [c('subtime', 'subnext')]) - - if (hdr$fwplanes > 0) - data [s, "w"] <- hdr$subhdr$w - } - } - - if (hdr$ftflgs ['TXYXYS'] && hdr$ftflgs ['TMULTI']) - ## list of hyperSpec objects - ## consistent file import behaviour across import functions - lapply (spc, .fileio.optional, filename = filename) - else if (no.object) - list (spc = spc, wavelength = wavelength, data = data, labels = label) - else { - if (hdr$fnsub > 1L && nrow (data) == 1L) - data <- data [rep (1L, hdr$fnsub), ] - - spc <- new ("hyperSpec", spc = spc, wavelength = wavelength, - data = data, labels = label) - - ## consistent file import behaviour across import functions - .fileio.optional (spc, filename) - } +read.spc <- function(filename, + keys.hdr2data = FALSE, keys.log2data = FALSE, + log.txt = TRUE, log.bin = FALSE, log.disk = FALSE, + hdr = list(), + no.object = FALSE) { + + ## f contains the raw bytes of the file + + ## fpos marks the position of the last read byte + ## this is the same as the offset from beginning of the file (count 0) in the .spc definition + + f <- readBin(filename, "raw", file.info(filename)$size, 1) + + hdr <- modifyList(.spc.filehdr(f), hdr) + fpos <- hdr$.last.read + + if (!hdr$ftflgs ["TXYXYS"]) { + if (!hdr$ftflgs ["TXVALS"]) { + ## spectra with common evenly spaced wavelength axis + wavelength <- seq(hdr$ffirst, hdr$flast, length.out = hdr$fnpts) + } else { + ## spectra with common unevenly spaced wavelength axis + # if (! hdr$ftflgs ['TMULTI']) { # also for multifile with common wavelength axis + tmp <- .spc.read.x(f, fpos, hdr$fnpts) + wavelength <- tmp$x + fpos <- tmp$.last.read + } + # } + } + + ## otherwise (TXYXYS set) hdr$fnpts gives offset to subfile directory if that exists + + ## obtain labels from file hdr or from parameter + label <- list( + .wavelength = hdr$fxtype, spc = hdr$fytype, + z = hdr$fztype, z.end = hdr$fztype + ) + + if (hdr$fwplanes > 0) { + label$w <- hdr$fwtype + } + + ## prepare list for hyperSpec log and data.frame for extra data + + data <- list(z = NA, z.end = NA) + if (hdr$fwplanes > 0) { + data <- c(data, w = NA) + } + + ## process the log block + tmp <- .spc.log( + f, hdr$flogoff, + log.bin, log.disk, log.txt, + keys.log2data + ) + ## TODO: remove data2log + + data <- c(data, tmp$extra.data, getbynames(hdr, keys.hdr2data)) + + ## preallocate spectra matrix or list for multispectra file with separate wavelength axes + ## populate extra data + if (hdr$ftflgs ["TXYXYS"] && hdr$ftflgs ["TMULTI"]) { + spc <- list() + data <- .prepare.hdr.df(data, nsubfiles = 1L) + } else { + spc <- matrix(NA, nrow = hdr$fnsub, ncol = hdr$fnpts) + data <- .prepare.hdr.df(data, nsubfiles = hdr$fnsub) + } + + ## read subfiles + if (hdr$subfiledir) { ## TXYXYS + hdr$subfiledir <- .spc.subfiledir(f, hdr$subfiledir, hdr$fnsub) + + for (s in seq_len(hdr$fnsub)) { + hdr <- .spc.subhdr(f, hdr$subfiledir$ssfposn [s], hdr) + fpos <- hdr$.last.read + wavelength <- .spc.read.x(f, fpos, hdr$subhdr$subnpts) + fpos <- wavelength$.last.read + + y <- .spc.read.y(f, fpos, + npts = hdr$subhdr$subnpts, exponent = hdr$subhdr$subexp, + word = hdr$ftflgs ["TSPREC"] + ) + fpos <- y$.last.read + + data$z <- hdr$subhdr$subtime + data$z.end <- hdr$subhdr$subnext + + if (hdr$fwplanes > 0) { + data$w <- hdr$subhdr$w + } + + if (!exists("wavelength")) { + .spc.error( + "read.spc", list(hdr = hdr), + "wavelength not read. This may be caused by wrong header information." + ) + } + + spc [[s]] <- new("hyperSpec", + spc = y$y, + wavelength = wavelength$x, + data = data, + labels = label + ) + } + } else { ## multiple y data blocks behind each other + for (s in seq_len(hdr$fnsub)) { + hdr <- .spc.subhdr(f, fpos, hdr) + fpos <- hdr$.last.read + tmp <- .spc.read.y(f, fpos, + npts = hdr$subhdr$subnpts, exponent = hdr$subhdr$subexp, + word = hdr$ftflgs ["TSPREC"] + ) + fpos <- tmp$.last.read + + spc [s, ] <- tmp$y + + data [s, c("z", "z.end")] <- unlist(hdr$subhdr [c("subtime", "subnext")]) + + if (hdr$fwplanes > 0) { + data [s, "w"] <- hdr$subhdr$w + } + } + } + + if (hdr$ftflgs ["TXYXYS"] && hdr$ftflgs ["TMULTI"]) { + ## list of hyperSpec objects + ## consistent file import behaviour across import functions + lapply(spc, .fileio.optional, filename = filename) + } else if (no.object) { + list(spc = spc, wavelength = wavelength, data = data, labels = label) + } else { + if (hdr$fnsub > 1L && nrow(data) == 1L) { + data <- data [rep(1L, hdr$fnsub), ] + } + + spc <- new("hyperSpec", + spc = spc, wavelength = wavelength, + data = data, labels = label + ) + + ## consistent file import behaviour across import functions + .fileio.optional(spc, filename) + } } -.test (read.spc) <- function (){ - context ("read.spc") +.test(read.spc) <- function() { + context("read.spc") - old.spc <- paste0 ("fileio/spc/", c ('CONTOUR.SPC', 'DEMO 3D.SPC', 'LC DIODE ARRAY.SPC')) + old.spc <- paste0("fileio/spc/", c("CONTOUR.SPC", "DEMO 3D.SPC", "LC DIODE ARRAY.SPC")) wplanes <- "fileio/spc/wplanes.spc" - other.spc <- setdiff (Sys.glob ("fileio/spc/*.[sS][pP][cC]"), c (old.spc, wplanes)) + other.spc <- setdiff(Sys.glob("fileio/spc/*.[sS][pP][cC]"), c(old.spc, wplanes)) - test_that ("old file format -> error", { + test_that("old file format -> error", { skip_if_not_fileio_available() - for (f in old.spc) - expect_error (read.spc (f)) + for (f in old.spc) { + expect_error(read.spc(f)) + } }) test_that("SPC SDK example files", { skip_if_not_fileio_available() - checksums <- c (`fileio/spc/BARBITUATES.SPC` = 'f49bbc854c', - `fileio/spc/barbsvd.spc` = '8a4d30672c', - `fileio/spc/BENZENE.SPC` = '6fc7901d15', - `fileio/spc/DRUG SAMPLE_PEAKS.SPC` = 'a600cd05e2', - `fileio/spc/DRUG SAMPLE.SPC` = '981e42bfb8', - `fileio/spc/FID.SPC` = 'ab65b6bb23', - `fileio/spc/HCL.SPC` = 'c657dd8279', - `fileio/spc/HOLMIUM.SPC` = '18dc3b1ca3', - `fileio/spc/IG_BKGND.SPC` = '0b083dab3a', - `fileio/spc/IG_MULTI.SPC` = 'fed652db3b', - `fileio/spc/IG_SAMP.SPC` = 'c72dd5fc70', - `fileio/spc/KKSAM.SPC` = '8e905a5500', - `fileio/spc/POLYR.SPC` = '78b5987d93', - `fileio/spc/POLYS.SPC` = '608c01f69b', - `fileio/spc/SINGLE POLYMER FILM.SPC` = '0e13423de4', - `fileio/spc/SPECTRUM WITH BAD BASELINE.SPC` = 'a05b77fada', - `fileio/spc/time.spc` = '98eabdd347', - `fileio/spc/TOLUENE.SPC` = 'eb08948be8', - `fileio/spc/TriVista-linear.spc` = '31b30dac34', - `fileio/spc/TriVista-normal.spc` = '15d5d219b0', - `fileio/spc/TUMIX.SPC` = '7f8db885fb', - `fileio/spc/TWO POLYMER FILMS.SPC` = '173a0bb6d3', - `fileio/spc/Witec-timeseries.spc` = '65f84533d8', - `fileio/spc/XYTRACE.SPC` = '28594b6078') - - for (f in other.spc ) { + checksums <- c( + `fileio/spc/BARBITUATES.SPC` = "f49bbc854c", + `fileio/spc/barbsvd.spc` = "8a4d30672c", + `fileio/spc/BENZENE.SPC` = "6fc7901d15", + `fileio/spc/DRUG SAMPLE_PEAKS.SPC` = "a600cd05e2", + `fileio/spc/DRUG SAMPLE.SPC` = "981e42bfb8", + `fileio/spc/FID.SPC` = "ab65b6bb23", + `fileio/spc/HCL.SPC` = "c657dd8279", + `fileio/spc/HOLMIUM.SPC` = "18dc3b1ca3", + `fileio/spc/IG_BKGND.SPC` = "0b083dab3a", + `fileio/spc/IG_MULTI.SPC` = "fed652db3b", + `fileio/spc/IG_SAMP.SPC` = "c72dd5fc70", + `fileio/spc/KKSAM.SPC` = "8e905a5500", + `fileio/spc/POLYR.SPC` = "78b5987d93", + `fileio/spc/POLYS.SPC` = "608c01f69b", + `fileio/spc/SINGLE POLYMER FILM.SPC` = "0e13423de4", + `fileio/spc/SPECTRUM WITH BAD BASELINE.SPC` = "a05b77fada", + `fileio/spc/time.spc` = "98eabdd347", + `fileio/spc/TOLUENE.SPC` = "eb08948be8", + `fileio/spc/TriVista-linear.spc` = "31b30dac34", + `fileio/spc/TriVista-normal.spc` = "15d5d219b0", + `fileio/spc/TUMIX.SPC` = "7f8db885fb", + `fileio/spc/TWO POLYMER FILMS.SPC` = "173a0bb6d3", + `fileio/spc/Witec-timeseries.spc` = "65f84533d8", + `fileio/spc/XYTRACE.SPC` = "28594b6078" + ) + + for (f in other.spc) { ## for wholesale output of current hashes: - # cat (sprintf ("`%s` = '%s',\n", f, digest (read.spc (f)))) - expect_known_hash (read.spc (f), checksums [f]) + # cat (sprintf ("`%s` = '%s',\n", f, digest (read.spc (f)))) + expect_known_hash(read.spc(f), checksums [f]) } }) test_that("LabRam spc files", { skip_if_not_fileio_available() - expect_known_hash (read.spc("fileio/spc.LabRam/LabRam-1.spc"), "d67562e4b4") - expect_known_hash (read.spc("fileio/spc.LabRam/LabRam-2.spc"), "c87094210a") + expect_known_hash(read.spc("fileio/spc.LabRam/LabRam-1.spc"), "d67562e4b4") + expect_known_hash(read.spc("fileio/spc.LabRam/LabRam-2.spc"), "c87094210a") }) - test_that ("Shimadzu spc files do not yet work", { + test_that("Shimadzu spc files do not yet work", { skip_if_not_fileio_available() - expect_error (read.spc("fileio/spc.Shimadzu/F80A20-1.SPC")) - + expect_error(read.spc("fileio/spc.Shimadzu/F80A20-1.SPC")) + fname <- "fileio/spc.Shimadzu/UV-2600_labeled_DNA" # TODO #102 - implement support for Shimadzu files SHIMADZU_SPC_IMPLEMENTED <- F - if (SHIMADZU_SPC_IMPLEMENTED){ + if (SHIMADZU_SPC_IMPLEMENTED) { # Compare data from SPC file and from CSV file. They should be equal - spc <- read.spc( paste0(fname, ".spc")) - expected <- read.txt.long(paste0(fname, '.csv'), sep=',') + spc <- read.spc(paste0(fname, ".spc")) + expected <- read.txt.long(paste0(fname, ".csv"), sep = ",") expect_true(all.equal(spc$spc, expected$spc)) - }else{ + } else { # IF NOT IMPLEMENTED - #expect_error (read.spc("fileio/spc.Shimadzu/F80A20-1.SPC"), regexp = 'Shimadzu SPC') - expect_error (read.spc(paste0(fname, ".spc")), - regexp = 'Support for Shimadzu SPC file format (OLE CF) is not yet implemented', - fixed = T) + # expect_error (read.spc("fileio/spc.Shimadzu/F80A20-1.SPC"), regexp = 'Shimadzu SPC') + expect_error(read.spc(paste0(fname, ".spc")), + regexp = "Support for Shimadzu SPC file format (OLE CF) is not yet implemented", + fixed = T + ) } }) - - + + test_that("Witec: some files supported", { skip_if_not_fileio_available() - - expect_error (read.spc("fileio/spc.Witec/P_A32_006_Spec.Data 1.spc")) - expect_error (read.spc("fileio/spc.Witec/P_A32_007_Spec.Data 1.spc")) + + expect_error(read.spc("fileio/spc.Witec/P_A32_006_Spec.Data 1.spc")) + expect_error(read.spc("fileio/spc.Witec/P_A32_007_Spec.Data 1.spc")) tmp <- read.spc("fileio/spc.Witec/Witec-Map.spc") - expect_known_hash (tmp, "d737a0a777") + expect_known_hash(tmp, "d737a0a777") ## no spatial information expect_null(tmp$x) expect_null(tmp$y) ## spectra numbered in z tmp <- read.spc("fileio/spc.Witec/Witec-timeseries.spc") - expect_known_hash (tmp, "d6879317f2") + expect_known_hash(tmp, "d6879317f2") }) ## Kaiser spc files tested mostly in Kaiser-specific read.spc.Kaiser* unit tests - test_that("wplanes",{ + test_that("wplanes", { skip_if_not_fileio_available() - skip ("wplanes do not yet work") + skip("wplanes do not yet work") # wplanes }) @@ -845,82 +944,92 @@ read.spc <- function (filename, file.keep.name <- hy.getOption("file.keep.name") hy.setOptions(file.keep.name = FALSE) - expect_null (read.spc("fileio/spc.LabRam/LabRam-2.spc")$filename) + expect_null(read.spc("fileio/spc.LabRam/LabRam-2.spc")$filename) hy.setOptions(file.keep.name = TRUE) - expect_equal (read.spc("fileio/spc.LabRam/LabRam-2.spc")$filename, "fileio/spc.LabRam/LabRam-2.spc") + expect_equal(read.spc("fileio/spc.LabRam/LabRam-2.spc")$filename, "fileio/spc.LabRam/LabRam-2.spc") hy.setOptions(file.keep.name = file.keep.name) }) test_that("option file.remove.emptyspc", { - skip ("no spc files with empty spectra available so far") - skip_if_not_fileio_available() + skip("no spc files with empty spectra available so far") + skip_if_not_fileio_available() file.remove.emptyspc <- hy.getOption("file.remove.emptyspc") hy.setOptions(file.remove.emptyspc = FALSE) - expect_equal (nrow (read.spc("")), NA) + expect_equal(nrow(read.spc("")), NA) hy.setOptions(file.remove.emptyspc = TRUE) - expect_equal (nrow (read.spc("")), NA) + expect_equal(nrow(read.spc("")), NA) hy.setOptions(file.keep.name = file.remove.emptyspc) }) - test_that ("hdr2data", { + test_that("hdr2data", { skip_if_not_fileio_available() - expect_equal (colnames (read.spc("fileio/spc.LabRam/LabRam-2.spc", keys.hdr2data = TRUE)), - c("z", "z.end", "ftflgs", "fexper", "fexp", "fnpts", "ffirst", - "flast", "fnsub", "fxtype", "fytype", "fztype", "fpost", "fdate", - "fres", "fsource", "fspare", "fcmnt", "fcatxt", "flogoff", "fmods", - "fprocs", "flevel", "fsampin", "ffactor", "fmethod", "fzinc", - "fwplanes", "fwinc", "fwtype", ".last.read", "subfiledir", "spc", - "filename") + expect_equal( + colnames(read.spc("fileio/spc.LabRam/LabRam-2.spc", keys.hdr2data = TRUE)), + c( + "z", "z.end", "ftflgs", "fexper", "fexp", "fnpts", "ffirst", + "flast", "fnsub", "fxtype", "fytype", "fztype", "fpost", "fdate", + "fres", "fsource", "fspare", "fcmnt", "fcatxt", "flogoff", "fmods", + "fprocs", "flevel", "fsampin", "ffactor", "fmethod", "fzinc", + "fwplanes", "fwinc", "fwtype", ".last.read", "subfiledir", "spc", + "filename" + ) ) }) - test_that ("log2data", { + test_that("log2data", { skip_if_not_fileio_available() - expect_equal(colnames (read.spc ("fileio/spc.Kaisermap/ebroAVII.spc", keys.log2data = TRUE)), - c("z", "z.end", "Grams_File_Name", "HoloGRAMS_File_Name", "Acquisition_Date_Time", - "Lambda", "Accuracy_Mode", "Dark_subtracted", "Dark_File_Name", - "Auto_New_Dark_Curve", "Background_subtracted", "Background_File_Name", - "Intensity_Corrected", "Intensity_Calibration_Available", "Intensity_Correction_File", - "Intensity_Correction_Threshold", "Intensity_Source_Correction", - "Intensity_Source_Correction_File", "Comment", "Cosmic_Ray_Filtering", - "Total_Cosmic_Count", "Exposure_Length", "Accumulations", "Accumulation_Method", - "Calibration_File", "Comment.1", "Temperature_Status", "Temperature", - "HoloGRAMS_File_Version", "File_Type", "Operator", "Stage_X_Position", - "Stage_Y_Position", "Stage_Z_Position", "AutoFocusUsed", "WLInterval", - "CalInterval", "FFTFillFactor", "FFTApT", "SamplingMethod", "Has_MultiPlex_Laser", - "External_Trigger", "Laser_Wavelength", "Default_Laser_Wavelength", - "Laser_Tracking", "Laser_Block_Active", "Pixel_Fill_minimum", - "Pixel_Fill_maximum", "Binning_Start", "Binning_End", "NumPoints", - "First", "last", "spc", "filename")) + expect_equal( + colnames(read.spc("fileio/spc.Kaisermap/ebroAVII.spc", keys.log2data = TRUE)), + c( + "z", "z.end", "Grams_File_Name", "HoloGRAMS_File_Name", "Acquisition_Date_Time", + "Lambda", "Accuracy_Mode", "Dark_subtracted", "Dark_File_Name", + "Auto_New_Dark_Curve", "Background_subtracted", "Background_File_Name", + "Intensity_Corrected", "Intensity_Calibration_Available", "Intensity_Correction_File", + "Intensity_Correction_Threshold", "Intensity_Source_Correction", + "Intensity_Source_Correction_File", "Comment", "Cosmic_Ray_Filtering", + "Total_Cosmic_Count", "Exposure_Length", "Accumulations", "Accumulation_Method", + "Calibration_File", "Comment.1", "Temperature_Status", "Temperature", + "HoloGRAMS_File_Version", "File_Type", "Operator", "Stage_X_Position", + "Stage_Y_Position", "Stage_Z_Position", "AutoFocusUsed", "WLInterval", + "CalInterval", "FFTFillFactor", "FFTApT", "SamplingMethod", "Has_MultiPlex_Laser", + "External_Trigger", "Laser_Wavelength", "Default_Laser_Wavelength", + "Laser_Tracking", "Laser_Block_Active", "Pixel_Fill_minimum", + "Pixel_Fill_maximum", "Binning_Start", "Binning_End", "NumPoints", + "First", "last", "spc", "filename" + ) + ) }) } -.prepare.hdr.df <- function (data, nsubfiles){ +.prepare.hdr.df <- function(data, nsubfiles) { ## the *type header elements are expressions. They need to be converted to character. - data <- lapply (data, function (x) { - if (mode (x) == "expression") - as.character (x) - else + data <- lapply(data, function(x) { + if (mode(x) == "expression") { + as.character(x) + } else { x + } }) ## convert vectors to matrix, otherwise the data.frame will contain one row per element. ## matrices need to be protected during as.data.frame - vector.entries <- which (sapply (data, length) > 1L) - for (v in vector.entries) - data [[v]] <- I (t (as.matrix (data [[v]]))) + vector.entries <- which(sapply(data, length) > 1L) + for (v in vector.entries) { + data [[v]] <- I(t(as.matrix(data [[v]]))) + } - data <- as.data.frame (data, stringsAsFactors = FALSE) - data <- data [rep (1L, nsubfiles), ] + data <- as.data.frame(data, stringsAsFactors = FALSE) + data <- data [rep(1L, nsubfiles), ] - for (v in vector.entries) - data [[v]] <- unclass (data [[v]]) # remove AsIs protection + for (v in vector.entries) { + data [[v]] <- unclass(data [[v]]) + } # remove AsIs protection data } diff --git a/hyperSpec/R/read.spc.Shimadzu.R b/hyperSpec/R/read.spc.Shimadzu.R index d221aed08..21bbc490e 100644 --- a/hyperSpec/R/read.spc.Shimadzu.R +++ b/hyperSpec/R/read.spc.Shimadzu.R @@ -1,12 +1,11 @@ read.spc.Shimadzu <- function(filename) { - stop ("Import of Shimadzu SPC file format (OLE CF) is not yet implemented.") + stop("Import of Shimadzu SPC file format (OLE CF) is not yet implemented.") } -.test (read.spc.Shimadzu) <- function (){ - context ("read.spc.Shimadzu") +.test(read.spc.Shimadzu) <- function() { + context("read.spc.Shimadzu") test_that("not implemented error", { expect_error(read.spc.Shimadzu()) }) - -} \ No newline at end of file +} diff --git a/hyperSpec/R/read.spe.R b/hyperSpec/R/read.spe.R index d2e3625e7..e4ce1a50e 100644 --- a/hyperSpec/R/read.spe.R +++ b/hyperSpec/R/read.spe.R @@ -36,63 +36,70 @@ ##' ##' @author R. Kiselev, C. Beleites ##' @export -read.spe <- function(filename, xaxis="file", acc2avg=F, cts_sec=F, - keys.hdr2data=c("exposure_sec", - "LaserWavelen", - "accumulCount", - "numFrames", - "darkSubtracted")){ - +read.spe <- function(filename, xaxis = "file", acc2avg = F, cts_sec = F, + keys.hdr2data = c( + "exposure_sec", + "LaserWavelen", + "accumulCount", + "numFrames", + "darkSubtracted" + )) { hdr <- .read.spe.header(filename) # This is the size of one data point in bytes. WinSpec uses 2 bytes or 4 bytes only data_size <- ifelse(hdr$datatype > 2, 2L, 4L) data_chunk_size <- hdr$xdim * hdr$ydim * hdr$numFrames * data_size - + # Read the part of file that contains actual experimental data - raw.data <- readBin(filename, "raw", data_chunk_size + 4100, 1)[- (1:4100)] + raw.data <- readBin(filename, "raw", data_chunk_size + 4100, 1)[-(1:4100)] # Convert raw spectral data according to the datatype defined in the header spc <- switch(hdr$datatype + 1, - readBin(raw.data, "double", length(raw.data)/4, 4), # float - readBin(raw.data, "integer", length(raw.data)/4, 4, signed=TRUE), # long - readBin(raw.data, "integer", length(raw.data)/2, 2, signed=TRUE), # int - readBin(raw.data, "integer", length(raw.data)/2, 2, signed=FALSE) # uint + readBin(raw.data, "double", length(raw.data) / 4, 4), # float + readBin(raw.data, "integer", length(raw.data) / 4, 4, signed = TRUE), # long + readBin(raw.data, "integer", length(raw.data) / 2, 2, signed = TRUE), # int + readBin(raw.data, "integer", length(raw.data) / 2, 2, signed = FALSE) # uint ) - + # Create a structured data.frame that accomodates spectral data dim(spc) <- c(hdr$xdim, hdr$ydim * hdr$numFrames) - extra_data <- data.frame ( - px.y = rep(seq_len(hdr$ydim), hdr$numFrames), - frame = rep(seq_len(hdr$numFrames), each=hdr$ydim) + extra_data <- data.frame( + px.y = rep(seq_len(hdr$ydim), hdr$numFrames), + frame = rep(seq_len(hdr$numFrames), each = hdr$ydim) ) # Extract selected items from the header. They will go to a new hyperSpec object hdr2data <- hdr[keys.hdr2data] - if (length (hdr2data > 0)) - extra_data <- cbind (extra_data, hdr2data) + if (length(hdr2data > 0)) { + extra_data <- cbind(extra_data, hdr2data) + } # Create hyperSpec object - spc <- new("hyperSpec", spc=t(spc), data=extra_data, - labels = list (spc = "counts", .wavelength = "pixel number")) + spc <- new("hyperSpec", + spc = t(spc), data = extra_data, + labels = list(spc = "counts", .wavelength = "pixel number") + ) # For SPE 3.0 and above we need to read the XML header - if (hdr$fileFormatVer >= 3.0){ + if (hdr$fileFormatVer >= 3.0) { spc@data$xml <- .read.spe.xml(filename) } # Check if we should use display units specified in the SPE file - if (xaxis == "file") - xaxis = .fixunitname(hdr$xCalDisplayUnit) + if (xaxis == "file") { + xaxis <- .fixunitname(hdr$xCalDisplayUnit) + } # Create a new x-axis, if required xaxis <- .fixunitname(xaxis) - if (xaxis == "px") + if (xaxis == "px") { return(.fileio.optional(spc, filename)) + } - if (! hdr$xCalValid) + if (!hdr$xCalValid) { warning("The calibration is NOT valid") + } # Recreate calibration function polyorder <- hdr$xCalPolyOrder @@ -101,36 +108,40 @@ read.spe <- function(filename, xaxis="file", acc2avg=F, cts_sec=F, vM <- vanderMonde(spc@wavelength, polyorder) # Check if we have laser wavelength - if (hdr$LaserWavelen < 10) + if (hdr$LaserWavelen < 10) { hdr$LaserWavelen <- NULL + } # Perform convertion - spc@wavelength <- wlconv(src=.fixunitname(hdr$xCalPolyUnit), - dst=xaxis, - points=as.numeric(vM %*% coeffs), - laser=hdr$LaserWavelen) - - spc@label$.wavelength = switch(xaxis, - nm=expression("Wavelength, nm"), - invcm=expression(tilde(nu) / cm^-1), - ev=expression("Energy / eV"), - freq=expression(nu / THz), - raman=expression(Raman~shift / cm^-1)) - if (acc2avg){ + spc@wavelength <- wlconv( + src = .fixunitname(hdr$xCalPolyUnit), + dst = xaxis, + points = as.numeric(vM %*% coeffs), + laser = hdr$LaserWavelen + ) + + spc@label$.wavelength <- switch(xaxis, + nm = expression("Wavelength, nm"), + invcm = expression(tilde(nu) / cm^-1), + ev = expression("Energy / eV"), + freq = expression(nu / THz), + raman = expression(Raman ~ shift / cm^-1) + ) + if (acc2avg) { spc <- spc / hdr$accumulCount spc@data$averaged <- T } - if (cts_sec){ + if (cts_sec) { spc <- spc / hdr$exposure_sec spc@label$spc <- expression("counts / s") } ## consistent file import behaviour across import functions - .fileio.optional (spc, filename) + .fileio.optional(spc, filename) } #' Read XML footer from SPE file format version 3.0 -#' +#' #' The new SPE file format, introduced in 2012, was designed to be backwards compatible with the #' previous format 2.5. The most prominent change is the new plain text XML footer holding vast #' experimental metadata that gets attached at the end of the file. Thus, the file contains 3 @@ -138,20 +149,20 @@ read.spe <- function(filename, xaxis="file", acc2avg=F, cts_sec=F, #' This function retrieves the XML footer converted to R list, and throws error if it is not available. #' The file format specification is available at Princeton Instruments FTP server under name #' 'SPE 3.0 File Format Specification'. -#' +#' #' This function relies on R package xml2 to work correctly #' #' @param filename - SPE filename #' #' @return xml data from the file converted to R list #' @importFrom xml2 as_list read_xml -.read.spe.xml <- function(filename){ +.read.spe.xml <- function(filename) { as_list(read_xml(.read.spe.xml_string(filename))) } #' .read.spe.xml_string -#' +#' #' Read XML footer from SPE file format version 3.0 and return it as a long string #' for subsequent parsing. Basically the purpose of this function is to check #' that the file format version is 3.0 or above, and to find and read the @@ -160,20 +171,22 @@ read.spe <- function(filename, xaxis="file", acc2avg=F, cts_sec=F, #' @param filename - SPE filename #' #' @return string containing XML footer -.read.spe.xml_string <- function(filename){ +.read.spe.xml_string <- function(filename) { hdr <- .read.spe.header(filename) - - if (hdr$fileFormatVer < 3.0){ - stop(paste("This SPE file contains no XML data: file format version", - round(hdr$fileFormatVer, digits = 3), "< 3.0")) + + if (hdr$fileFormatVer < 3.0) { + stop(paste( + "This SPE file contains no XML data: file format version", + round(hdr$fileFormatVer, digits = 3), "< 3.0" + )) return() } - + data_size <- ifelse(hdr$datatype > 2, 2L, 4L) data_chunk_size <- hdr$xdim * hdr$ydim * hdr$numFrames * data_size - + # Read the part of file that contains actual experimental data - raw_bytes <- readBin(filename, "raw", file.info(filename)$size, 1)[- (1:(4100+data_chunk_size))] + raw_bytes <- readBin(filename, "raw", file.info(filename)$size, 1)[-(1:(4100 + data_chunk_size))] readChar(raw_bytes, length(raw_bytes)) } @@ -181,70 +194,70 @@ read.spe <- function(filename, xaxis="file", acc2avg=F, cts_sec=F, ##' @describeIn read.spe Read only header of a WinSpec SPE file (version 2.5) ##' @return hdr list with \code{key=value} pairs -.read.spe.header <- function(filename){ +.read.spe.header <- function(filename) { # Read the 4100-byte long binary header from the SPE file and parse it # Load the header raw.data <- readBin(filename, "raw", 4100, 1) # Extract some items from the 4100 bytes-long file header - hdr <- list ( - hwVersion = readBin(raw.data[1 :2 ], "integer", 1, 2, signed=TRUE ), # uint16 - xDimDet = readBin(raw.data[7 :8 ], "integer", 1, 2, signed=FALSE), # uint16 - mode = readBin(raw.data[9 :10 ], "integer", 1, 2, signed=TRUE ), # uint16 - exposure_sec = readBin(raw.data[11 :14 ], "double", 1, 4), # float32 - vChipXDim = readBin(raw.data[15 :16 ], "integer", 1, 2, signed=TRUE ), # int8 - vChipYDim = readBin(raw.data[17 :18 ], "integer", 1, 2, signed=TRUE ), # int8 - yDimDet = readBin(raw.data[19 :20 ], "integer", 1, 2, signed=FALSE), # uint16 - date = readBin(raw.data[21 :30 ], "character", 1, 10 ), # char - detTemperature = readBin(raw.data[37 :40 ], "double", 1, 4), # float32 - xdim = readBin(raw.data[43 :44 ], "integer", 1, 2, signed=FALSE), # uint16 - shutterMode = readBin(raw.data[51 :52 ], "integer", 1, 2, signed=FALSE), # uint16 - specCenterWlNm = readBin(raw.data[73 :76 ], "double", 1, 4), # float32 - datatype = readBin(raw.data[109 :110 ], "integer", 1, 2, signed=TRUE ), # int8 - darkSubtracted = readBin(raw.data[151 :152 ], "integer", 1, 2, signed=FALSE), # int8 - timeLocal = readBin(raw.data[173 :179 ], "character", 1, 7 ), # char - timeUTC = readBin(raw.data[180 :186 ], "character", 1, 7 ), # char - gain = readBin(raw.data[199 :200 ], "integer", 1, 2, signed=FALSE), # uint16 - comments = readBin(raw.data[201 :600 ], "character", 1, 400 ), # char - ydim = readBin(raw.data[657 :658 ], "integer", 1, 2, signed=FALSE), # uint16 - accumulCount = readBin(raw.data[669 :672 ], "integer", 1, 4), # uint32 - readoutTime = readBin(raw.data[673 :676 ], "double", 1, 4), # float32 - swVersion = readBin(raw.data[688 :704 ], "character", 1, 16 ), # char - kinTrigMode = readBin(raw.data[725 :726 ], "integer", 1, 2, signed=TRUE ), # int16 - expRepeatCount = readBin(raw.data[1419:1422], "integer", 1, 4, signed=TRUE ), # int32 - expAccumCount = readBin(raw.data[1423:1426], "integer", 1, 4, signed=TRUE ), # int32 - hwAccumFlag = readBin(raw.data[1433:1434], "integer", 1, 2, signed=TRUE ), # int16 - cosmicApplied = readBin(raw.data[1439:1440], "integer", 1, 2, signed=TRUE ), # int16 - cosmicType = readBin(raw.data[1441:1442], "integer", 1, 2, signed=TRUE ), # int16 - numFrames = readBin(raw.data[1447:1450], "integer", 1, 4), # int32 - shutterType = readBin(raw.data[1475:1476], "integer", 1, 2, signed=TRUE ), # int16 - readoutMode = readBin(raw.data[1481:1482], "integer", 1, 2, signed=TRUE ), # int16 - kinWindowSize = readBin(raw.data[1483:1484], "integer", 1, 2, signed=TRUE ), # int16 - clkSpeed = readBin(raw.data[1485:1486], "integer", 1, 2, signed=TRUE ), # int16 - computerIface = readBin(raw.data[1487:1488], "integer", 1, 2, signed=TRUE ), # int16 - fileFormatVer = readBin(raw.data[1993:1996], "double", 1, 4, signed=TRUE ), # float32 - + hdr <- list( + hwVersion = readBin(raw.data[1:2], "integer", 1, 2, signed = TRUE), # uint16 + xDimDet = readBin(raw.data[7:8], "integer", 1, 2, signed = FALSE), # uint16 + mode = readBin(raw.data[9:10], "integer", 1, 2, signed = TRUE), # uint16 + exposure_sec = readBin(raw.data[11:14], "double", 1, 4), # float32 + vChipXDim = readBin(raw.data[15:16], "integer", 1, 2, signed = TRUE), # int8 + vChipYDim = readBin(raw.data[17:18], "integer", 1, 2, signed = TRUE), # int8 + yDimDet = readBin(raw.data[19:20], "integer", 1, 2, signed = FALSE), # uint16 + date = readBin(raw.data[21:30], "character", 1, 10), # char + detTemperature = readBin(raw.data[37:40], "double", 1, 4), # float32 + xdim = readBin(raw.data[43:44], "integer", 1, 2, signed = FALSE), # uint16 + shutterMode = readBin(raw.data[51:52], "integer", 1, 2, signed = FALSE), # uint16 + specCenterWlNm = readBin(raw.data[73:76], "double", 1, 4), # float32 + datatype = readBin(raw.data[109:110], "integer", 1, 2, signed = TRUE), # int8 + darkSubtracted = readBin(raw.data[151:152], "integer", 1, 2, signed = FALSE), # int8 + timeLocal = readBin(raw.data[173:179], "character", 1, 7), # char + timeUTC = readBin(raw.data[180:186], "character", 1, 7), # char + gain = readBin(raw.data[199:200], "integer", 1, 2, signed = FALSE), # uint16 + comments = readBin(raw.data[201:600], "character", 1, 400), # char + ydim = readBin(raw.data[657:658], "integer", 1, 2, signed = FALSE), # uint16 + accumulCount = readBin(raw.data[669:672], "integer", 1, 4), # uint32 + readoutTime = readBin(raw.data[673:676], "double", 1, 4), # float32 + swVersion = readBin(raw.data[688:704], "character", 1, 16), # char + kinTrigMode = readBin(raw.data[725:726], "integer", 1, 2, signed = TRUE), # int16 + expRepeatCount = readBin(raw.data[1419:1422], "integer", 1, 4, signed = TRUE), # int32 + expAccumCount = readBin(raw.data[1423:1426], "integer", 1, 4, signed = TRUE), # int32 + hwAccumFlag = readBin(raw.data[1433:1434], "integer", 1, 2, signed = TRUE), # int16 + cosmicApplied = readBin(raw.data[1439:1440], "integer", 1, 2, signed = TRUE), # int16 + cosmicType = readBin(raw.data[1441:1442], "integer", 1, 2, signed = TRUE), # int16 + numFrames = readBin(raw.data[1447:1450], "integer", 1, 4), # int32 + shutterType = readBin(raw.data[1475:1476], "integer", 1, 2, signed = TRUE), # int16 + readoutMode = readBin(raw.data[1481:1482], "integer", 1, 2, signed = TRUE), # int16 + kinWindowSize = readBin(raw.data[1483:1484], "integer", 1, 2, signed = TRUE), # int16 + clkSpeed = readBin(raw.data[1485:1486], "integer", 1, 2, signed = TRUE), # int16 + computerIface = readBin(raw.data[1487:1488], "integer", 1, 2, signed = TRUE), # int16 + fileFormatVer = readBin(raw.data[1993:1996], "double", 1, 4, signed = TRUE), # float32 + # X Calibration Structure - xCalOffset = readBin(raw.data[3001:3008], "double", 1, 8, signed=TRUE ), # float64 - xCalFactor = readBin(raw.data[3009:3016], "double", 1, 8, signed=TRUE ), # float64 - xCalDisplayUnit= readBin(raw.data[3017 ], "integer", 1, 1, signed=FALSE), # uint8 - xCalValid = readBin(raw.data[3099 ], "integer", 1, 1, signed=FALSE), # uint8 - xCalInputUnit = readBin(raw.data[3100 ], "integer", 1, 1, signed=FALSE), # uint8 - xCalPolyUnit = readBin(raw.data[3101 ], "integer", 1, 1, signed=FALSE), # uint8 - xCalPolyOrder = readBin(raw.data[3102 ], "integer", 1, 1, signed=FALSE), # uint8 - xCalPointCount = readBin(raw.data[3103 ], "integer", 1, 1, signed=FALSE), # uint8 - xCalPxPos = readBin(raw.data[3104:3183], "double", 10, 8, signed=TRUE ), # float64 - xCalValues = readBin(raw.data[3184:3263], "double", 10, 8, signed=TRUE ), # float64 - xCalPolCoeffs = readBin(raw.data[3264:3311], "double", 6, 8, signed=TRUE ), # float64 - LaserWavelen = readBin(raw.data[3312:3319], "double", 1, 8, signed=TRUE ) # float64 + xCalOffset = readBin(raw.data[3001:3008], "double", 1, 8, signed = TRUE), # float64 + xCalFactor = readBin(raw.data[3009:3016], "double", 1, 8, signed = TRUE), # float64 + xCalDisplayUnit = readBin(raw.data[3017], "integer", 1, 1, signed = FALSE), # uint8 + xCalValid = readBin(raw.data[3099], "integer", 1, 1, signed = FALSE), # uint8 + xCalInputUnit = readBin(raw.data[3100], "integer", 1, 1, signed = FALSE), # uint8 + xCalPolyUnit = readBin(raw.data[3101], "integer", 1, 1, signed = FALSE), # uint8 + xCalPolyOrder = readBin(raw.data[3102], "integer", 1, 1, signed = FALSE), # uint8 + xCalPointCount = readBin(raw.data[3103], "integer", 1, 1, signed = FALSE), # uint8 + xCalPxPos = readBin(raw.data[3104:3183], "double", 10, 8, signed = TRUE), # float64 + xCalValues = readBin(raw.data[3184:3263], "double", 10, 8, signed = TRUE), # float64 + xCalPolCoeffs = readBin(raw.data[3264:3311], "double", 6, 8, signed = TRUE), # float64 + LaserWavelen = readBin(raw.data[3312:3319], "double", 1, 8, signed = TRUE) # float64 ) # Convert magic numbers into human-readable unit strings - spe_units <- c("pixel", "pixel", "data", "user units", "nm", "cm-1", "Raman shift") + spe_units <- c("pixel", "pixel", "data", "user units", "nm", "cm-1", "Raman shift") hdr$xCalDisplayUnit <- spe_units[hdr$xCalDisplayUnit + 1] - hdr$xCalInputUnit <- spe_units[hdr$xCalInputUnit + 1] - hdr$xCalPolyUnit <- spe_units[hdr$xCalPolyUnit + 1] + hdr$xCalInputUnit <- spe_units[hdr$xCalInputUnit + 1] + hdr$xCalPolyUnit <- spe_units[hdr$xCalPolyUnit + 1] return(hdr) } @@ -253,56 +266,59 @@ read.spe <- function(filename, xaxis="file", acc2avg=F, cts_sec=F, ##' @describeIn read.spe Plot the WinSpec SPE file (version 2.5) and show the ##' calibration points stored inside of it (x-axis calibration) ##' @export -spe.showcalpoints <- function(filename, xaxis="file", acc2avg=F, cts_sec=F){ - +spe.showcalpoints <- function(filename, xaxis = "file", acc2avg = F, cts_sec = F) { hdr <- .read.spe.header(filename) xaxis <- .fixunitname(xaxis) # Check if we should use display units specified in the SPE file - if (xaxis == "file") + if (xaxis == "file") { xaxis <- .fixunitname(hdr$xCalDisplayUnit) - if (xaxis == "px"){ + } + if (xaxis == "px") { xaxis <- hdr$xCalPolyUnit warning("Cannot show calibration data in pixels") - } + } # Open file, make plot and mark position of all peaks stored inside the file # in the x-calibration structure spc <- read.spe(filename, xaxis, acc2avg, cts_sec) rng <- max(spc) - min(spc) - ylims <- c(min(spc), max(spc) + 0.3*rng) - if (dim(spc@data$spc)[1] > 1) - plot(spc, plot.args=list(ylim=(ylims)), "spcprctl5") - else - plot(spc, plot.args=list(ylim=(ylims))) + ylims <- c(min(spc), max(spc) + 0.3 * rng) + if (dim(spc@data$spc)[1] > 1) { + plot(spc, plot.args = list(ylim = (ylims)), "spcprctl5") + } else { + plot(spc, plot.args = list(ylim = (ylims))) + } title(basename(filename)) - if (hdr$xCalPointCount == 0){ + if (hdr$xCalPointCount == 0) { warning("No calibration data! Nothing to show") return("") } - markpeak(spc, wlconv(src=hdr$xCalInputUnit, - dst=.fixunitname(xaxis), - points=hdr$xCalValues, - laser=hdr$LaserWavelen)) + markpeak(spc, wlconv( + src = hdr$xCalInputUnit, + dst = .fixunitname(xaxis), + points = hdr$xCalValues, + laser = hdr$LaserWavelen + )) } ############# UNIT TESTS ################ -.test (read.spe) <- function (){ +.test(read.spe) <- function() { # Filenames polystyrene <- "fileio/spe/polystyrene.SPE" - blut1 <- "fileio/spe/blut1.SPE" - spe3 <- "fileio/spe/spe_format_3.0.SPE" + blut1 <- "fileio/spe/blut1.SPE" + spe3 <- "fileio/spe/spe_format_3.0.SPE" # unit tests for `read.spe` itself ################################## test_that("read.spe correctly extracts spectral data from SPE file", { - skip_if_not_fileio_available () + skip_if_not_fileio_available() fname <- blut1 expect_true(file.exists(fname)) spc <- read.spe(fname) @@ -312,21 +328,21 @@ spe.showcalpoints <- function(filename, xaxis="file", acc2avg=F, cts_sec=F){ expect_equal(spc$spc[[5, 77]], 1484) expect_equal(spc$spc[[2, 811]], 606) expect_equal(spc@wavelength[621], 2618.027) - }) + }) test_that("read.spe detects an XML footer in SPE 3.0 file", { - skip_if_not_fileio_available () + skip_if_not_fileio_available() fname <- spe3 expect_true(file.exists(fname)) spc <- read.spe(fname) - expect_true('xml' %in% names(spc@data)) + expect_true("xml" %in% names(spc@data)) }) test_that("read.spe correctly parses XML footer with SPE 3.0 file and saves metadata in hyperSpec object", { - skip_if_not_fileio_available () + skip_if_not_fileio_available() fname <- spe3 expect_true(file.exists(fname)) spc <- read.spe(fname) @@ -337,17 +353,17 @@ spe.showcalpoints <- function(filename, xaxis="file", acc2avg=F, cts_sec=F){ # unit tests for helper functions of `read.spe` (whose name starts with .) ########################################################################## - test_that (".read.spe.xml_string throws error on SPE format below v3.0", { - skip_if_not_fileio_available () + test_that(".read.spe.xml_string throws error on SPE format below v3.0", { + skip_if_not_fileio_available() fname <- blut1 expect_true(file.exists(fname)) - expect_error(.read.spe.xml_string(fname), regexp = '*no XML*') + expect_error(.read.spe.xml_string(fname), regexp = "*no XML*") }) - test_that ("We can correctly read XML footer from SPE3.0 file", { - skip_if_not_fileio_available () + test_that("We can correctly read XML footer from SPE3.0 file", { + skip_if_not_fileio_available() expect_true(file.exists(spe3)) xml_file <- paste0(spe3, "_metadata.xml") @@ -357,8 +373,8 @@ spe.showcalpoints <- function(filename, xaxis="file", acc2avg=F, cts_sec=F){ }) - test_that (".read.spe.xml correctly parses the XML footer and can extract the actual data", { - skip_if_not_fileio_available () + test_that(".read.spe.xml correctly parses the XML footer and can extract the actual data", { + skip_if_not_fileio_available() expect_true(file.exists(spe3)) # Read XML footer and convert it to R list @@ -367,22 +383,22 @@ spe.showcalpoints <- function(filename, xaxis="file", acc2avg=F, cts_sec=F){ # Check values of some elements expect_true(is.list(x)) - expect_true('SpeFormat' %in% names(x)) + expect_true("SpeFormat" %in% names(x)) # Check file format version and namespace URL - expect_equal(attr(x$SpeFormat, 'version'), "3.0") - expect_equal(attr(x$SpeFormat, 'xmlns'), "http://www.princetoninstruments.com/spe/2009") - + expect_equal(attr(x$SpeFormat, "version"), "3.0") + expect_equal(attr(x$SpeFormat, "xmlns"), "http://www.princetoninstruments.com/spe/2009") + # Check that some children are present - expect_true('DataFormat' %in% names(x$SpeFormat)) - expect_true('Calibrations' %in% names(x$SpeFormat)) - expect_true('DataHistories' %in% names(x$SpeFormat)) - expect_true('GeneralInformation' %in% names(x$SpeFormat)) + expect_true("DataFormat" %in% names(x$SpeFormat)) + expect_true("Calibrations" %in% names(x$SpeFormat)) + expect_true("DataHistories" %in% names(x$SpeFormat)) + expect_true("GeneralInformation" %in% names(x$SpeFormat)) # Check that we can correctly extract file creation date info <- x$SpeFormat$GeneralInformation$FileInformation - expect_equal(attr(info, 'created'), "2018-01-26T16:31:09.0979397+01:00") - + expect_equal(attr(info, "created"), "2018-01-26T16:31:09.0979397+01:00") + # Check that we can correctly extract pixel format and laser line expect_equal(attr(x$SpeFormat$DataFormat$DataBlock, "pixelFormat"), "MonochromeFloating32") expect_equal(attr(x$SpeFormat$Calibrations$WavelengthMapping, "laserLine"), "785") diff --git a/hyperSpec/R/read.txt.Horiba.R b/hyperSpec/R/read.txt.Horiba.R index ee6e10b73..c06f15818 100644 --- a/hyperSpec/R/read.txt.Horiba.R +++ b/hyperSpec/R/read.txt.Horiba.R @@ -9,40 +9,50 @@ ##' @author C. Beleites ##' @return hyperSpec object ##' @export -read.txt.Horiba <- function (file, cols = c (spc = "I / a.u.", - .wavelength = expression (Delta*tilde(nu) / cm^-1)), - header = TRUE, sep = "\t", row.names = NULL, - check.names = FALSE, ...){ - spc <- read.txt.wide (file, cols = cols, - header = header, sep = sep, row.names = row.names, - check.names = check.names, ...) +read.txt.Horiba <- function(file, cols = c( + spc = "I / a.u.", + .wavelength = expression(Delta * tilde(nu) / cm^-1) + ), + header = TRUE, sep = "\t", row.names = NULL, + check.names = FALSE, ...) { + spc <- read.txt.wide(file, + cols = cols, + header = header, sep = sep, row.names = row.names, + check.names = check.names, ... + ) ## consistent file import behaviour across import functions ## is already provided by read.txt.wide - + spc } ##' @rdname read.txt.Horiba ##' @export -read.txt.Horiba.xy <- function (file, ...){ - read.txt.Horiba (file = file, - cols = c (x = expression (x / mu*m), - y = expression (y / mu*m), - spc = "I / a.u.", - .wavelength = expression (Delta*tilde(nu) / cm^-1)), - ...) +read.txt.Horiba.xy <- function(file, ...) { + read.txt.Horiba( + file = file, + cols = c( + x = expression(x / mu * m), + y = expression(y / mu * m), + spc = "I / a.u.", + .wavelength = expression(Delta * tilde(nu) / cm^-1) + ), + ... + ) } ##' \code{read.txt.Horiba.t} reads time series, i.e. .txt files with the time in the first column ##' @rdname read.txt.Horiba ##' @export -read.txt.Horiba.t <- function (file, header = TRUE, sep = "\t", row.names = NULL, - check.names = FALSE, ...){ - read.txt.Horiba (file, - cols = c (t = "t / s", - spc = "I / a.u.", - .wavelength = expression (Delta*tilde(nu) / cm^-1)), - ...) +read.txt.Horiba.t <- function(file, header = TRUE, sep = "\t", row.names = NULL, + check.names = FALSE, ...) { + read.txt.Horiba(file, + cols = c( + t = "t / s", + spc = "I / a.u.", + .wavelength = expression(Delta * tilde(nu) / cm^-1) + ), + ... + ) } - diff --git a/hyperSpec/R/read.txt.Renishaw.R b/hyperSpec/R/read.txt.Renishaw.R index 12b169eab..aad1053e5 100644 --- a/hyperSpec/R/read.txt.Renishaw.R +++ b/hyperSpec/R/read.txt.Renishaw.R @@ -42,142 +42,160 @@ ##' \code{\link[base]{scan}} ##' @keywords IO file ##' @importFrom utils head -read.txt.Renishaw <- function (file = stop ("file is required"), - data = "xyspc", nlines = 0, nspc = NULL){ - cols <- switch (data, - spc = NULL, - xyspc = list (y = expression ("/" (y, mu * m)), - x = expression ("/" (x, mu * m))), - zspc = , - depth = list (z = expression ("/" (z, mu * m))), - ts = list (t = "t / s"), - stop ("unknown format for Renishaw .txt files.") - ) - cols <- c (cols, list (.wavelength = expression (Delta * tilde(nu) / cm^-1) , - spc = "I / a.u.")) - - if (!is (file, "connection")) - file <- gzfile (file, "r") +read.txt.Renishaw <- function(file = stop("file is required"), + data = "xyspc", nlines = 0, nspc = NULL) { + cols <- switch(data, + spc = NULL, + xyspc = list( + y = expression("/"(y, mu * m)), + x = expression("/"(x, mu * m)) + ), + zspc = , + depth = list(z = expression("/"(z, mu * m))), + ts = list(t = "t / s"), + stop("unknown format for Renishaw .txt files.") + ) + cols <- c(cols, list( + .wavelength = expression(Delta * tilde(nu) / cm^-1), + spc = "I / a.u." + )) + + if (!is(file, "connection")) { + file <- gzfile(file, "r") + } on.exit(close(file)) first <- scan(file, nlines = 1, quiet = TRUE) - ncol <- length (first) + ncol <- length(first) - if (ncol == 0) - return (new ("hyperSpec")) + if (ncol == 0) { + return(new("hyperSpec")) + } - if (ncol != length (cols)) - stop (paste ("File has", ncol, "columns, while 'cols' gives", length (cols))) + if (ncol != length(cols)) { + stop(paste("File has", ncol, "columns, while 'cols' gives", length(cols))) + } - fbuf <- matrix (c (first, scan (file, quiet = TRUE, nlines = nlines)), - ncol = ncol, byrow = TRUE) + fbuf <- matrix(c(first, scan(file, quiet = TRUE, nlines = nlines)), + ncol = ncol, byrow = TRUE + ) ## wavelength axis - wl <- rep (TRUE, nrow (fbuf)) - for (i in seq_len (ncol (fbuf) - 2)) + wl <- rep(TRUE, nrow(fbuf)) + for (i in seq_len(ncol(fbuf) - 2)) { wl [wl] <- fbuf [wl, i] == fbuf [1, i] + } wl <- fbuf[wl, ncol - 1] ## if the file is to be read in chunks ## try to find out how many lines it has - if (is.null (nspc)) - if (nlines > 0){ - nspc <- count_lines (summary(file)$description, nlines) - if (is.null (nspc)) - stop ("Failed guessing nspc.") - else { - message ("Counted ", nspc, " lines = ", nspc / length (wl), " spectra.") - nspc <- nspc / length (wl) + if (is.null(nspc)) { + if (nlines > 0) { + nspc <- count_lines(summary(file)$description, nlines) + if (is.null(nspc)) { + stop("Failed guessing nspc.") + } else { + message("Counted ", nspc, " lines = ", nspc / length(wl), " spectra.") + nspc <- nspc / length(wl) } } else { - nspc <- nrow (fbuf) / length (wl) + nspc <- nrow(fbuf) / length(wl) } + } - data <- matrix (NA, ncol = ncol - 2, nrow = nspc) - colnames (data) <- head (names (cols), -2) + data <- matrix(NA, ncol = ncol - 2, nrow = nspc) + colnames(data) <- head(names(cols), -2) pos.data <- 0 - spc <- numeric (nspc * length (wl)) + spc <- numeric(nspc * length(wl)) pos.spc <- 0 - while (length (fbuf > 0)){ - if (nlines > 0) cat (".") - spc [pos.spc + seq_len (nrow (fbuf))] <- fbuf [, ncol] - pos.spc <- pos.spc + nrow (fbuf) + while (length(fbuf > 0)) { + if (nlines > 0) cat(".") + spc [pos.spc + seq_len(nrow(fbuf))] <- fbuf [, ncol] + pos.spc <- pos.spc + nrow(fbuf) - tmp <- fbuf [fbuf[, ncol - 1] == wl [1], seq_len (ncol - 2), drop = FALSE] + tmp <- fbuf [fbuf[, ncol - 1] == wl [1], seq_len(ncol - 2), drop = FALSE] - data [pos.data + seq_len (nrow (tmp)), ] <- tmp - pos.data <- pos.data + nrow (tmp) + data [pos.data + seq_len(nrow(tmp)), ] <- tmp + pos.data <- pos.data + nrow(tmp) - fbuf <- matrix (scan (file, quiet = TRUE, nlines = nlines), ncol = ncol, - byrow = TRUE) + fbuf <- matrix(scan(file, quiet = TRUE, nlines = nlines), + ncol = ncol, + byrow = TRUE + ) - if (length (fbuf > 0) & ! all(unique (fbuf[, ncol - 1]) %in% wl)) - stop ("Wavelengths do not correspond to that of the other chunks. ", - "Is the size of the first chunk large enough to cover a complete ", - "spectrum?") + if (length(fbuf > 0) & !all(unique(fbuf[, ncol - 1]) %in% wl)) { + stop( + "Wavelengths do not correspond to that of the other chunks. ", + "Is the size of the first chunk large enough to cover a complete ", + "spectrum?" + ) + } } - if (nlines > 0) cat ("\n") + if (nlines > 0) cat("\n") - spc <- matrix (spc, ncol = length (wl), nrow = nspc, byrow = TRUE) + spc <- matrix(spc, ncol = length(wl), nrow = nspc, byrow = TRUE) - spc <- orderwl (new ("hyperSpec", spc = spc, data = as.data.frame (data), - wavelength = wl, label = cols)) + spc <- orderwl(new("hyperSpec", + spc = spc, data = as.data.frame(data), + wavelength = wl, label = cols + )) ## consistent file import behaviour across import functions - .fileio.optional (spc, file) + .fileio.optional(spc, file) } -.test (read.txt.Renishaw) <- function(){ +.test(read.txt.Renishaw) <- function() { context("read.txt.Renishaw") - + test_that("single spectrum", { - skip_if_not_fileio_available () - tmp <- read.txt.Renishaw ("fileio/txt.Renishaw/paracetamol.txt", "spc") - expect_equal(dim (tmp), c(nrow = 1L, ncol = 2L, nwl = 4064L)) + skip_if_not_fileio_available() + tmp <- read.txt.Renishaw("fileio/txt.Renishaw/paracetamol.txt", "spc") + expect_equal(dim(tmp), c(nrow = 1L, ncol = 2L, nwl = 4064L)) }) test_that("time series spectrum, gzipped", { - skip_if_not_fileio_available () - tmp <- read.txt.Renishaw ("fileio/txt.Renishaw/laser.txt.gz", "ts") - expect_equal(dim (tmp), c(nrow = 84L, ncol = 3L, nwl = 140L)) - expect_equal(colnames (tmp), c("t", "spc", "filename")) + skip_if_not_fileio_available() + tmp <- read.txt.Renishaw("fileio/txt.Renishaw/laser.txt.gz", "ts") + expect_equal(dim(tmp), c(nrow = 84L, ncol = 3L, nwl = 140L)) + expect_equal(colnames(tmp), c("t", "spc", "filename")) }) - + test_that("map (= default)", { - skip_if_not_fileio_available () - tmp <- read.txt.Renishaw ("fileio/txt.Renishaw/chondro.txt", "xyspc") - expect_equal(dim (tmp), c(nrow = 875L, ncol = 4L, nwl = 1272L)) - expect_equal(colnames (tmp), c("y", "x", "spc", "filename")) - - tmp <- read.txt.Renishaw ("fileio/txt.Renishaw/chondro.txt") - expect_equal(dim (tmp), c(nrow = 875L, ncol = 4L, nwl = 1272L)) - expect_equal(colnames (tmp), c("y", "x", "spc", "filename")) - + skip_if_not_fileio_available() + tmp <- read.txt.Renishaw("fileio/txt.Renishaw/chondro.txt", "xyspc") + expect_equal(dim(tmp), c(nrow = 875L, ncol = 4L, nwl = 1272L)) + expect_equal(colnames(tmp), c("y", "x", "spc", "filename")) + + tmp <- read.txt.Renishaw("fileio/txt.Renishaw/chondro.txt") + expect_equal(dim(tmp), c(nrow = 875L, ncol = 4L, nwl = 1272L)) + expect_equal(colnames(tmp), c("y", "x", "spc", "filename")) }) - + test_that("chunked reading", { - skip_if_not_fileio_available () - + skip_if_not_fileio_available() + ## error on too small chunk size - expect_error (read.txt.Renishaw ("fileio/txt.Renishaw/chondro.txt", nlines = 10), - "Wavelengths do not correspond") - - tmp <- read.txt.Renishaw ("fileio/txt.Renishaw/chondro.txt", nlines = 1e5) - expect_equal(dim (tmp), c(nrow = 875L, ncol = 4L, nwl = 1272L)) + expect_error( + read.txt.Renishaw("fileio/txt.Renishaw/chondro.txt", nlines = 10), + "Wavelengths do not correspond" + ) + + tmp <- read.txt.Renishaw("fileio/txt.Renishaw/chondro.txt", nlines = 1e5) + expect_equal(dim(tmp), c(nrow = 875L, ncol = 4L, nwl = 1272L)) }) - - test_that("compressed files",{ - skip_if_not_fileio_available () - + + test_that("compressed files", { + skip_if_not_fileio_available() + files <- Sys.glob("fileio/txt.Renishaw/chondro.*") - files <- grep ("[.]zip", files, invert = TRUE, value = TRUE) # .zip is tested with read.zip.Renishaw - for (f in files){ - expect_equal(dim (read.txt.Renishaw (!!f)), c(nrow = 875L, ncol = 4L, nwl = 1272L)) + files <- grep("[.]zip", files, invert = TRUE, value = TRUE) # .zip is tested with read.zip.Renishaw + for (f in files) { + expect_equal(dim(read.txt.Renishaw(!!f)), c(nrow = 875L, ncol = 4L, nwl = 1272L)) } }) } @@ -186,17 +204,17 @@ read.txt.Renishaw <- function (file = stop ("file is required"), ##' @param txt.file name of the .txt file in the .zip archive. Defaults to zip ##' file's name with suffix .txt instead of .zip ##' @rdname read.txt.Renishaw -read.zip.Renishaw <- function (file = stop ("filename is required"), - txt.file = sub ("[.]zip", ".txt", basename (file)), ...){ - read.txt.Renishaw (file = unz (file, filename = txt.file, "r"), ...) +read.zip.Renishaw <- function(file = stop("filename is required"), + txt.file = sub("[.]zip", ".txt", basename(file)), ...) { + read.txt.Renishaw(file = unz(file, filename = txt.file, "r"), ...) } -.test (read.zip.Renishaw) <- function(){ +.test(read.zip.Renishaw) <- function() { context("read.zip.Renishaw") - test_that("compressed files",{ - skip_if_not_fileio_available () - - expect_equal(dim (read.zip.Renishaw ("fileio/txt.Renishaw/chondro.zip")), c(nrow = 875L, ncol = 4L, nwl = 1272L)) + test_that("compressed files", { + skip_if_not_fileio_available() + + expect_equal(dim(read.zip.Renishaw("fileio/txt.Renishaw/chondro.zip")), c(nrow = 875L, ncol = 4L, nwl = 1272L)) }) } diff --git a/hyperSpec/R/read.txt.Shimadzu.R b/hyperSpec/R/read.txt.Shimadzu.R index 5e54f128d..8c8023c53 100644 --- a/hyperSpec/R/read.txt.Shimadzu.R +++ b/hyperSpec/R/read.txt.Shimadzu.R @@ -1,204 +1,205 @@ - ##' Reads Shimadzu GCxGC-qMS - Spectra Files (.txt) as exported by Shimadzu Chrome Solution (v. 2.72) - ##' Mass Spectrometer: Shimadzu GCMS-QP 2010 Ultra (www.shimadzu.com) - ##' - ##' @note This is a first rough import function and the functions may change without notice. - ##' @param filename file name and path of the .txt file - ##' @param encoding encoding of the txt file (used by \code{\link[base]{readLines}}) - ##' @param quiet suppress printing of progress - ##' @return list of spectra tables - ##' @author Bjoern Egert - ##' @export - ##' @importFrom utils read.table - read.txt.Shimadzu <- function(filename, encoding = "", quiet = TRUE) - { - - # A file consists of several sections ([Headers]) - # Each Section consists of: - # [Header] - # [MS Spectrum] - # [MC Peak Table] - # [MS Similarity Search Results for Spectrum Process Table] - - impLines <- readLines(con = filename, n = -1L, ok = TRUE, warn = TRUE, encoding = encoding) - length(impLines) - - # total numbers of pos1 and pos2 and pos3 are equal - pos1 <- which(impLines == "[Header]") # row positions of Headers - pos2 <- which(impLines == "[MC Peak Table]") # row positions of peak info tables - pos3 <- which(impLines == "[MS Similarity Search Results for Spectrum Process Table]") # row positions of peak annotations - pos4 <- which(impLines == "[MS Spectrum]") # row positions of peak spectra - - headers <- length(pos1) # number of header sections - - # link spectra to headers - pos4Li = list() - for (i in 1:(length(pos1))) - { - header <- pos1[i] - headerNext <- pos1[i+1] - tmp <- (pos4>header & pos4headerLast - pos4Li[[length(pos1)]] = pos4[tmp] - - for (i in 1:(length(pos4Li)-1)) - { - tmp <- length(pos4Li[[i]]) - vec <- pos4Li[[i]] - pos4Li[[i]] <- c(vec,pos1[i+1]) +##' Reads Shimadzu GCxGC-qMS - Spectra Files (.txt) as exported by Shimadzu Chrome Solution (v. 2.72) +##' Mass Spectrometer: Shimadzu GCMS-QP 2010 Ultra (www.shimadzu.com) +##' +##' @note This is a first rough import function and the functions may change without notice. +##' @param filename file name and path of the .txt file +##' @param encoding encoding of the txt file (used by \code{\link[base]{readLines}}) +##' @param quiet suppress printing of progress +##' @return list of spectra tables +##' @author Bjoern Egert +##' @export +##' @importFrom utils read.table +read.txt.Shimadzu <- function(filename, encoding = "", quiet = TRUE) { + + # A file consists of several sections ([Headers]) + # Each Section consists of: + # [Header] + # [MS Spectrum] + # [MC Peak Table] + # [MS Similarity Search Results for Spectrum Process Table] + + impLines <- readLines(con = filename, n = -1L, ok = TRUE, warn = TRUE, encoding = encoding) + length(impLines) + + # total numbers of pos1 and pos2 and pos3 are equal + pos1 <- which(impLines == "[Header]") # row positions of Headers + pos2 <- which(impLines == "[MC Peak Table]") # row positions of peak info tables + pos3 <- which(impLines == "[MS Similarity Search Results for Spectrum Process Table]") # row positions of peak annotations + pos4 <- which(impLines == "[MS Spectrum]") # row positions of peak spectra + + headers <- length(pos1) # number of header sections + + # link spectra to headers + pos4Li <- list() + for (i in 1:(length(pos1))) + { + header <- pos1[i] + headerNext <- pos1[i + 1] + tmp <- (pos4 > header & pos4 < headerNext) + pos4Li[[i]] <- pos4[tmp] + } + + # treat last Header section separately ... + headerLast <- pos1[length(pos1)] + tmp <- pos4 > headerLast + pos4Li[[length(pos1)]] <- pos4[tmp] + + for (i in 1:(length(pos4Li) - 1)) + { + tmp <- length(pos4Li[[i]]) + vec <- pos4Li[[i]] + pos4Li[[i]] <- c(vec, pos1[i + 1]) + } + # End position + pos4Li[[headers]] <- c(pos4Li[[headers]], length(impLines)) + + # Check + stopifnot(impLines[1] == "[Header]") + stopifnot(length(pos1) == length(pos2)) + stopifnot(length(pos2) == length(pos3)) + stopifnot(length(pos3) == length(pos4Li)) + + + # ----------------- 1. Import: gather [Header] informations + + # gather in lists + res2Li <- list() # Peak Info + res3Li <- list() # Peak Similarity + res4Li <- list() # Mass Spectra + + for (header in 1:headers) + { + if (!quiet) cat("header:", header, "\n") + + # ----------------- 1a. Import: "[MC Peak Table]" + + start <- pos2[header] + 3 + stop <- pos3[header] - 2 + + peakMat <- read.table( + file = filename, skip = start - 1, nrows = stop - start, + header = TRUE, sep = ";", dec = ".", comment.char = "", + stringsAsFactors = FALSE, quote = "\"'" + ) + + # maybe faster than above ... + # Peak#;Ret.Time;Proc.From;Proc.To;Mass;Area;Height;A/H;Conc.;Mark;Name;Ret. Index" + # colnames <- strsplit(impLines[start], split = ";")[[1]] + # strsplit(impLines[(start+1):stop], split = ";")[[1]] + # peakMat <- matrix(impLines[(start+1):stop], ncol = length(colnames), byrow = TRUE) + + res2Li[[header]] <- peakMat + + # ----------------- 1b. Import: "[MS Similarity Search Results for Spectrum Process Table]" + + start <- pos3[header] + 2 + stop <- pos4Li[[header]][1] - 1 + if (stop - start != 0) # no annotation hits + { + simMat <- read.table( + file = filename, skip = start - 1, , nrows = stop - start, + header = TRUE, sep = ";", dec = ".", comment.char = "", + stringsAsFactors = FALSE, quote = "" + ) # quote = "\"'" + } else { + simMat <- NA } - #End position - pos4Li[[headers]] <- c(pos4Li[[headers]], length(impLines)) - - # Check - stopifnot(impLines[1] == "[Header]") - stopifnot(length(pos1) == length(pos2)) - stopifnot(length(pos2) == length(pos3)) - stopifnot(length(pos3) == length(pos4Li)) - - - # ----------------- 1. Import: gather [Header] informations - - # gather in lists - res2Li <- list() # Peak Info - res3Li <- list() # Peak Similarity - res4Li <- list() # Mass Spectra - - for(header in 1:headers) + res3Li[[header]] <- simMat + + # ----------------- 1c. Import: "[MS Spectrum]" + + specLi <- list() # list of all spectra in current header section + for (i in 1:(length(pos4Li[[header]]) - 1)) { - - if(!quiet) cat("header:", header, "\n") - - # ----------------- 1a. Import: "[MC Peak Table]" - - start <- pos2[header]+3 - stop <- pos3[header]-2 - - peakMat <- read.table(file = filename, skip = start-1, nrows = stop - start, - header = TRUE, sep = ";", dec =".", comment.char = "", - stringsAsFactors = FALSE, quote = "\"'") - - # maybe faster than above ... - #Peak#;Ret.Time;Proc.From;Proc.To;Mass;Area;Height;A/H;Conc.;Mark;Name;Ret. Index" - #colnames <- strsplit(impLines[start], split = ";")[[1]] - #strsplit(impLines[(start+1):stop], split = ";")[[1]] - #peakMat <- matrix(impLines[(start+1):stop], ncol = length(colnames), byrow = TRUE) - - res2Li[[header]] <- peakMat - - # ----------------- 1b. Import: "[MS Similarity Search Results for Spectrum Process Table]" - - start <- pos3[header]+2 - stop <- pos4Li[[header]][1]-1 - if(stop-start!=0) # no annotation hits - { - simMat <- read.table(file = filename, skip = start - 1, , nrows = stop - start, - header = TRUE, sep = ";", dec =".", comment.char = "", - stringsAsFactors = FALSE, quote = "") # quote = "\"'" - }else simMat <- NA - res3Li[[header]] <- simMat - - # ----------------- 1c. Import: "[MS Spectrum]" - - specLi <- list() # list of all spectra in current header section - for(i in 1:(length(pos4Li[[header]])-1)) - { - - # extract spectra - start <- pos4Li[[header]][i]+5 # data starts 5 rows below - stop <- pos4Li[[header]][i+1]-1 # last data row before new Spectrum - - # debug purposes - if(! quiet) cat("header:", header, "spec:", i, "start:", start, "stop:", stop, "\n") - - # ------------------- - # Catch expeption, when peak is reported in peakMat, but [MS Spectrum] is not available: like example: (keyrow: # of Peaks; 0) - # [MS Spectrum] - # # of Peaks;0 - # Raw Spectrum;38.343 (scan : 68686);Base Peak;m/z 0.00 (Inten : 0) - # Background;38.342 <-> 38.348 (scan : 68684 <-> 68697) - # m/z;Absolute Intensity;Relative Intensity - # [MS Spectrum] - - checkRow <- pos4Li[[header]][i]+1 # check for: "# of Peaks;0" - isEmptySpec <- impLines[checkRow] == "# of Peaks;0" - if(isEmptySpec) - { - # special case: create dummy spectrum with zero intensities - spec <- cbind("m/z" = 1:100, "Absolute Intensity" = 0, "Relative Intensity" = 0) - - } - # ------------------- - - if(!isEmptySpec) - { - spec <- scan(file = filename, sep = ";", skip = start - 1, nlines = (stop - start) + 1, - dec = ".", quiet = TRUE) - spec <- matrix(spec,ncol = 3, byrow = T) - colnames(spec) <- c("m/z", "Absolute Intensity", "Relative Intensity") - } - - specLi[[i]] <- spec - + + # extract spectra + start <- pos4Li[[header]][i] + 5 # data starts 5 rows below + stop <- pos4Li[[header]][i + 1] - 1 # last data row before new Spectrum + + # debug purposes + if (!quiet) cat("header:", header, "spec:", i, "start:", start, "stop:", stop, "\n") + + # ------------------- + # Catch expeption, when peak is reported in peakMat, but [MS Spectrum] is not available: like example: (keyrow: # of Peaks; 0) + # [MS Spectrum] + # # of Peaks;0 + # Raw Spectrum;38.343 (scan : 68686);Base Peak;m/z 0.00 (Inten : 0) + # Background;38.342 <-> 38.348 (scan : 68684 <-> 68697) + # m/z;Absolute Intensity;Relative Intensity + # [MS Spectrum] + + checkRow <- pos4Li[[header]][i] + 1 # check for: "# of Peaks;0" + isEmptySpec <- impLines[checkRow] == "# of Peaks;0" + if (isEmptySpec) { + # special case: create dummy spectrum with zero intensities + spec <- cbind("m/z" = 1:100, "Absolute Intensity" = 0, "Relative Intensity" = 0) } - - res4Li[[header]] <- specLi - - } # for(headers) - - - # ----------------- 2. combine all headers sections - - # res2Li --> m2 - m2 <- as.data.frame(res2Li[[1]]) - m2 <- cbind(header = 1, m2) - for(header in 2:headers) - { - tmp <- as.data.frame(res2Li[[header]]) - tmp <- cbind(header=header,tmp) - m2 <- rbind(m2,tmp) + # ------------------- + + if (!isEmptySpec) { + spec <- scan( + file = filename, sep = ";", skip = start - 1, nlines = (stop - start) + 1, + dec = ".", quiet = TRUE + ) + spec <- matrix(spec, ncol = 3, byrow = T) + colnames(spec) <- c("m/z", "Absolute Intensity", "Relative Intensity") + } + + specLi[[i]] <- spec } - - # res3Li --> m3 - # In a header section there may be not annotation tables - m3 <- do.call("rbind", res3Li) - # add header Nr. - tmpMat <- lapply(X = res3Li, FUN = nrow) - tmpMat <- as.matrix(tmpMat) - tmp <- vector(length = 0) - for(i in 1:nrow(tmpMat)) + + res4Li[[header]] <- specLi + } # for(headers) + + + # ----------------- 2. combine all headers sections + + # res2Li --> m2 + m2 <- as.data.frame(res2Li[[1]]) + m2 <- cbind(header = 1, m2) + for (header in 2:headers) + { + tmp <- as.data.frame(res2Li[[header]]) + tmp <- cbind(header = header, tmp) + m2 <- rbind(m2, tmp) + } + + # res3Li --> m3 + # In a header section there may be not annotation tables + m3 <- do.call("rbind", res3Li) + # add header Nr. + tmpMat <- lapply(X = res3Li, FUN = nrow) + tmpMat <- as.matrix(tmpMat) + tmp <- vector(length = 0) + for (i in 1:nrow(tmpMat)) + { + if (tmpMat[i, 1] == "NULL") tmp <- c(tmp, i) + if (tmpMat[i, 1] != "NULL") tmp <- c(tmp, rep(x = i, times = tmpMat[i, 1])) + } + m3 <- cbind(header = tmp, m3) + m3 <- m3 [, c( + "header", "Spectrum.", "Hit..", "SI", "CAS..", "Name", "Mol.Weight", "Mol.Form", + "Retention.Index" + )] # select most important columns + tmp <- complete.cases(m3) + m3 <- m3[tmp, ] + + # res4Li --> m4 + tmp <- colnames(res4Li[[1]][[1]]) + m4 <- matrix(NA, nrow = 1, ncol = length(tmp)) + colnames(m4) <- tmp + m4 <- cbind(header = NA, spectra = NA, m4) # header number and spectra number as first columns + for (header in 1:headers) + { + for (spectra in 1:length(res4Li[[header]])) { - if(tmpMat[i,1] == "NULL" ) tmp <- c(tmp,i) - if(tmpMat[i,1] != "NULL" ) tmp <- c(tmp,rep(x = i, times = tmpMat[i,1])) - } - m3 <- cbind(header = tmp, m3) - m3 <- m3 [, c("header", "Spectrum.", "Hit..", "SI", "CAS..", "Name", "Mol.Weight", "Mol.Form", - "Retention.Index")] # select most important columns - tmp <- complete.cases(m3) - m3 <- m3[tmp,] - - # res4Li --> m4 - tmp <- colnames(res4Li[[1]][[1]]) - m4 <- matrix(NA, nrow = 1, ncol = length(tmp)) - colnames(m4) <- tmp - m4 <- cbind(header = NA, spectra = NA, m4) # header number and spectra number as first columns - for(header in 1:headers) - { - for(spectra in 1:length(res4Li[[header]])) - { - tmp <- as.matrix(res4Li[[header]][[spectra]]) - tmp <- cbind(header, spectra, tmp) - m4 <- rbind(m4, tmp) - }# spectras - }# header - mode(m4) <- "numeric" - m4 <- m4[-1,] - - return(list(peakInfo = m2, peakAnnotate = m3, peakMasses = m4)) - - } - + tmp <- as.matrix(res4Li[[header]][[spectra]]) + tmp <- cbind(header, spectra, tmp) + m4 <- rbind(m4, tmp) + } # spectras + } # header + mode(m4) <- "numeric" + m4 <- m4[-1, ] + + return(list(peakInfo = m2, peakAnnotate = m3, peakMasses = m4)) +} diff --git a/hyperSpec/R/read.txt.Witec.R b/hyperSpec/R/read.txt.Witec.R index 0c5c0d48e..997f10b61 100644 --- a/hyperSpec/R/read.txt.Witec.R +++ b/hyperSpec/R/read.txt.Witec.R @@ -21,73 +21,76 @@ ##' \code{\link{options}} for details on options. ##' @export ##' @importFrom utils head -read.txt.Witec <- function (file = stop ("filename or connection needed"), - points.per.line = NULL, - lines.per.image = NULL, - type = c ("single", "map"), - hdr.label = FALSE, - hdr.units = FALSE, - encoding = "unknown", - ..., - quiet = TRUE){ +read.txt.Witec <- function(file = stop("filename or connection needed"), + points.per.line = NULL, + lines.per.image = NULL, + type = c("single", "map"), + hdr.label = FALSE, + hdr.units = FALSE, + encoding = "unknown", + ..., + quiet = TRUE) { - ## check for valid data connection - .check.con (file = file) + ## check for valid data connection + .check.con(file = file) - ## check for valid input - type <- .check.valid (type, hdr = NULL, points.per.line, lines.per.image) + ## check for valid input + type <- .check.valid(type, hdr = NULL, points.per.line, lines.per.image) - ## manage possible header lines by export function 'Table' in WITec Control/Project (version 4) - skip <- hdr.label + hdr.units + ## manage possible header lines by export function 'Table' in WITec Control/Project (version 4) + skip <- hdr.label + hdr.units - ## read spectra - tmp <- readLines (file, encoding = encoding) - nwl <- length (tmp) - skip - txt <- scan (text = tmp, skip = skip, quiet = quiet, encoding = encoding, ...) + ## read spectra + tmp <- readLines(file, encoding = encoding) + nwl <- length(tmp) - skip + txt <- scan(text = tmp, skip = skip, quiet = quiet, encoding = encoding, ...) - dim (txt) <- c (length (txt) / nwl, nwl) + dim(txt) <- c(length(txt) / nwl, nwl) - hdr <- head (tmp, skip) + hdr <- head(tmp, skip) - ## fix: Witec/Andor may have final comma without values - if (all (is.na (txt [nrow (txt), ]))) - txt <- txt [- nrow (txt), ] + ## fix: Witec/Andor may have final comma without values + if (all(is.na(txt [nrow(txt), ]))) { + txt <- txt [-nrow(txt), ] + } - spc <- new ("hyperSpec", wavelength = txt [1, ], spc = txt [-1, ]) + spc <- new("hyperSpec", wavelength = txt [1, ], spc = txt [-1, ]) - ## add header information - if (hdr.label | hdr.units) - spc <- .parse.hdr (spc, hdr, hdr.label) + ## add header information + if (hdr.label | hdr.units) { + spc <- .parse.hdr(spc, hdr, hdr.label) + } - ## add map information - if (type == "map") - spc <- .parse.xy (spc, hdr, hdr.label, points.per.line, lines.per.image) + ## add map information + if (type == "map") { + spc <- .parse.xy(spc, hdr, hdr.label, points.per.line, lines.per.image) + } - ## consistent file import behaviour across import functions - .fileio.optional (spc, file) + ## consistent file import behaviour across import functions + .fileio.optional(spc, file) } -.test (read.txt.Witec) <- function (){ - context ("read.txt.Witec") +.test(read.txt.Witec) <- function() { + context("read.txt.Witec") test_that("Map with neither header nor label lines", { skip_if_not_fileio_available() - expect_error (suppressWarnings (read.txt.Witec("fileio/txt.Witec/Witec-Map_no.txt", - type = "map", hdr.units = TRUE, hdr.label = TRUE) - )) - expect_warning (read.txt.Witec("fileio/txt.Witec/Witec-Map_no.txt", type = "map")) + expect_error(suppressWarnings(read.txt.Witec("fileio/txt.Witec/Witec-Map_no.txt", + type = "map", hdr.units = TRUE, hdr.label = TRUE + ))) + expect_warning(read.txt.Witec("fileio/txt.Witec/Witec-Map_no.txt", type = "map")) spc <- read.txt.Witec("fileio/txt.Witec/Witec-Map_no.txt", type = "map", points.per.line = 5, lines.per.image = 5) - expect_known_hash (spc, hash = "6816a87cf3") + expect_known_hash(spc, hash = "6816a87cf3") }) test_that("Map: one of points.per.line and lines.per.image is sufficient", { skip_if_not_fileio_available() spc <- read.txt.Witec("fileio/txt.Witec/Witec-Map_no.txt", type = "map", lines.per.image = 5) - expect_known_hash (spc, hash = "6816a87cf3") + expect_known_hash(spc, hash = "6816a87cf3") spc <- read.txt.Witec("fileio/txt.Witec/Witec-Map_no.txt", type = "map", points.per.line = 5) - expect_known_hash (spc, hash = "6816a87cf3") + expect_known_hash(spc, hash = "6816a87cf3") }) test_that("Map with label line but no units header", { @@ -98,12 +101,14 @@ read.txt.Witec <- function (file = stop ("filename or connection needed"), test_that("Map with units header line but no labels", { skip_if_not_fileio_available() - expect_warning (spc <- read.txt.Witec("fileio/txt.Witec/Witec-Map_unit.txt", type = "map", hdr.units = TRUE, hdr.label = FALSE)) + expect_warning(spc <- read.txt.Witec("fileio/txt.Witec/Witec-Map_unit.txt", type = "map", hdr.units = TRUE, hdr.label = FALSE)) expect_null(spc$x) expect_null(spc$y) - spc <- read.txt.Witec("fileio/txt.Witec/Witec-Map_unit.txt", type = "map", hdr.units = TRUE, hdr.label = FALSE, - points.per.line = 5, lines.per.image = 5) + spc <- read.txt.Witec("fileio/txt.Witec/Witec-Map_unit.txt", + type = "map", hdr.units = TRUE, hdr.label = FALSE, + points.per.line = 5, lines.per.image = 5 + ) expect_known_hash(spc, "86ecc17360") }) @@ -113,7 +118,7 @@ read.txt.Witec <- function (file = stop ("filename or connection needed"), expect_known_hash(spc, "76db6397fc") }) - test_that ("Map can be read as time series", { + test_that("Map can be read as time series", { skip_if_not_fileio_available() spc <- read.txt.Witec("fileio/txt.Witec/Witec-Map_no.txt") expect_known_hash(spc, "6213aefc6b") @@ -122,7 +127,7 @@ read.txt.Witec <- function (file = stop ("filename or connection needed"), }) - test_that ("parameter default type = 'single'", { + test_that("parameter default type = 'single'", { skip_if_not_fileio_available() spc <- read.txt.Witec("fileio/txt.Witec/Witec-timeseries_no.txt") expect_known_hash(spc, "1a8c3be079") @@ -142,14 +147,14 @@ read.txt.Witec <- function (file = stop ("filename or connection needed"), test_that("Time series with units header line but no labels", { skip_if_not_fileio_available() - spc <- read.txt.Witec("fileio/txt.Witec/Witec-timeseries_unit.txt", hdr.units = TRUE, hdr.label = FALSE) + spc <- read.txt.Witec("fileio/txt.Witec/Witec-timeseries_unit.txt", hdr.units = TRUE, hdr.label = FALSE) expect_known_hash(spc, "6b6abac4e8") }) test_that("Time series with header and label lines", { skip_if_not_fileio_available() - expect_error (spc <- read.txt.Witec("fileio/txt.Witec/Witec-timeseries_full.txt")) + expect_error(spc <- read.txt.Witec("fileio/txt.Witec/Witec-timeseries_full.txt")) spc <- read.txt.Witec("fileio/txt.Witec/Witec-timeseries_full.txt", hdr.units = TRUE, hdr.label = TRUE) expect_known_hash(spc, "db5b1a5db0") @@ -157,8 +162,10 @@ read.txt.Witec <- function (file = stop ("filename or connection needed"), test_that("encoding", { skip_if_not_fileio_available() - spc <- read.txt.Witec("fileio/txt.Witec/Witec-timeseries_full.txt", hdr.units = TRUE, hdr.label = TRUE, - encoding = "ascii") + spc <- read.txt.Witec("fileio/txt.Witec/Witec-timeseries_full.txt", + hdr.units = TRUE, hdr.label = TRUE, + encoding = "ascii" + ) expect_known_hash(spc, "db5b1a5db0") }) } @@ -167,59 +174,62 @@ read.txt.Witec <- function (file = stop ("filename or connection needed"), ##' @param filex filename wavelength axis file ##' @param filey filename intensity file ##' @export -read.dat.Witec <- function (filex = stop ("filename or connection needed"), - filey = sub ("-x", "-y", filex), - points.per.line = NULL, - lines.per.image = NULL, - type = c ("single", "map"), - encoding = "unknown", - ..., - quiet = hy.getOption ("debuglevel") < 1L){ - ## check valid data connection - .check.con (filex = filex, filey = filey) - - ## check valid input - type <- .check.valid (type = type, points.per.line = points.per.line, - lines.per.image = lines.per.image) - - ## read data - wl <- scan (file = filex, ..., quiet = quiet, encoding = encoding) - spc <- scan (file = filey, ..., quiet = quiet, encoding = encoding) - - dim (spc) <- c (length (wl), length (spc) / length (wl)) - - spc <- new ("hyperSpec", wavelength = wl, spc = t (spc)) - - ## add map information - if (type == "map") - spc <- .parse.xy (spc = spc, points.per.line = points.per.line, lines.per.image = lines.per.image) - - ## consistent file import behaviour across import functions - .fileio.optional (spc, filey) +read.dat.Witec <- function(filex = stop("filename or connection needed"), + filey = sub("-x", "-y", filex), + points.per.line = NULL, + lines.per.image = NULL, + type = c("single", "map"), + encoding = "unknown", + ..., + quiet = hy.getOption("debuglevel") < 1L) { + ## check valid data connection + .check.con(filex = filex, filey = filey) + + ## check valid input + type <- .check.valid( + type = type, points.per.line = points.per.line, + lines.per.image = lines.per.image + ) + + ## read data + wl <- scan(file = filex, ..., quiet = quiet, encoding = encoding) + spc <- scan(file = filey, ..., quiet = quiet, encoding = encoding) + + dim(spc) <- c(length(wl), length(spc) / length(wl)) + + spc <- new("hyperSpec", wavelength = wl, spc = t(spc)) + + ## add map information + if (type == "map") { + spc <- .parse.xy(spc = spc, points.per.line = points.per.line, lines.per.image = lines.per.image) + } + + ## consistent file import behaviour across import functions + .fileio.optional(spc, filey) } -.test (read.dat.Witec) <- function (){ +.test(read.dat.Witec) <- function() { context("read.dat.Witec") - test_that ("-y file guessing", { + test_that("-y file guessing", { skip_if_not_fileio_available() spc <- read.dat.Witec("fileio/txt.Witec/Witec-timeseries-x.dat") expect_known_hash(spc, "9562f59323") }) - test_that ("encoding", { + test_that("encoding", { skip_if_not_fileio_available() spc <- read.dat.Witec("fileio/txt.Witec/Witec-timeseries-x.dat", encoding = "ascii") expect_known_hash(spc, "9562f59323") }) - test_that ("Time series", { + test_that("Time series", { skip_if_not_fileio_available() spc <- read.dat.Witec("fileio/txt.Witec/Witec-timeseries-x.dat", "fileio/txt.Witec/Witec-timeseries-y.dat") expect_known_hash(spc, "9562f59323") }) - test_that ("Map: .dat does not have spatial information", { + test_that("Map: .dat does not have spatial information", { skip_if_not_fileio_available() spc <- read.dat.Witec("fileio/txt.Witec/Witec-Map-x.dat", "fileio/txt.Witec/Witec-Map-y.dat") expect_null(spc$x) @@ -227,75 +237,80 @@ read.dat.Witec <- function (filex = stop ("filename or connection needed"), expect_known_hash(spc, "8a7ed06b0b") }) - test_that ("Map", { + test_that("Map", { skip_if_not_fileio_available() expect_warning(read.dat.Witec("fileio/txt.Witec/Witec-Map-x.dat", "fileio/txt.Witec/Witec-Map-y.dat", - points.per.line = 5, lines.per.image = 5) - ) + points.per.line = 5, lines.per.image = 5 + )) spc <- read.dat.Witec("fileio/txt.Witec/Witec-Map-x.dat", "fileio/txt.Witec/Witec-Map-y.dat", - type = "map", points.per.line = 5, lines.per.image = 5) + type = "map", points.per.line = 5, lines.per.image = 5 + ) expect_known_hash(spc, "3d6339675b") }) - - } ##' @rdname read.txt.Witec ##' @param headerfile filename or connection to ASCII file with header information ##' @export -read.txt.Witec.Graph <- function (headerfile = stop ("filename or connection needed"), - filex = gsub ("Header", "X-Axis", headerfile), - filey = gsub ("Header", "Y-Axis", headerfile), - type = c ("single", "map"), encoding = "unknown", - ..., quiet = TRUE){ - ## check for valid data connection - .check.con (headerfile, filex, filey) - - ## processing headerfile - hdr <- read.ini (headerfile, skip = 1, encoding = encoding) - hdr <- sapply (hdr, function (x) unlist (x, recursive = FALSE)) # returns a matrix with colnames and rownames for better adressing - - ## check valid input - type <- .check.valid (type = type, hdr = hdr, - ...) - - ## read spectra and header - wl <- scan (filex, quiet = quiet, encoding = encoding) - nwl <- length (wl) - - txt <- scan (filey, quiet = quiet, encoding = encoding) - dim (txt) <- c (nwl, length (txt) / nwl) - - spc <- new ("hyperSpec", wavelength = wl, spc = t (txt)) - - ## cross validation of parameters and information provided by header file - if (nwl != hdr["SizeGraph", ]) - stop (paste ("length of wavelength axis in file '", filex, - "' differs from 'SizeGraph' in header file '", headerfile, "'", sep ="")) - - ## add header information - spc <- .parse.hdr (spc, hdr) - - ## add map information - if (type == "map") - spc <- .parse.xy (spc, hdr, ...) - - ## consistent file import behaviour across import functions - .fileio.optional (spc, filex) +read.txt.Witec.Graph <- function(headerfile = stop("filename or connection needed"), + filex = gsub("Header", "X-Axis", headerfile), + filey = gsub("Header", "Y-Axis", headerfile), + type = c("single", "map"), encoding = "unknown", + ..., quiet = TRUE) { + ## check for valid data connection + .check.con(headerfile, filex, filey) + + ## processing headerfile + hdr <- read.ini(headerfile, skip = 1, encoding = encoding) + hdr <- sapply(hdr, function(x) unlist(x, recursive = FALSE)) # returns a matrix with colnames and rownames for better adressing + + ## check valid input + type <- .check.valid( + type = type, hdr = hdr, + ... + ) + + ## read spectra and header + wl <- scan(filex, quiet = quiet, encoding = encoding) + nwl <- length(wl) + + txt <- scan(filey, quiet = quiet, encoding = encoding) + dim(txt) <- c(nwl, length(txt) / nwl) + + spc <- new("hyperSpec", wavelength = wl, spc = t(txt)) + + ## cross validation of parameters and information provided by header file + if (nwl != hdr["SizeGraph", ]) { + stop(paste("length of wavelength axis in file '", filex, + "' differs from 'SizeGraph' in header file '", headerfile, "'", + sep = "" + )) + } + + ## add header information + spc <- .parse.hdr(spc, hdr) + + ## add map information + if (type == "map") { + spc <- .parse.xy(spc, hdr, ...) + } + + ## consistent file import behaviour across import functions + .fileio.optional(spc, filex) } -.test (read.txt.Witec.Graph) <- function (){ - context ("read.txt.Witec.Graph") +.test(read.txt.Witec.Graph) <- function() { + context("read.txt.Witec.Graph") - test_that ("defaults and (X-Axis)/(Y-Axis) file guessing", { + test_that("defaults and (X-Axis)/(Y-Axis) file guessing", { skip_if_not_fileio_available() spc <- read.txt.Witec.Graph("fileio/txt.Witec/Witec-timeseries (Header).txt") expect_known_hash(spc, "295499c43c") }) - test_that ("encoding", { + test_that("encoding", { skip_if_not_fileio_available() expect_warning(read.txt.Witec.Graph("fileio/txt.Witec/nofilename (Header).txt")) @@ -303,16 +318,16 @@ read.txt.Witec.Graph <- function (headerfile = stop ("filename or connection nee expect_known_hash(spc, "2bad36adb3") }) - test_that ("Time Series", { + test_that("Time Series", { skip_if_not_fileio_available() spc <- read.txt.Witec.Graph("fileio/txt.Witec/Witec-timeseries (Header).txt", type = "single") expect_known_hash(spc, "295499c43c") }) - test_that ("Map", { + test_that("Map", { skip_if_not_fileio_available() - expect_warning (read.txt.Witec.Graph("fileio/txt.Witec/Witec-Map (Header).txt")) - expect_warning (read.txt.Witec.Graph("fileio/txt.Witec/Witec-Map (Header).txt", type = "single")) + expect_warning(read.txt.Witec.Graph("fileio/txt.Witec/Witec-Map (Header).txt")) + expect_warning(read.txt.Witec.Graph("fileio/txt.Witec/Witec-Map (Header).txt", type = "single")) spc <- read.txt.Witec.Graph("fileio/txt.Witec/Witec-Map (Header).txt", type = "map") expect_known_hash(spc, "cb9cd9757a") @@ -324,108 +339,117 @@ read.txt.Witec.Graph <- function (headerfile = stop ("filename or connection nee expect_known_hash(spc, "2bad36adb3") }) - test_that ("wrong combination of file names", { + test_that("wrong combination of file names", { skip_if_not_fileio_available() - expect_error (read.txt.Witec.Graph("fileio/txt.Witec/Witec-timeseries (Header).txt", "fileio/txt.Witec/Witec-timeseries (Y-Axis).txt")) + expect_error(read.txt.Witec.Graph("fileio/txt.Witec/Witec-timeseries (Header).txt", "fileio/txt.Witec/Witec-timeseries (Y-Axis).txt")) }) - } ### -------- helpers ------------------------ -###checking file connection -.check.con <- function (headerfile, filex, filey, file){ - ## check for valid data connection - if (!missing (headerfile) && !file.exists (headerfile)) - stop ("Header file not found!") +### checking file connection +.check.con <- function(headerfile, filex, filey, file) { + ## check for valid data connection + if (!missing(headerfile) && !file.exists(headerfile)) { + stop("Header file not found!") + } - if (!missing (filex) && !file.exists (filex)) - stop ("Wavelength axis file not found!") + if (!missing(filex) && !file.exists(filex)) { + stop("Wavelength axis file not found!") + } - if (!missing (filey) && !file.exists (filey)) - stop ("Intensity file not found!") + if (!missing(filey) && !file.exists(filey)) { + stop("Intensity file not found!") + } - if (!missing (file) && !file.exists (file)) - stop ("Spectra file not found!") + if (!missing(file) && !file.exists(file)) { + stop("Spectra file not found!") + } } -###checking for valid input -.check.valid <- function (type, hdr, points.per.line, lines.per.image){ - ## check valid input - type <- match.arg (type, c ("single", "map")) +### checking for valid input +.check.valid <- function(type, hdr, points.per.line, lines.per.image) { + ## check valid input + type <- match.arg(type, c("single", "map")) - if (type == "single" && !missing (points.per.line) && !is.null (points.per.line) && points.per.line != 1)#TODO: better to prove for values > 1? - warning ("points.per.line != 1 given for single spectrum") + if (type == "single" && !missing(points.per.line) && !is.null(points.per.line) && points.per.line != 1) { # TODO: better to prove for values > 1? + warning("points.per.line != 1 given for single spectrum") + } - if (type == "single" && !missing (lines.per.image) && !is.null (lines.per.image) && lines.per.image != 1)#TODO: see above - warning ("lines.per.image != 1 are defined for single spectrum") + if (type == "single" && !missing(lines.per.image) && !is.null(lines.per.image) && lines.per.image != 1) { # TODO: see above + warning("lines.per.image != 1 are defined for single spectrum") + } - if (type == "single" && !missing (hdr) && !is.null (hdr) && hdr ["SizeY", ] != 1) - warning ("header provides spatial information in y direction for single spectra") + if (type == "single" && !missing(hdr) && !is.null(hdr) && hdr ["SizeY", ] != 1) { + warning("header provides spatial information in y direction for single spectra") + } - return (type) + return(type) } ### parsing header information -.parse.hdr <- function (spc, hdr, hdr.label) { - if (!missing (hdr) && !missing (hdr.label)){ - hdr <- strsplit (hdr, "\t") - - if (length (hdr) == 2){ - spc@data$spcname <- hdr [[1]][-1] - labels (spc, ".wavelength") <- hdr [[2]] [1] - labels (spc, "spc") <- unique (hdr [[2]] [-1]) - } else if (length (hdr) == 1 && hdr.label){ - spc@data$spcname <- hdr [[1]][-1] - } else { - labels (spc, ".wavelength") <- hdr [[1]] [1] - labels (spc, "spc") <- unique (hdr [[1]] [-1]) - } +.parse.hdr <- function(spc, hdr, hdr.label) { + if (!missing(hdr) && !missing(hdr.label)) { + hdr <- strsplit(hdr, "\t") + + if (length(hdr) == 2) { + spc@data$spcname <- hdr [[1]][-1] + labels(spc, ".wavelength") <- hdr [[2]] [1] + labels(spc, "spc") <- unique(hdr [[2]] [-1]) + } else if (length(hdr) == 1 && hdr.label) { + spc@data$spcname <- hdr [[1]][-1] + } else { + labels(spc, ".wavelength") <- hdr [[1]] [1] + labels(spc, "spc") <- unique(hdr [[1]] [-1]) } + } - if (!missing (hdr) && missing (hdr.label)){ - spc@data$spcname <- hdr ["GraphName", ] - if ("FileName" %in% rownames (hdr)) - spc@data$WIPname <- hdr ["FileName", ] - labels (spc, "spc") <- hdr ["DataUnit", ] + if (!missing(hdr) && missing(hdr.label)) { + spc@data$spcname <- hdr ["GraphName", ] + if ("FileName" %in% rownames(hdr)) { + spc@data$WIPname <- hdr ["FileName", ] } - return (spc) + labels(spc, "spc") <- hdr ["DataUnit", ] + } + return(spc) } ### parsing map information -.parse.xy <- function (spc, hdr, hdr.label, points.per.line, lines.per.image, ...){ - - ## set points.per.line and lines.per.image, if at least one is set unequal NULL - if (xor (!missing (points.per.line) && !is.null (points.per.line), - !missing (lines.per.image) && !is.null(lines.per.image))){ - if ((missing (points.per.line) || is.null (points.per.line)) && - !is.null (lines.per.image)) { - points.per.line <- nrow (spc) / lines.per.image - } else { - lines.per.image <- nrow (spc) / points.per.line - } - - } else if (!missing (points.per.line) && !missing (lines.per.image) && - is.null (points.per.line) && is.null (points.per.line) && - !missing (hdr.label) && hdr.label) {#TODO: only read, if not yet calculated? - x <- sub ("^.*\\(([[:digit:]]+)/[[:digit:]]+\\)$", "\\1", hdr[1]) - y <- sub ("^.*\\([[:digit:]]+/([[:digit:]]+)\\)$", "\\1", hdr[1]) - points.per.line <- as.numeric (x) + 1 - lines.per.image <- as.numeric (y) + 1 - } else if ((missing (points.per.line) || missing (lines.per.image)) && - !missing (hdr) && missing (hdr.label)){#TODO: only read, if not yet calculated? - points.per.line <- as.numeric (hdr ["SizeX", ]) - lines.per.image <- as.numeric (hdr ["SizeY", ]) - } else if (is.null (points.per.line) && is.null (lines.per.image)) { - warning ("no spatial information provided") - return (spc) +.parse.xy <- function(spc, hdr, hdr.label, points.per.line, lines.per.image, ...) { + + ## set points.per.line and lines.per.image, if at least one is set unequal NULL + if (xor( + !missing(points.per.line) && !is.null(points.per.line), + !missing(lines.per.image) && !is.null(lines.per.image) + )) { + if ((missing(points.per.line) || is.null(points.per.line)) && + !is.null(lines.per.image)) { + points.per.line <- nrow(spc) / lines.per.image + } else { + lines.per.image <- nrow(spc) / points.per.line } - - if (points.per.line * lines.per.image == nrow (spc)){ - spc@data$x <- rep (seq_len (points.per.line), lines.per.image) - spc@data$y <- rep (- seq_len (lines.per.image), each = points.per.line) - } else - warning ("number of spectra and number of points in map are not equal!") - - return (spc) + } else if (!missing(points.per.line) && !missing(lines.per.image) && + is.null(points.per.line) && is.null(points.per.line) && + !missing(hdr.label) && hdr.label) { # TODO: only read, if not yet calculated? + x <- sub("^.*\\(([[:digit:]]+)/[[:digit:]]+\\)$", "\\1", hdr[1]) + y <- sub("^.*\\([[:digit:]]+/([[:digit:]]+)\\)$", "\\1", hdr[1]) + points.per.line <- as.numeric(x) + 1 + lines.per.image <- as.numeric(y) + 1 + } else if ((missing(points.per.line) || missing(lines.per.image)) && + !missing(hdr) && missing(hdr.label)) { # TODO: only read, if not yet calculated? + points.per.line <- as.numeric(hdr ["SizeX", ]) + lines.per.image <- as.numeric(hdr ["SizeY", ]) + } else if (is.null(points.per.line) && is.null(lines.per.image)) { + warning("no spatial information provided") + return(spc) + } + + if (points.per.line * lines.per.image == nrow(spc)) { + spc@data$x <- rep(seq_len(points.per.line), lines.per.image) + spc@data$y <- rep(-seq_len(lines.per.image), each = points.per.line) + } else { + warning("number of spectra and number of points in map are not equal!") + } + + return(spc) } diff --git a/hyperSpec/R/read.txt.long.R b/hyperSpec/R/read.txt.long.R index 805c850ce..2ce828481 100644 --- a/hyperSpec/R/read.txt.long.R +++ b/hyperSpec/R/read.txt.long.R @@ -114,59 +114,59 @@ ##' ##' ##' @importFrom utils read.table unstack -read.txt.long <- function (file = stop ("file is required"), - cols = list ( - .wavelength = expression (lambda / nm), - spc = "I / a.u." - ), - header = TRUE, - ...) { - txtfile <- read.table (file = file, header = header, ...) +read.txt.long <- function(file = stop("file is required"), + cols = list( + .wavelength = expression(lambda / nm), + spc = "I / a.u." + ), + header = TRUE, + ...) { + txtfile <- read.table(file = file, header = header, ...) if (header) { - cln <- match (colnames (txtfile), names (cols)) + cln <- match(colnames(txtfile), names(cols)) cln <- cols[cln] - names (cln) <- colnames (txtfile) + names(cln) <- colnames(txtfile) cols <- cln - rm (cln) + rm(cln) } else { - if (ncol (txtfile) != length (cols)) { - warning (paste ( + if (ncol(txtfile) != length(cols)) { + warning(paste( "cols does not correspond to the columns in", file, ". Guessing remaining columns." )) - cols <- c (character (ncol (txtfile) - 2), cols) + cols <- c(character(ncol(txtfile) - 2), cols) } } - if (is.na (match ("spc", names (cols)))) { - stop ("cols$spc must exist.") + if (is.na(match("spc", names(cols)))) { + stop("cols$spc must exist.") } - wavelength <- match (".wavelength", names (cols)) - if (is.na (wavelength)) { - stop ("cols$.wavelength must exist.") + wavelength <- match(".wavelength", names(cols)) + if (is.na(wavelength)) { + stop("cols$.wavelength must exist.") } - colnames (txtfile) <- names (cols) + colnames(txtfile) <- names(cols) ## wavelength axis - wavelength <- as.numeric (levels (as.factor (txtfile$.wavelength))) + wavelength <- as.numeric(levels(as.factor(txtfile$.wavelength))) - spc <- as.matrix (unstack (txtfile, form = spc ~ .wavelength)) - if ((nrow (spc) == length (wavelength)) & (ncol (spc) != length (wavelength))) { - spc <- t (spc) + spc <- as.matrix(unstack(txtfile, form = spc ~ .wavelength)) + if ((nrow(spc) == length(wavelength)) & (ncol(spc) != length(wavelength))) { + spc <- t(spc) } - colnames (spc) <- levels (txtfile$.wavelength) + colnames(spc) <- levels(txtfile$.wavelength) txtfile <- txtfile [txtfile$.wavelength == txtfile$.wavelength[1], ] txtfile$.wavelength <- NULL - txtfile$spc <- I (spc) + txtfile$spc <- I(spc) - spc <- new ("hyperSpec", wavelength = wavelength, data = txtfile, labels = cols) + spc <- new("hyperSpec", wavelength = wavelength, data = txtfile, labels = cols) ## consistent file import behaviour across import functions - .fileio.optional (spc, filename = file) + .fileio.optional(spc, filename = file) } diff --git a/hyperSpec/R/read.txt.wide.R b/hyperSpec/R/read.txt.wide.R index ee3a1680d..2b7f7b104 100644 --- a/hyperSpec/R/read.txt.wide.R +++ b/hyperSpec/R/read.txt.wide.R @@ -1,4 +1,4 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### read.txt.wide ### @@ -45,40 +45,44 @@ ##' the column names of the spectra are the wavelength values. ##' @export ##' @importFrom utils read.table head -read.txt.wide <- function (file = stop ("file is required"), - cols = list ( - spc = "I / a.u.", - .wavelength = expression (lambda / nm)), - sep = '\t', - row.names = NULL, - check.names = FALSE, - ...){ - - .wavelength <- match (".wavelength", names (cols)) - if (is.na (.wavelength)) - cols <- as.list (c (cols, .wavelength = expression (lambda / nm))) - else - if (.wavelength != length (cols)) # .wavelength should be at the end of cols - cols <- cols [c (seq_along (cols)[-.wavelength], .wavelength)] +read.txt.wide <- function(file = stop("file is required"), + cols = list( + spc = "I / a.u.", + .wavelength = expression(lambda / nm) + ), + sep = "\t", + row.names = NULL, + check.names = FALSE, + ...) { + .wavelength <- match(".wavelength", names(cols)) + if (is.na(.wavelength)) { + cols <- as.list(c(cols, .wavelength = expression(lambda / nm))) + } else + if (.wavelength != length(cols)) { # .wavelength should be at the end of cols + cols <- cols [c(seq_along(cols)[-.wavelength], .wavelength)] + } ## columns containing the spectra - spc <- match ("spc", names (cols)) - if (is.na (spc)) - stop ("cols$spc must exist.") + spc <- match("spc", names(cols)) + if (is.na(spc)) { + stop("cols$spc must exist.") + } - txtfile <- read.table (file = file, check.names = check.names, row.names = row.names, - sep = sep, ...) + txtfile <- read.table( + file = file, check.names = check.names, row.names = row.names, + sep = sep, ... + ) - ispc <- 0 : (ncol (txtfile) - length (cols) + 1) + spc + ispc <- 0:(ncol(txtfile) - length(cols) + 1) + spc - spc.data <- as.matrix (txtfile[, ispc]) + spc.data <- as.matrix(txtfile[, ispc]) txtfile <- txtfile [, -ispc, drop = FALSE] - + ## enforce colnames given by cols - colnames (txtfile) <- head (names (cols) [-spc], -1) + colnames(txtfile) <- head(names(cols) [-spc], -1) - spc <- new ("hyperSpec", spc = spc.data, data = txtfile, labels = cols) + spc <- new("hyperSpec", spc = spc.data, data = txtfile, labels = cols) ## consistent file import behaviour across import functions - .fileio.optional (spc, filename = file) + .fileio.optional(spc, filename = file) } diff --git a/hyperSpec/R/replace.R b/hyperSpec/R/replace.R index 36f6af5a7..31d542b66 100644 --- a/hyperSpec/R/replace.R +++ b/hyperSpec/R/replace.R @@ -1,9 +1,9 @@ ##' @rdname extractreplace ##' @name [<- ##' @usage -##' +##' ##' \S4method{[}{hyperSpec}(x, i, j, \dots) <- value -##' +##' ##' @aliases [<-,hyperSpec-method ##' @param value the replacement value ##' @include wl2i.R @@ -19,33 +19,35 @@ ##' spc [] <- 6 : 1 ##' spc$.. ##' plot (spc) -##' -setReplaceMethod("[", signature = signature (x = "hyperSpec"), - function (x, i, j, - ..., - value){ - validObject (x) - - if (missing (i)) i <- row.seq (x) - if (missing (j)) j <- col.seq (x) - - if (is (value, "hyperSpec")){ - validObject (value) - x@data [i, j, ...] <- value@data - } else { - x@data [i, j, ...] <- value - } +##' +setReplaceMethod("[", + signature = signature(x = "hyperSpec"), + function(x, i, j, + ..., + value) { + validObject(x) + + if (missing(i)) i <- row.seq(x) + if (missing(j)) j <- col.seq(x) + + if (is(value, "hyperSpec")) { + validObject(value) + x@data [i, j, ...] <- value@data + } else { + x@data [i, j, ...] <- value + } - validObject (x) + validObject(x) - x -}) + x + } +) ##' @rdname extractreplace ##' @usage -##' +##' ##' \S4method{[[}{hyperSpec}(x, i, j, l, wl.index = FALSE, \dots) <- value -##' +##' ##' @aliases [[<-,hyperSpec-method ##' @name [[<- ##' @export @@ -57,71 +59,80 @@ setReplaceMethod("[", signature = signature (x = "hyperSpec"), ##' spc [[,,405 : 410]] <- -spc[[,,405 : 410]] ##' spc [[]] ##' spc [[,,405 ~ 410]] <- -spc[[,,405 ~ 410]] -##' +##' ##' ## indexing with logical matrix ##' spc <- flu [,, min ~ 410] ##' spc < 125 ##' spc [[spc < 125]] <- NA ##' spc [[]] -##' +##' ##' ## indexing with n by 2 matrix ##' ind <- matrix (c (1, 2, 4, 406, 405.5, 409), ncol = 2) ##' ind ##' spc [[ind]] <- 3 ##' spc [[]] -##' +##' ##' ind <- matrix (c (1, 2, 4, 4:6), ncol = 2) ##' ind ##' spc [[ind, wl.index = TRUE]] <- 9999 ##' spc [[]] -##' -setReplaceMethod ("[[", signature = signature (x = "hyperSpec"), - function (x, i, j, l, wl.index = FALSE, - ..., value){ - validObject (x) - - - if (is (value, "hyperSpec")){ - validObject (value) - value <- value@data$spc - } - - ## check wheter a index matrix is used - if (! missing (i) && is.matrix (i)){ - if (is.logical (i)) { - x@data$spc [i] <- value - } else if (is.numeric (i) && ncol (i) == 2) { - if (! wl.index) { - i [, 2] <- .getindex (x, i [, 2], extrapolate = FALSE) - if (any (is.na (i [, 2]))) - stop ("wavelength specification outside spectral range") +##' +setReplaceMethod("[[", + signature = signature(x = "hyperSpec"), + function(x, i, j, l, wl.index = FALSE, + ..., value) { + validObject(x) + + + if (is(value, "hyperSpec")) { + validObject(value) + value <- value@data$spc + } + + ## check wheter a index matrix is used + if (!missing(i) && is.matrix(i)) { + if (is.logical(i)) { + x@data$spc [i] <- value + } else if (is.numeric(i) && ncol(i) == 2) { + if (!wl.index) { + i [, 2] <- .getindex(x, i [, 2], extrapolate = FALSE) + if (any(is.na(i [, 2]))) { + stop("wavelength specification outside spectral range") + } + } + x@data$spc [i] <- value + } else { + stop( + "Index matrix i must either be logical of the size of x$spc,", + "or a n by 2 matrix." + ) } - x@data$spc [i] <- value - } else - stop ("Index matrix i must either be logical of the size of x$spc,", - "or a n by 2 matrix.") - - } else { # index by row and columns - if (! missing (j)) - stop ("The spectra matrix may only be indexed by i (spectra) and l", - " (wavelengths). j (data column) must be missing.") - - if (!missing (l) && !wl.index) - l <- wl2i (x, l) - - x@data$spc[i, l, ...] <- value - } + } else { # index by row and columns + if (!missing(j)) { + stop( + "The spectra matrix may only be indexed by i (spectra) and l", + " (wavelengths). j (data column) must be missing." + ) + } + + if (!missing(l) && !wl.index) { + l <- wl2i(x, l) + } + + x@data$spc[i, l, ...] <- value + } - validObject (x) + validObject(x) - x -}) + x + } +) ##' @rdname extractreplace ##' @usage -##' +##' ##' \S4method{$}{hyperSpec}(x, name) <- value -##' +##' ##' @aliases $<-,hyperSpec-method ##' @name $<- ##' @export @@ -129,42 +140,43 @@ setReplaceMethod ("[[", signature = signature (x = "hyperSpec"), ##' spc$. ##' spc$z <- 1 : 6 ##' spc -##' spc$z <- list (1 : 6, "z / a.u.") -##' - -setReplaceMethod ("$", signature = signature (x = "hyperSpec"), - function (x, name, value){ - validObject (x) +##' spc$z <- list (1 : 6, "z / a.u.") +##' - if (is.list (value) && (length (value) == 2)){ - ilabel <- match ("label", names (value)) +setReplaceMethod("$", + signature = signature(x = "hyperSpec"), + function(x, name, value) { + validObject(x) - if (is.na (ilabel)) - ilabel <- 2 + if (is.list(value) && (length(value) == 2)) { + ilabel <- match("label", names(value)) - label <- value [[ilabel]] + if (is.na(ilabel)) { + ilabel <- 2 + } - value <- value [[3 - ilabel]] ## the other of the 2 entries + label <- value [[ilabel]] - } else { - label <- name - } + value <- value [[3 - ilabel]] ## the other of the 2 entries + } else { + label <- name + } - if (name == "..") { ## shortcut - i <- -match ("spc", colnames (x@data)) - x@data[, i] <- value + if (name == "..") { ## shortcut + i <- -match("spc", colnames(x@data)) + x@data[, i] <- value - if (!is.null (label)){ - i <- colnames (x@data)[i] - i <- match (i, names (x@label)) - x@label[i] <- label + if (!is.null(label)) { + i <- colnames(x@data)[i] + i <- match(i, names(x@label)) + x@label[i] <- label + } + } else { + dots <- list(x = x@data, name = name, value = value) + x@data <- do.call("$<-", dots) + x@label[[name]] <- label } - } else { - dots <- list (x = x@data, name = name, value = value) - x@data <- do.call("$<-", dots) - x@label[[name]] <- label - } - - x -}) + x + } +) diff --git a/hyperSpec/R/sample.R b/hyperSpec/R/sample.R index 4626f5ef0..c748eff10 100644 --- a/hyperSpec/R/sample.R +++ b/hyperSpec/R/sample.R @@ -1,36 +1,35 @@ -.sample <- function (x, size, replace = FALSE, prob = NULL) { - validObject (x) +.sample <- function(x, size, replace = FALSE, prob = NULL) { + validObject(x) - if (missing (size)) size <- nrow (x) # normal default does not work! + if (missing(size)) size <- nrow(x) # normal default does not work! - s <- sample.int (nrow (x@data), size = size, replace = replace, prob = prob) + s <- sample.int(nrow(x@data), size = size, replace = replace, prob = prob) - x [s] + x [s] } -.test (.sample) <- function (){ - context (".sample") +.test(.sample) <- function() { + context(".sample") - test_that ("defaults", { - tmp <- sample (flu) - expect_equal (tmp [order (tmp$c)], flu) + test_that("defaults", { + tmp <- sample(flu) + expect_equal(tmp [order(tmp$c)], flu) set.seed(101) - expect_equal (sample (flu)$c, c(0.05, 0.3, 0.1, 0.15, 0.25, 0.2)) + expect_equal(sample(flu)$c, c(0.05, 0.3, 0.1, 0.15, 0.25, 0.2)) }) test_that("size", { - expect_length (isample (flu, size = 3), 3L) + expect_length(isample(flu, size = 3), 3L) }) test_that("prob", { - expect_equal (isample (flu, size = 1, prob = c (1, rep (0, 5))), 1L) + expect_equal(isample(flu, size = 1, prob = c(1, rep(0, 5))), 1L) }) test_that("replace", { - expect_equal (isample (flu, size = 3, replace = TRUE, prob = c (1, rep (0, 5))), rep (1L, 3)) + expect_equal(isample(flu, size = 3, replace = TRUE, prob = c(1, rep(0, 5))), rep(1L, 3)) }) - } @@ -64,7 +63,7 @@ ##' plot (sample (flu, 3, replace = TRUE), col = "#0000FF80", add = TRUE, ##' lines.args = list (lwd = 2)); ##' -setMethod ("sample", signature = signature (x = "hyperSpec"), .sample) +setMethod("sample", signature = signature(x = "hyperSpec"), .sample) ##' \code{isample} returns an vector of indices, \code{sample} returns the ##' corresponding hyperSpec object. @@ -77,41 +76,39 @@ setMethod ("sample", signature = signature (x = "hyperSpec"), .sample) ##' isample (flu, 3, replace = TRUE) ##' isample (flu, 8, replace = TRUE) -isample <- function (x, size = nrow (x), replace = FALSE, prob = NULL) { - chk.hy (x) - validObject (x) +isample <- function(x, size = nrow(x), replace = FALSE, prob = NULL) { + chk.hy(x) + validObject(x) - sample.int (nrow (x), size = size, replace = replace, prob = prob) + sample.int(nrow(x), size = size, replace = replace, prob = prob) } -.test (isample) <- function (){ - context ("isample") +.test(isample) <- function() { + context("isample") - test_that ("defaults", { - expect_equal (sort (isample (flu)), 1 : nrow (flu)) + test_that("defaults", { + expect_equal(sort(isample(flu)), 1:nrow(flu)) set.seed(101) - expect_equal (isample (flu), c(1L, 6L, 2L, 3L, 5L, 4L)) - + expect_equal(isample(flu), c(1L, 6L, 2L, 3L, 5L, 4L)) }) test_that("size", { - expect_equal (nrow (sample (flu, size = 3)), 3L) + expect_equal(nrow(sample(flu, size = 3)), 3L) }) test_that("prob", { - expect_equal (sample (flu, size = 1, prob = c (1, rep (0, 5))), flu [1L]) + expect_equal(sample(flu, size = 1, prob = c(1, rep(0, 5))), flu [1L]) }) test_that("replace", { - expect_equal (sample (flu, size = 3, replace = TRUE, prob = c (1, rep (0, 5))), flu [rep (1L, 3)]) + expect_equal(sample(flu, size = 3, replace = TRUE, prob = c(1, rep(0, 5))), flu [rep(1L, 3)]) }) - } -.sample.data.frame <- function (x, size, replace = FALSE, prob = NULL, drop = FALSE) { - if (missing (size)) size <- nrow (x) - x [sample.int (nrow (x), size = size, replace = replace, prob = prob), , drop = drop] +.sample.data.frame <- function(x, size, replace = FALSE, prob = NULL, drop = FALSE) { + if (missing(size)) size <- nrow(x) + x [sample.int(nrow(x), size = size, replace = replace, prob = prob), , drop = drop] } ##' @rdname sample @@ -119,53 +116,54 @@ isample <- function (x, size = nrow (x), replace = FALSE, prob = NULL) { ##' @export ##' @examples ##' sample (cars, 2) -setMethod ("sample", signature = signature (x = "data.frame"), .sample.data.frame) - -.test (.sample.data.frame) <- function (){ - context ("sample data.frame") - test_that ("data.frame", { - set.seed (101) - tmp <- sample (iris) - expect_equal (rownames (tmp), c("73", "57", "95", "148", "61", "59", "99", "128", "131", "32", - "9", "96", "144", "98", "60", "147", "145", "14", "97", "45", - "117", "42", "64", "90", "43", "146", "125", "130", "58", "85", - "84", "133", "8", "72", "20", "6", "88", "39", "10", "74", "89", - "26", "140", "139", "37", "81", "135", "44", "138", "109", "108", - "3", "111", "116", "66", "65", "142", "28", "22", "80", "93", - "30", "25", "127", "103", "18", "50", "17", "86", "110", "34", - "150", "112", "106", "2", "15", "100", "62", "7", "52", "56", - "129", "101", "4", "143", "122", "79", "55", "149", "41", "114", - "12", "21", "94", "120", "113", "105", "54", "31", "77", "118", - "38", "136", "92", "19", "23", "16", "67", "134", "47", "35", - "69", "63", "75", "5", "121", "132", "126", "27", "48", "87", - "137", "13", "11", "102", "123", "24", "51", "46", "82", "40", - "115", "1", "119", "141", "33", "70", "68", "83", "91", "29", - "36", "78", "107", "76", "104", "71", "49", "53", "124")) - expect_equal(dim (tmp),dim (iris)) - expect_equal(tmp, iris [as.numeric (rownames (tmp)),]) +setMethod("sample", signature = signature(x = "data.frame"), .sample.data.frame) + +.test(.sample.data.frame) <- function() { + context("sample data.frame") + test_that("data.frame", { + set.seed(101) + tmp <- sample(iris) + expect_equal(rownames(tmp), c( + "73", "57", "95", "148", "61", "59", "99", "128", "131", "32", + "9", "96", "144", "98", "60", "147", "145", "14", "97", "45", + "117", "42", "64", "90", "43", "146", "125", "130", "58", "85", + "84", "133", "8", "72", "20", "6", "88", "39", "10", "74", "89", + "26", "140", "139", "37", "81", "135", "44", "138", "109", "108", + "3", "111", "116", "66", "65", "142", "28", "22", "80", "93", + "30", "25", "127", "103", "18", "50", "17", "86", "110", "34", + "150", "112", "106", "2", "15", "100", "62", "7", "52", "56", + "129", "101", "4", "143", "122", "79", "55", "149", "41", "114", + "12", "21", "94", "120", "113", "105", "54", "31", "77", "118", + "38", "136", "92", "19", "23", "16", "67", "134", "47", "35", + "69", "63", "75", "5", "121", "132", "126", "27", "48", "87", + "137", "13", "11", "102", "123", "24", "51", "46", "82", "40", + "115", "1", "119", "141", "33", "70", "68", "83", "91", "29", + "36", "78", "107", "76", "104", "71", "49", "53", "124" + )) + expect_equal(dim(tmp), dim(iris)) + expect_equal(tmp, iris [as.numeric(rownames(tmp)), ]) }) } -.sample.matrix <- function (x, size, replace = FALSE, prob = NULL, drop = FALSE) { - if (missing (size)) size <- nrow (x) - x [sample.int (nrow (x), size = size, replace = replace, prob = prob), , drop = drop] +.sample.matrix <- function(x, size, replace = FALSE, prob = NULL, drop = FALSE) { + if (missing(size)) size <- nrow(x) + x [sample.int(nrow(x), size = size, replace = replace, prob = prob), , drop = drop] } ##' @rdname sample ##' @export ##' @examples ##' sample (matrix (1:24, 6), 2) -setMethod ("sample", signature = signature (x = "matrix"), .sample.matrix) - -.test (.sample.matrix) <- function (){ - context (".sample.matrix") - test_that ("matrix", { - set.seed (101) - tmp <- sample (flu [[]]) - expect_equal(dim (tmp),dim (flu [[]])) - expect_equal(tmp [c(1L, 3L, 4L, 6L, 5L, 2L),], flu [[]]) +setMethod("sample", signature = signature(x = "matrix"), .sample.matrix) +.test(.sample.matrix) <- function() { + context(".sample.matrix") + test_that("matrix", { + set.seed(101) + tmp <- sample(flu [[]]) + expect_equal(dim(tmp), dim(flu [[]])) + expect_equal(tmp [c(1L, 3L, 4L, 6L, 5L, 2L), ], flu [[]]) }) } diff --git a/hyperSpec/R/scale.R b/hyperSpec/R/scale.R index a9ee13e44..d68fccc21 100644 --- a/hyperSpec/R/scale.R +++ b/hyperSpec/R/scale.R @@ -3,7 +3,7 @@ ##' \code{link[base]{scale}}s the spectra matrix. \code{scale (x, scale = FALSE)} centers the data. ##' ##' Package \code{scale} provides a fast alternative for \code{base::\link[base]{scale}} -##' +##' ##' @name scale,hyperSpec-method ##' @rdname scale ##' @aliases scale scale-methods scale,hyperSpec-method @@ -40,15 +40,17 @@ ##' tmp <- sweep (chondro, 1, mean, `/`) ##' plot (tmp, "spcmeansd") ##' tmp <- scale (tmp, center = quantile (tmp, .05), scale = FALSE) -##' -setMethod ("scale", signature = signature (x = "hyperSpec"), - function (x, center = TRUE, scale = TRUE){ - validObject (x) +##' +setMethod("scale", + signature = signature(x = "hyperSpec"), + function(x, center = TRUE, scale = TRUE) { + validObject(x) + + if (!is.logical(center)) center <- as.matrix(center) + if (!is.logical(scale)) scale <- as.matrix(scale) - if (! is.logical (center)) center <- as.matrix (center) - if (! is.logical (scale)) scale <- as.matrix (scale) - - x@data$spc <- scale (x@data$spc, center, scale) + x@data$spc <- scale(x@data$spc, center, scale) - x -}) + x + } +) diff --git a/hyperSpec/R/seq.R b/hyperSpec/R/seq.R index a855b6f73..dd2d6c994 100644 --- a/hyperSpec/R/seq.R +++ b/hyperSpec/R/seq.R @@ -1,16 +1,16 @@ ##' Sequence generation along spectra or wavelengths ##' This function generates sequences along the spectra (rows) or wavelengths of hyperSpec objects. -##' +##' ##' Note that \code{\link{wl2i}} generates sequences of indices along the wavelength axis. -##' +##' ##' \code{seq} had to be implemented as S3 method as the generic has only \dots{} arguments (on which ##' no dispatch with differing types is possible). -##' +##' ##' \code{\link[base]{seq_along}} is not generic, but returns a sequence of the \code{length} of the ##' object. As hyperSpec provides a Method \code{\link{length}}, it can be used. The result is a ##' sequence of indices for the spectra. -##' +##' ##' @aliases seq seq,hyperSpec-method ##' @param x the hyperSpec object ##' @param from,to arguments handed to \code{\link[base]{seq.int}} @@ -19,56 +19,59 @@ ##' @return a numeric or hyperSpec object, depending on \code{index}. ##' @author C. Beleites ##' @seealso \code{\link{wl2i}} to construct sequences of wavelength indices. -##' +##' ##' \code{\link[base]{seq}} ##' @rdname seq ##' @export ##' @method seq hyperSpec ##' @keywords manip ##' @examples -##' +##' ##' seq (flu, index = TRUE) ##' seq_along (flu) -##' seq (flu, length.out = 3, index = TRUE) # return value is numeric, not integer! -##' seq (flu, by = 2, index = TRUE) # return value is numeric, not integer! -##' -##' plot (flu, col = "darkgray") +##' seq (flu, length.out = 3, index = TRUE) # return value is numeric, not integer! +##' seq (flu, by = 2, index = TRUE) # return value is numeric, not integer! +##' +##' plot (flu, col = "darkgray") ##' plot (seq (flu, by = 2), add = TRUE, col= "red") ##' plot (seq (flu, length.out = 2), add = TRUE, col= "blue") -##' +##' ### needs to be an S3 function as S4 ... dispatch has to have the same signature for all parameters -seq.hyperSpec <- function (x, from = 1, to = nrow (x), - ..., index = FALSE){ - validObject (x) +seq.hyperSpec <- function(x, from = 1, to = nrow(x), + ..., index = FALSE) { + validObject(x) - s <- seq (from = from, to = to, ...) + s <- seq(from = from, to = to, ...) - if (index) + if (index) { s - else { - .extract (x, i = s) - } + } else { + .extract(x, i = s) + } } ## internal abbreviation function -row.seq <- function (x, from = 1, to = nrow (x@data), ...){ - if (nrow (x@data) == 0) - integer (0) - else - seq (from = from, to = to, ...) +row.seq <- function(x, from = 1, to = nrow(x@data), ...) { + if (nrow(x@data) == 0) { + integer(0) + } else { + seq(from = from, to = to, ...) + } } -col.seq <- function (x, from = 1, to = ncol (x@data), ...){ - if (ncol (x@data) == 0) - integer (0) - else - seq (from = from, to = to, ...) +col.seq <- function(x, from = 1, to = ncol(x@data), ...) { + if (ncol(x@data) == 0) { + integer(0) + } else { + seq(from = from, to = to, ...) + } } -wl.seq <- function (x, from = 1, to = ncol (x@data$spc), ...){ - if (ncol (x@data$spc) == 0) - integer (0) - else - seq (from = from, to = to, ...) +wl.seq <- function(x, from = 1, to = ncol(x@data$spc), ...) { + if (ncol(x@data$spc) == 0) { + integer(0) + } else { + seq(from = from, to = to, ...) + } } diff --git a/hyperSpec/R/show.R b/hyperSpec/R/show.R index 31704ba85..941ce4af3 100644 --- a/hyperSpec/R/show.R +++ b/hyperSpec/R/show.R @@ -11,57 +11,71 @@ ##' printed ##' @return \code{as.character} returns a character vector fit to be printed by ##' \code{cat} with \code{sep = "\n"}. -##' +##' ##' @seealso \code{\link[base]{as.character}} ##' @include paste.row.R ##' @export -setMethod ("as.character", signature = signature (x = "hyperSpec"), - function (x, digits = getOption ("digits"), range = TRUE, - max.print = 5, shorten.to = c(2,1)){ - ## input checking - validObject (x) +setMethod("as.character", + signature = signature(x = "hyperSpec"), + function(x, digits = getOption("digits"), range = TRUE, + max.print = 5, shorten.to = c(2, 1)) { + ## input checking + validObject(x) - if (is.null (max.print)) - max.print <- getOption ("max.print") + if (is.null(max.print)) { + max.print <- getOption("max.print") + } - if ((length (max.print) != 1) | ! is.numeric (max.print)) - stop ("max.print needs to be a number") - if ((length (shorten.to) < 1) |(length (shorten.to) > 2) | ! is.numeric (shorten.to)) - stop ("shorten.to needs to be a numeric vector with length 1 or 2") - if (sum (shorten.to) > max.print) - stop ("sum (shorten.to) > max.print: this does not make sense.") + if ((length(max.print) != 1) | !is.numeric(max.print)) { + stop("max.print needs to be a number") + } + if ((length(shorten.to) < 1) | (length(shorten.to) > 2) | !is.numeric(shorten.to)) { + stop("shorten.to needs to be a numeric vector with length 1 or 2") + } + if (sum(shorten.to) > max.print) { + stop("sum (shorten.to) > max.print: this does not make sense.") + } - ## printing information - chr <- c("hyperSpec object", - paste (" ", nrow (x), "spectra"), - paste (" ", ncol (x), "data columns"), - paste (" ", nwl (x), "data points / spectrum") - ) + ## printing information + chr <- c( + "hyperSpec object", + paste(" ", nrow(x), "spectra"), + paste(" ", ncol(x), "data columns"), + paste(" ", nwl(x), "data points / spectrum") + ) - chr <- c (chr, .paste.row (x@wavelength, x@label$.wavelength, "wavelength", - ins = 0, val = TRUE, range = FALSE, - shorten.to = shorten.to, max.print = max.print)) - - n.cols <- ncol (x@data) + chr <- c(chr, .paste.row(x@wavelength, x@label$.wavelength, "wavelength", + ins = 0, val = TRUE, range = FALSE, + shorten.to = shorten.to, max.print = max.print + )) - chr <- c(chr, paste ("data: ", " (", nrow(x@data), " rows x ", n.cols, - " columns)", sep = "")) + n.cols <- ncol(x@data) - if (n.cols > 0) - for (n in names (x@data)) - chr <- c(chr, .paste.row (x@data[[n]], x@label[[n]], n, ins = 3, - i = match (n, names (x@data)), - val = TRUE, range = range, - shorten.to = shorten.to, max.print = max.print)) - - chr -}) + chr <- c(chr, paste("data: ", " (", nrow(x@data), " rows x ", n.cols, + " columns)", + sep = "" + )) + + if (n.cols > 0) { + for (n in names(x@data)) { + chr <- c(chr, .paste.row(x@data[[n]], x@label[[n]], n, + ins = 3, + i = match(n, names(x@data)), + val = TRUE, range = range, + shorten.to = shorten.to, max.print = max.print + )) + } + } + + chr + } +) ##' Convert a hyperSpec object to character strings for Display ##' \code{print}, \code{show}, and \code{summary} show the result of ##' \code{as.character}. -##' +##' ##' \code{print}, \code{show}, and \code{summary} differ only in the defaults. ##' \code{show} displays the range of values instead, ##' @name show @@ -72,18 +86,18 @@ setMethod ("as.character", signature = signature (x = "hyperSpec"), ##' @keywords methods print ##' @export ##' @examples -##' +##' ##' chondro -##' +##' ##' show (chondro) -##' +##' ##' summary (chondro) -##' +##' ##' print (chondro, range = TRUE) -##' -setMethod ("show", signature = signature (object = "hyperSpec"), function (object){ - print (object, range = TRUE) - invisible (NULL) +##' +setMethod("show", signature = signature(object = "hyperSpec"), function(object) { + print(object, range = TRUE) + invisible(NULL) }) ##' @@ -95,23 +109,25 @@ setMethod ("show", signature = signature (object = "hyperSpec"), function (objec ##' @return \code{print} invisibly returns \code{x} after printing, \code{show} returns ##' an invisible \code{NULL}. ##' @rdname show -##' @export +##' @export ##' @seealso \code{\link[base]{print}} -setMethod ("print", signature = signature (x = "hyperSpec"), function (x, range = FALSE, ...){ - validObject (x) - cat (as.character (x, range = FALSE, ...), sep ="\n") - invisible (x) +setMethod("print", signature = signature(x = "hyperSpec"), function(x, range = FALSE, ...) { + validObject(x) + cat(as.character(x, range = FALSE, ...), sep = "\n") + invisible(x) }) -##' +##' ##' \code{summary} displays the logbook in addition. -##' +##' ##' @aliases summary summary,hyperSpec-method ##' @seealso \code{\link[base]{summary}} ##' @export ##' @rdname show -setMethod ("summary", signature = signature (object = "hyperSpec"), - function (object, ...){ - print (object, ...) -}) +setMethod("summary", + signature = signature(object = "hyperSpec"), + function(object, ...) { + print(object, ...) + } +) diff --git a/hyperSpec/R/spc.NA.approx.R b/hyperSpec/R/spc.NA.approx.R index e3cbe60a1..0b5cffc25 100644 --- a/hyperSpec/R/spc.NA.approx.R +++ b/hyperSpec/R/spc.NA.approx.R @@ -18,78 +18,89 @@ ##' spc.NA.approx (fluNA [,, min ~ 410], debuglevel = 1) ##' spc.NA.approx (fluNA [1,, min ~ 410], debuglevel = 2) ##' spc.NA.approx (fluNA [4,, min ~ 410], neighbours = 3, df = 4, debuglevel = 2) -spc.NA.approx <- function (spc, neighbours = 1, w = rep (1, 2 * neighbours), df = 1 + .Machine$double.eps, spar = NULL, - debuglevel = hy.getOption("debuglevel")){ - chk.hy (spc) - validObject (spc) - - all.na <- which (apply (is.na (spc@data$spc), 1, all)) - if (length (all.na) > 0){ - warning ("Spectra containing only NAs found. They will not be approximated.") +spc.NA.approx <- function(spc, neighbours = 1, w = rep(1, 2 * neighbours), df = 1 + .Machine$double.eps, spar = NULL, + debuglevel = hy.getOption("debuglevel")) { + chk.hy(spc) + validObject(spc) + + all.na <- which(apply(is.na(spc@data$spc), 1, all)) + if (length(all.na) > 0) { + warning("Spectra containing only NAs found. They will not be approximated.") } - stopifnot (neighbours >= 1L) + stopifnot(neighbours >= 1L) - ispc <- which (is.na (spc@data$spc), arr.ind = TRUE) + ispc <- which(is.na(spc@data$spc), arr.ind = TRUE) - ispc <- setdiff (unique (ispc[,"row"]), all.na) + ispc <- setdiff(unique(ispc[, "row"]), all.na) - if (debuglevel == 1L) - plot (spc [ispc], col = "gray") + if (debuglevel == 1L) { + plot(spc [ispc], col = "gray") + } - for (i in ispc){ - if (debuglevel == 2L) - plot (spc [i], col = "gray") + for (i in ispc) { + if (debuglevel == 2L) { + plot(spc [i], col = "gray") + } - nas <- which (is.na (spc@data$spc[i,])) + nas <- which(is.na(spc@data$spc[i, ])) - start <- c (0, which (diff (nas) > 1)) + 1 - end <- c (start [-1] - 1, length (nas)) + start <- c(0, which(diff(nas) > 1)) + 1 + end <- c(start [-1] - 1, length(nas)) - for (j in seq (along = start)) { - pts <- nas [start [j]] : nas [end [j]] + for (j in seq(along = start)) { + pts <- nas [start [j]]:nas [end [j]] - xneighbours <- c ( -(1 : neighbours) + nas [start [j]], - (1 : neighbours) + nas [end [j]]) - mask <- xneighbours > 0 & xneighbours <= nwl (spc) + xneighbours <- c( + -(1:neighbours) + nas [start [j]], + (1:neighbours) + nas [end [j]] + ) + mask <- xneighbours > 0 & xneighbours <= nwl(spc) xneighbours <- xneighbours [mask] - if (sum (mask) == 0) {# should not happen as all NA-only spectra were excluded - stop ("No data to interpolate from.") - - } else if (sum (mask) == 1) { + if (sum(mask) == 0) { # should not happen as all NA-only spectra were excluded + stop("No data to interpolate from.") + } else if (sum(mask) == 1) { spc@data$spc [i, pts] <- spc@data$spc [i, xneighbours] - if (debuglevel == 2L) - points (x = spc@wavelength [xneighbours], y = spc@data$spc [i, xneighbours]) - - } else if (sum (mask) < 4) { # old behaviour using linear interpolation - spc@data$spc [i, pts] <- approx (x = spc@wavelength [xneighbours], - y = spc@data$spc [i, xneighbours], - xout = spc@wavelength [pts], - method = "linear", - rule = 2)$y - if (debuglevel == 2L) - lines (x = spc@wavelength [xneighbours], y = spc@data$spc [i, xneighbours]) - } else {# more neighbours: interpolation spline - spline <- smooth.spline(x = spc@wavelength [xneighbours], - y = spc@data$spc [i, xneighbours], - w = w [mask], df = df, spar = spar, - cv = FALSE, all.knots = TRUE, keep.data = FALSE) - spc@data$spc [i, pts] <- predict (spline, x = spc@wavelength [pts])$y - if (debuglevel == 2L) { - wlr <- seq (from = min (spc@wavelength [xneighbours]), - to = max (spc@wavelength [xneighbours]), - length.out = 100) - lines (predict (spline, wlr)) + points(x = spc@wavelength [xneighbours], y = spc@data$spc [i, xneighbours]) + } + } else if (sum(mask) < 4) { # old behaviour using linear interpolation + spc@data$spc [i, pts] <- approx( + x = spc@wavelength [xneighbours], + y = spc@data$spc [i, xneighbours], + xout = spc@wavelength [pts], + method = "linear", + rule = 2 + )$y + if (debuglevel == 2L) { + lines(x = spc@wavelength [xneighbours], y = spc@data$spc [i, xneighbours]) } + } else { # more neighbours: interpolation spline + spline <- smooth.spline( + x = spc@wavelength [xneighbours], + y = spc@data$spc [i, xneighbours], + w = w [mask], df = df, spar = spar, + cv = FALSE, all.knots = TRUE, keep.data = FALSE + ) + spc@data$spc [i, pts] <- predict(spline, x = spc@wavelength [pts])$y + if (debuglevel == 2L) { + wlr <- seq( + from = min(spc@wavelength [xneighbours]), + to = max(spc@wavelength [xneighbours]), + length.out = 100 + ) + lines(predict(spline, wlr)) + } } - if (debuglevel == 2L) - plot (spc [i,,xneighbours, wl.index = TRUE], add = TRUE, lines.args = list (type = "p", pch = 20), col = 1) - if (debuglevel >= 1L) - plot (spc [i,,pts, wl.index = TRUE], add = TRUE, lines.args = list (type = "p", pch = 20), col = 2) + if (debuglevel == 2L) { + plot(spc [i, , xneighbours, wl.index = TRUE], add = TRUE, lines.args = list(type = "p", pch = 20), col = 1) + } + if (debuglevel >= 1L) { + plot(spc [i, , pts, wl.index = TRUE], add = TRUE, lines.args = list(type = "p", pch = 20), col = 2) + } } } @@ -98,45 +109,45 @@ spc.NA.approx <- function (spc, neighbours = 1, w = rep (1, 2 * neighbours), df ##' @rdname spc.NA.approx ##' @param ... ignored -spc.NA.linapprox <- function (...){ - stop ("spc.NA.linapprox has been renamed to spc.NA.approx") +spc.NA.linapprox <- function(...) { + stop("spc.NA.linapprox has been renamed to spc.NA.approx") } -.test (spc.NA.approx) <- function (){ - context ("spc.NA.approx") +.test(spc.NA.approx) <- function() { + context("spc.NA.approx") - test_that ("linear interpolation", { - tmp <- spc.NA.approx (fluNA [-2,, min ~ 410]) - expect_equivalent(as.numeric (tmp [[,, 406]]), rowMeans (fluNA [[-2,, 405.5 ~ 406.5]], na.rm = TRUE)) + test_that("linear interpolation", { + tmp <- spc.NA.approx(fluNA [-2, , min ~ 410]) + expect_equivalent(as.numeric(tmp [[, , 406]]), rowMeans(fluNA [[-2, , 405.5 ~ 406.5]], na.rm = TRUE)) }) - test_that ("spline interpolation", { - tmp <- spc.NA.approx (fluNA [-2,, min ~ 410], neighbours = 2) - expect_true (all (abs (tmp [[,, 406]] - rowMeans (fluNA [[-2,, 405 ~ 407]], na.rm = TRUE)) <= 1e-5)) + test_that("spline interpolation", { + tmp <- spc.NA.approx(fluNA [-2, , min ~ 410], neighbours = 2) + expect_true(all(abs(tmp [[, , 406]] - rowMeans(fluNA [[-2, , 405 ~ 407]], na.rm = TRUE)) <= 1e-5)) # version on CRAN throws error on `expect_equal (tolerance = 1e-5)` # TODO => change back ASAP }) - test_that ("edge treatment and debuglevel", { - ranges <- list (405 ~ 407, 405.5 ~ 406.5, 405.6 ~ 406) - for (d in 0 : 2) { + test_that("edge treatment and debuglevel", { + ranges <- list(405 ~ 407, 405.5 ~ 406.5, 405.6 ~ 406) + for (d in 0:2) { for (r in ranges) { - tmp <- spc.NA.approx (fluNA [-2,, r], neighbours = 3, debuglevel = d) + tmp <- spc.NA.approx(fluNA [-2, , r], neighbours = 3, debuglevel = d) # expect_equal (round (as.numeric (tmp [[,, 406]]), 5), # round (rowMeans (fluNA [[-2,, r]], na.rm = TRUE), 5), # tolerance = 1e-5, # info = paste0 ("debuglevel = ", d, ", range = ", paste0 (r [c (2, 1, 3)], collapse = ""))) # version on CRAN throws error on `expect_equal (tolerance = 1e-5)` # TODO => change back ASAP - expect_true (all (abs (tmp [[,, 406]] - rowMeans (fluNA [[-2,, r]], na.rm = TRUE)) <= 1e-5), - info = paste0 ("debuglevel = ", d, ", range = ", paste0 (r [c (2, 1, 3)], collapse = ""))) + expect_true(all(abs(tmp [[, , 406]] - rowMeans(fluNA [[-2, , r]], na.rm = TRUE)) <= 1e-5), + info = paste0("debuglevel = ", d, ", range = ", paste0(r [c(2, 1, 3)], collapse = "")) + ) } } }) - test_that ("spc.NA.linapprox deprecated",{ - expect_error(spc.NA.linapprox (fluNA)) + test_that("spc.NA.linapprox deprecated", { + expect_error(spc.NA.linapprox(fluNA)) }) - } diff --git a/hyperSpec/R/spc.bin.R b/hyperSpec/R/spc.bin.R index 73760db8d..56a9a2494 100644 --- a/hyperSpec/R/spc.bin.R +++ b/hyperSpec/R/spc.bin.R @@ -2,22 +2,22 @@ ##' In order to reduce the spectral resolution and thus gain signal to noise ##' ratio or to reduce the dimensionality of the spectral data set, the ##' spectral resolution can be reduced. -##' +##' ##' The mean of every \code{by} data points in the spectra is calculated. -##' +##' ##' Using \code{na.rm = TRUE} always takes about twice as long as \code{na.rm = FALSE}. -##' +##' ##' If the spectra matrix does not contain too many \code{NA}s, \code{na.rm = 2} is faster than ##' \code{na.rm = TRUE}. -##' +##' ##' @param spc the \code{hyperSpec} object ##' @param by reduction factor ##' @param na.rm decides about the treatment of \code{NA}s: -##' +##' ##' if \code{FALSE} or \code{0}, the binning is done using \code{na.rm = FALSE} -##' +##' ##' if \code{TRUE} or \code{1}, the binning is done using \code{na.rm = TRUE} -##' +##' ##' if \code{2}, the binning is done using \code{na.rm = FALSE}, and resulting \code{NA}s are ##' corrected with \code{mean(\dots{}, na.rm = TRUE)}. ##' @param ... ignored @@ -27,53 +27,53 @@ ##' @author C. Beleites ##' @keywords manip datagen ##' @examples -##' +##' ##' spc <- spc.bin (flu, 5) -##' +##' ##' plot (flu[1,,425:475]) ##' plot (spc[1,,425:475], add = TRUE, col = "blue") -##' +##' ##' nwl (flu) ##' nwl (spc) -##' -spc.bin <- function (spc, by = stop ("reduction factor needed"), na.rm = TRUE, ...) { - chk.hy (spc) - validObject (spc) +##' +spc.bin <- function(spc, by = stop("reduction factor needed"), na.rm = TRUE, ...) { + chk.hy(spc) + validObject(spc) - n <- ceiling (nwl (spc) / by) + n <- ceiling(nwl(spc) / by) - small <- nwl (spc) %% by - if (small != 0) - warning (paste (c("Last data point averages only ", small, " points."))) + small <- nwl(spc) %% by + if (small != 0) { + warning(paste(c("Last data point averages only ", small, " points."))) + } - bin <- rep (seq_len (n), each = by, length.out = nwl (spc)) + bin <- rep(seq_len(n), each = by, length.out = nwl(spc)) - na <- is.na (spc@data$spc) + na <- is.na(spc@data$spc) - if ((na.rm > 0) && any (na)) { + if ((na.rm > 0) && any(na)) { if (na.rm == 1) { - na <- apply (!na, 1, tapply, bin, sum, na.rm = FALSE) - spc@data$spc <- t (apply (spc@data$spc, 1, tapply, bin, sum, na.rm = TRUE) / na) + na <- apply(!na, 1, tapply, bin, sum, na.rm = FALSE) + spc@data$spc <- t(apply(spc@data$spc, 1, tapply, bin, sum, na.rm = TRUE) / na) } else { # faster for small numbers of NA - tmp <- t (apply (spc@data$spc, 1, tapply, bin, sum, na.rm = FALSE)) - tmp <- sweep (tmp, 2, rle (bin)$lengths, "/") + tmp <- t(apply(spc@data$spc, 1, tapply, bin, sum, na.rm = FALSE)) + tmp <- sweep(tmp, 2, rle(bin)$lengths, "/") - na <- which (is.na (tmp), arr.ind = TRUE) - bin <- split (wl.seq (spc), bin) + na <- which(is.na(tmp), arr.ind = TRUE) + bin <- split(wl.seq(spc), bin) - for (i in seq_len (nrow (na))){ - tmp [na [i, 1], na [i, 2]] <- mean (spc@data$spc [na [i, 1], bin [[na[i, 2]]]], na.rm = TRUE) + for (i in seq_len(nrow(na))) { + tmp [na [i, 1], na [i, 2]] <- mean(spc@data$spc [na [i, 1], bin [[na[i, 2]]]], na.rm = TRUE) } spc@data$spc <- tmp } - } else { # considerably faster - spc@data$spc <- t (apply (spc@data$spc, 1, tapply, bin, sum, na.rm = FALSE)) - spc@data$spc <- sweep (spc@data$spc, 2, rle (bin)$lengths, "/") + } else { # considerably faster + spc@data$spc <- t(apply(spc@data$spc, 1, tapply, bin, sum, na.rm = FALSE)) + spc@data$spc <- sweep(spc@data$spc, 2, rle(bin)$lengths, "/") } - .wl (spc) <- as.numeric (tapply (spc@wavelength, bin, mean, na.rm = na.rm > 0)) + .wl(spc) <- as.numeric(tapply(spc@wavelength, bin, mean, na.rm = na.rm > 0)) - validObject (spc) + validObject(spc) spc } - diff --git a/hyperSpec/R/spc.fit.poly.R b/hyperSpec/R/spc.fit.poly.R index b996a93f2..735bbd894 100644 --- a/hyperSpec/R/spc.fit.poly.R +++ b/hyperSpec/R/spc.fit.poly.R @@ -34,44 +34,48 @@ ##' baselines <- spc.fit.poly(spc [,, c (625 ~ 640, 1785 ~ 1800)], spc) ##' plot(spc - baselines) ##' -spc.fit.poly <- function (fit.to, apply.to = NULL, poly.order = 1, offset.wl = ! (is.null (apply.to))){ - chk.hy (fit.to) - if (! is.null (apply.to)) - chk.hy (apply.to) +spc.fit.poly <- function(fit.to, apply.to = NULL, poly.order = 1, offset.wl = !(is.null(apply.to))) { + chk.hy(fit.to) + if (!is.null(apply.to)) { + chk.hy(apply.to) + } - validObject (fit.to) - validObject (apply.to) + validObject(fit.to) + validObject(apply.to) x <- fit.to@wavelength - if (offset.wl){ - minx <- min (x) - x <- x - min (x) + if (offset.wl) { + minx <- min(x) + x <- x - min(x) } else { minx <- 0 } - x <- vanderMonde (x, poly.order) # Vandermonde matrix of x - - p <- apply (fit.to, 1, - function (y, x){ - x <- x [! is.na (y),,drop = FALSE] - y <- y [! is.na (y)] - qr.solve (x, y) - }, - x) + x <- vanderMonde(x, poly.order) # Vandermonde matrix of x - if (is.null (apply.to)){ - colnames (p@data$spc) <- paste0 ("(x - minx)^", 0 : poly.order) + p <- apply( + fit.to, 1, + function(y, x) { + x <- x [!is.na(y), , drop = FALSE] + y <- y [!is.na(y)] + qr.solve(x, y) + }, + x + ) - p$min.x = minx - return (p) + if (is.null(apply.to)) { + colnames(p@data$spc) <- paste0("(x - minx)^", 0:poly.order) + p$min.x <- minx + return(p) } else { wl <- apply.to@wavelength - minx - x <- vanderMonde(wl, poly.order) # Vandermonde matrix of x - apply.to@data$spc <- I (t (apply (p[[]], 1, function (p, x) {x %*% p}, x))) + x <- vanderMonde(wl, poly.order) # Vandermonde matrix of x + apply.to@data$spc <- I(t(apply(p[[]], 1, function(p, x) { + x %*% p + }, x))) validObject(apply.to) @@ -79,40 +83,40 @@ spc.fit.poly <- function (fit.to, apply.to = NULL, poly.order = 1, offset.wl = ! } } -.test (spc.fit.poly) <- function (){ - context ("spc.fit.poly") +.test(spc.fit.poly) <- function() { + context("spc.fit.poly") - test_that("no normalization", - bl.nonorm <- spc.fit.poly (flu, flu, poly.order = 3, offset.wl = FALSE) + test_that( + "no normalization", + bl.nonorm <- spc.fit.poly(flu, flu, poly.order = 3, offset.wl = FALSE) ) # test effect of wavelength axis normalization # was issue 1 on github tmp <- flu - wl (tmp) <- wl (tmp) + 1e4 + wl(tmp) <- wl(tmp) + 1e4 test_that("normalization/offset wavelengths", { - expect_error (spc.fit.poly(tmp, poly.order = 3, offset.wl = FALSE)) + expect_error(spc.fit.poly(tmp, poly.order = 3, offset.wl = FALSE)) bl.1e4 <- spc.fit.poly(tmp, tmp, poly.order = 3, offset.wl = TRUE) - bl.nonorm <- spc.fit.poly (flu, flu, poly.order = 3, offset.wl = FALSE) - expect_equal (bl.nonorm [[]], bl.1e4 [[]]) + bl.nonorm <- spc.fit.poly(flu, flu, poly.order = 3, offset.wl = FALSE) + expect_equal(bl.nonorm [[]], bl.1e4 [[]]) }) - + test_that("spectrum containing NA", { tmp <- chondro [1] - tmp [[,, 1600]] <- NA - - coefs <- spc.fit.poly (tmp, apply.to = NULL) [[]] + tmp [[, , 1600]] <- NA + + coefs <- spc.fit.poly(tmp, apply.to = NULL) [[]] expect_equal( coefs, - spc.fit.poly(chondro [1,, !is.na (tmp)], apply.to = NULL) [[]] + spc.fit.poly(chondro [1, , !is.na(tmp)], apply.to = NULL) [[]] ) - - ## bug was: all coefficients were silently 0 - expect_true (all (abs (coefs) > sqrt (.Machine$double.eps))) + + ## bug was: all coefficients were silently 0 + expect_true(all(abs(coefs) > sqrt(.Machine$double.eps))) }) - } ##' @@ -123,12 +127,12 @@ spc.fit.poly <- function (fit.to, apply.to = NULL, poly.order = 1, offset.wl = ! ##' @param npts.min minimal number of points used for fitting the polynomial ##' @param noise noise level to be considered during the fit. It may be given ##' as one value for all the spectra, or for each spectrum separately. -##' @param max.iter stop at the latest after so many iterations. -##' @param stop.on.increase additional stopping rule: stop if the number of support points would increase, +##' @param max.iter stop at the latest after so many iterations. +##' @param stop.on.increase additional stopping rule: stop if the number of support points would increase, ##' regardless whether npts.min was reached or not. ##' @param debuglevel additional output: -##' \code{1} shows \code{npts.min}, -##' \code{2} plots support points for the final baseline of 1st spectrum, +##' \code{1} shows \code{npts.min}, +##' \code{2} plots support points for the final baseline of 1st spectrum, ##' \code{3} plots support points for 1st spectrum, ##' \code{4} plots support points for all spectra. ##' @seealso see \code{\link[hyperSpec]{options}} for more on \code{debuglevel} @@ -141,157 +145,164 @@ spc.fit.poly <- function (fit.to, apply.to = NULL, poly.order = 1, offset.wl = ! ##' spc.fit.poly.below(chondro [1:3], debuglevel = 1) ##' spc.fit.poly.below(chondro [1:3], debuglevel = 2) ##' spc.fit.poly.below(chondro [1:3], debuglevel = 3, noise = sqrt (rowMeans (chondro [[1:3]]))) -##' -spc.fit.poly.below <- function (fit.to, apply.to = fit.to, poly.order = 1, - npts.min = max (round (nwl (fit.to) * 0.05), 3 * (poly.order + 1)), - noise = 0, offset.wl = FALSE, max.iter = nwl (fit.to), - stop.on.increase = FALSE, - debuglevel = hy.getOption("debuglevel")){ +##' +spc.fit.poly.below <- function(fit.to, apply.to = fit.to, poly.order = 1, + npts.min = max(round(nwl(fit.to) * 0.05), 3 * (poly.order + 1)), + noise = 0, offset.wl = FALSE, max.iter = nwl(fit.to), + stop.on.increase = FALSE, + debuglevel = hy.getOption("debuglevel")) { ## for debuglevel >= 2L cols <- matlab.dark.palette(max.iter) - - chk.hy (fit.to) - if (! is.null (apply.to)) - chk.hy (apply.to) - validObject (fit.to) - validObject (apply.to) + chk.hy(fit.to) + if (!is.null(apply.to)) { + chk.hy(apply.to) + } + + validObject(fit.to) + validObject(apply.to) - if (missing (npts.min) && debuglevel >= 1L) - message ("Fitting with npts.min = ", npts.min, "\n") + if (missing(npts.min) && debuglevel >= 1L) { + message("Fitting with npts.min = ", npts.min, "\n") + } - if (npts.min <= poly.order){ + if (npts.min <= poly.order) { npts.min <- poly.order + 1 - warning (paste ("npts.min too small: adjusted to", npts.min)) + warning(paste("npts.min too small: adjusted to", npts.min)) } - if (length (noise) == 1) - noise <- rep (noise, nrow (fit.to)) + if (length(noise) == 1) { + noise <- rep(noise, nrow(fit.to)) + } x <- fit.to@wavelength - if (offset.wl){ - minx <- min (x) - x <- x - min (x) + if (offset.wl) { + minx <- min(x) + x <- x - min(x) } else { minx <- 0 } - vdm <- vanderMonde (x, poly.order) - y <- t (fit.to [[]]) + vdm <- vanderMonde(x, poly.order) + y <- t(fit.to [[]]) - p <- matrix (nrow = nrow(fit.to) , ncol = poly.order + 1) - for (i in row.seq (fit.to)){ - use.old <- logical (nwl (fit.to)) - use <- !is.na (y [, i]) + p <- matrix(nrow = nrow(fit.to), ncol = poly.order + 1) + for (i in row.seq(fit.to)) { + use.old <- logical(nwl(fit.to)) + use <- !is.na(y [, i]) if (debuglevel %in% c(2L, 3L) && i == 1L || debuglevel >= 4L) { - plot(fit.to [i], title.args = list (main = paste ("spectrum", i))) - message ("start: ", sum (use, na.rm=TRUE), " support points") + plot(fit.to [i], title.args = list(main = paste("spectrum", i))) + message("start: ", sum(use, na.rm = TRUE), " support points") } - for (iter in 1 : max.iter) { - p[i,] <- qr.solve (vdm[use,], y[use, i]) - bl <- vdm %*% p [i,] + for (iter in 1:max.iter) { + p[i, ] <- qr.solve(vdm[use, ], y[use, i]) + bl <- vdm %*% p [i, ] use.old <- use - use <- y[, i] < bl + noise [i] & !is.na (y [, i]) + use <- y[, i] < bl + noise [i] & !is.na(y [, i]) if (debuglevel == 3L && i == 1L || debuglevel >= 4L) { - plot (fit.to[i,, use], add = TRUE, lines.args = list (pch = 20, type = "p"), col= cols [iter]) - lines (fit.to@wavelength, bl, col = cols [iter]) - lines (fit.to@wavelength, bl + noise, col = cols [iter], lty = 2) - message ("Iteration ", iter, ": ", sum (use, na.rm=TRUE), " support points") + plot(fit.to[i, , use], add = TRUE, lines.args = list(pch = 20, type = "p"), col = cols [iter]) + lines(fit.to@wavelength, bl, col = cols [iter]) + lines(fit.to@wavelength, bl + noise, col = cols [iter], lty = 2) + message("Iteration ", iter, ": ", sum(use, na.rm = TRUE), " support points") } - if ((sum (use, na.rm=TRUE) < npts.min) || all (use == use.old, na.rm = TRUE)) + if ((sum(use, na.rm = TRUE) < npts.min) || all(use == use.old, na.rm = TRUE)) { break - - if (sum (use, na.rm=TRUE) > sum (use.old, na.rm=TRUE) && stop.on.increase){ - warning("Iteration ", iter, ": Number of support points is about to increase again. Stopping with ", - sum (use.old, na.rm=TRUE), " support points, but this is a local minimum only.") + } + + if (sum(use, na.rm = TRUE) > sum(use.old, na.rm = TRUE) && stop.on.increase) { + warning( + "Iteration ", iter, ": Number of support points is about to increase again. Stopping with ", + sum(use.old, na.rm = TRUE), " support points, but this is a local minimum only." + ) break } } - - if (iter == max.iter) - if ((sum (use.old, na.rm = TRUE) == npts.min) && - ! all (use == use.old, na.rm = TRUE) && - ! sum (use, na.rm = TRUE) < npts.min){ + + if (iter == max.iter) { + if ((sum(use.old, na.rm = TRUE) == npts.min) && + !all(use == use.old, na.rm = TRUE) && + !sum(use, na.rm = TRUE) < npts.min) { warning("Reached npts.min, but the solution is not stable. Stopped after ", iter, " iterations.") - } else if (sum (use, na.rm=TRUE) >= npts.min) { - warning ("Stopped after ", iter, " iterations with ", sum (use.old, na.rm = TRUE), " support points.") + } else if (sum(use, na.rm = TRUE) >= npts.min) { + warning("Stopped after ", iter, " iterations with ", sum(use.old, na.rm = TRUE), " support points.") } + } - if (debuglevel >= 1L) - message (sprintf ("spectrum % 6i: % 5i support points, noise = %0.1f, %3i iterations", i, sum (use.old, na.rm = TRUE), noise [i], iter)) - if ((debuglevel == 2L) && (i == 1L)){ - plot (fit.to[i,, use.old], add = TRUE, lines.args = list (pch = 20, type = "p"), col= cols [iter]) - lines (fit.to@wavelength, bl, col = cols [iter]) - lines (fit.to@wavelength, bl + noise, col = cols [iter], lty = 2) + if (debuglevel >= 1L) { + message(sprintf("spectrum % 6i: % 5i support points, noise = %0.1f, %3i iterations", i, sum(use.old, na.rm = TRUE), noise [i], iter)) + } + if ((debuglevel == 2L) && (i == 1L)) { + plot(fit.to[i, , use.old], add = TRUE, lines.args = list(pch = 20, type = "p"), col = cols [iter]) + lines(fit.to@wavelength, bl, col = cols [iter]) + lines(fit.to@wavelength, bl + noise, col = cols [iter], lty = 2) } - } - if (is.null (apply.to)){ - fit.to <- new("hyperSpec", spc=p, wavelength=0 : poly.order) - colnames (fit.to@data$spc) <- paste0 ("(x - minx)^", 0 : poly.order) - - validObject (fit.to) + if (is.null(apply.to)) { + fit.to <- new("hyperSpec", spc = p, wavelength = 0:poly.order) + colnames(fit.to@data$spc) <- paste0("(x - minx)^", 0:poly.order) - fit.to$min.x = minx - return (fit.to) + validObject(fit.to) + fit.to$min.x <- minx + return(fit.to) } else { x <- apply.to@wavelength - minx - vdm <- vanderMonde(x, poly.order) # Vandermonde matrix of x + vdm <- vanderMonde(x, poly.order) # Vandermonde matrix of x - apply.to@data$spc <- I (t (apply (p, 1, function (p, x) {x %*% p}, vdm))) + apply.to@data$spc <- I(t(apply(p, 1, function(p, x) { + x %*% p + }, vdm))) - validObject (apply.to) + validObject(apply.to) apply.to } } -.test (spc.fit.poly.below) <- function (){ - context ("spc.fit.poly.below") +.test(spc.fit.poly.below) <- function() { + context("spc.fit.poly.below") - test_that("no normalization", - bl.nonorm <- spc.fit.poly.below (flu, flu, poly.order = 3, offset.wl = FALSE, npts.min = 25) + test_that( + "no normalization", + bl.nonorm <- spc.fit.poly.below(flu, flu, poly.order = 3, offset.wl = FALSE, npts.min = 25) ) # test effect of wavelength axis normalization # was issue 1 on github tmp <- flu - wl (tmp) <- wl (tmp) + 1e4 + wl(tmp) <- wl(tmp) + 1e4 test_that("normalization/offset wavelengths", { - expect_error (spc.fit.poly.below (tmp, poly.order = 3, offset.wl = FALSE, npts.min = 25)) + expect_error(spc.fit.poly.below(tmp, poly.order = 3, offset.wl = FALSE, npts.min = 25)) - bl.1e4 <- spc.fit.poly.below (tmp, tmp, poly.order = 3, offset.wl = TRUE, npts.min = 25) - bl.nonorm <- spc.fit.poly.below (flu, flu, poly.order = 3, offset.wl = FALSE, npts.min = 25) + bl.1e4 <- spc.fit.poly.below(tmp, tmp, poly.order = 3, offset.wl = TRUE, npts.min = 25) + bl.nonorm <- spc.fit.poly.below(flu, flu, poly.order = 3, offset.wl = FALSE, npts.min = 25) - expect_equal (bl.nonorm [[]], bl.1e4 [[]]) + expect_equal(bl.nonorm [[]], bl.1e4 [[]]) }) - + test_that("requesting 2 support points working - issue #58", { - expect_warning (spc.fit.poly.below(chondro[103], npts.min = 2), "Stopped after") - expect_warning (spc.fit.poly.below(chondro[103], npts.min = 2, stop.on.increase = TRUE), "about to increase again") + expect_warning(spc.fit.poly.below(chondro[103], npts.min = 2), "Stopped after") + expect_warning(spc.fit.poly.below(chondro[103], npts.min = 2, stop.on.increase = TRUE), "about to increase again") }) - + test_that("spectrum containing NA", { tmp <- chondro [1] - tmp [[,, 1600]] <- NA - + tmp [[, , 1600]] <- NA + coefs <- spc.fit.poly.below(tmp, apply.to = NULL) [[]] expect_equal( coefs, - spc.fit.poly.below(chondro [1,, !is.na (tmp)], apply.to = NULL) [[]] + spc.fit.poly.below(chondro [1, , !is.na(tmp)], apply.to = NULL) [[]] ) - - ## bug was: all coefficients were silently 0 - expect_true (all (abs (coefs) > sqrt (.Machine$double.eps))) + + ## bug was: all coefficients were silently 0 + expect_true(all(abs(coefs) > sqrt(.Machine$double.eps))) }) } - - diff --git a/hyperSpec/R/spc.identify.R b/hyperSpec/R/spc.identify.R index cf1406072..9402e9c3b 100644 --- a/hyperSpec/R/spc.identify.R +++ b/hyperSpec/R/spc.identify.R @@ -1,11 +1,11 @@ ##' Identifying Spectra and Spectral Data Points ##' This function allows to identify the spectrum and the wavelength of a point ##' in a plot produced by \code{\link{plotspc}}. -##' +##' ##' This function first finds the spectrum with a point closest to the clicked ##' position (see \code{\link[graphics]{locator}}). The distance to the clicked ##' point is evaluated relative to the size of the tolerance window. -##' +##' ##' In a second step, \code{max.fn} searches for the actual point to label ##' within the specified wavelength window of that spectrum. This allows to ##' label maxima (or minima) without demanding too precise clicks. Currently, @@ -20,7 +20,7 @@ ##' respective intensities of the closest spectrum, and \code{wlclick} the ##' wavelength that was clicked. They return a vector of two elements ##' (wavelength and intensity). -##' +##' ##' As a last step, a label for the point produced by \code{formatter} and ##' plotted using \code{\link[graphics]{text}}. Currently, the following ##' \code{formatter}s are available: \tabular{ll}{ spc.label.default \tab @@ -30,20 +30,20 @@ ##' a character variable suitable for labelling. The predefined formatters ##' surround the label text by spaces in order to easily have an appropriate ##' offset from the point of the spectrum. -##' +##' ##' The warning issued if no spectral point is inside the tolerance window may ##' be switched of by \code{warn = FALSE}. In that case, the click will produce ##' a row of \code{NA}s in the resulting data.frame. -##' +##' ##' \code{spc.identify} uses option \code{debuglevel} to determine whether debugging output should be ##' produced. \code{debuglevel == 2} will plot the tolerance window for every clicked point, ##' \code{debuglevel == 1} will plot the tolerance window only if no data point was inside. See ##' \code{\link[hyperSpec:options]{hyperSpec options}} for details about retrieving and setting ##' options. -##' +##' ##' You may want to adjust the plot's \code{ylim} to ensure that the labels are ##' not clipped. As a dirty shortcut, \code{xpd = NA} may help. -##' +##' ##' @aliases spc.identify spc.label.default spc.label.wlonly spc.point.default ##' spc.point.max spc.point.min spc.point.sqr ##' @param x either the abscissa coordinates or the list returned by @@ -64,7 +64,7 @@ ##' @param warn Should the user be warned if no point is in the considered ##' window? In addition, see the discussion of option \code{debuglevel} in ##' the details. -##' +##' ##' If \code{FALSE}, the resulting data.frame will have a row of \code{NA}s ##' instead. ##' @param delta \code{spc.point.sqr} fits the parabola in the window wlclick @@ -72,138 +72,146 @@ ##' @return a \code{data.frame} with columns \item{ispc}{spectra indices of the ##' identified points, i.e. the rows of the \code{hyperSpec} object that was ##' plotted. -##' +##' ##' If \code{ispc} is given, \code{ispc [i]} is returned rather than \code{i}. ##' } \item{wavelengths}{the wavelengths of the identified points} ##' \item{spc}{the intensities of the identified points} ##' @author C. Beleites ##' @seealso \code{\link[graphics]{locator}}, \code{\link{plotspc}}, ##' \code{\link[hyperSpec:options]{hyperSpec options}} -##' +##' ##' \code{\link{map.identify}} \code{\link{map.sel.poly}} ##' @keywords iplot ##' @rdname spc-identify ##' @export ##' @examples -##' +##' ##' if (interactive ()){ ##' ispc <- sample (nrow (laser), 10) ##' ispc -##' +##' ##' identified <- spc.identify (plotspc (laser[ispc])) -##' +##' ##' ## convert to the "real" spectra indices ##' ispc [identified$ispc] ##' identified$wl ##' identified$spc -##' +##' ##' ## allow the labels to be plotted into the plot margin -##' spc.identify (plotspc (laser[ispc]), ispc = ispc, xpd = NA) -##' +##' spc.identify (plotspc (laser[ispc]), ispc = ispc, xpd = NA) +##' ##' spc.identify (plotspc (paracetamol, xoffset = 1100, ##' wl.range = c (600 ~ 1700, 2900 ~ 3150)), ##' formatter = spc.label.wlonly) -##' +##' ##' ## looking for minima ##' spc.identify (plot (-paracetamol, wl.reverse = TRUE), ##' point.fn = spc.point.min, adj = c (1, 0.5)) -##' +##' ##' } -##' -spc.identify <- function (x, y = NULL, wavelengths = NULL, ispc = NULL, - tol.wl = diff (range (x)) / 200, - tol.spc = diff (range (y)) / 50, - point.fn = spc.point.max, # function to find the maximum - formatter = spc.label.default, # NULL: suppress labels - ..., cex = 0.7, adj = c (0, 0.5), srt = 90, # for the label text - warn = TRUE){ - - if (! interactive ()) - stop ("spc.identify works only on interactive graphics devices.") - - if (is.list (x)) { - if (is.null (wavelengths)) +##' +spc.identify <- function(x, y = NULL, wavelengths = NULL, ispc = NULL, + tol.wl = diff(range(x)) / 200, + tol.spc = diff(range(y)) / 50, + point.fn = spc.point.max, # function to find the maximum + formatter = spc.label.default, # NULL: suppress labels + ..., cex = 0.7, adj = c(0, 0.5), srt = 90, # for the label text + warn = TRUE) { + if (!interactive()) { + stop("spc.identify works only on interactive graphics devices.") + } + + if (is.list(x)) { + if (is.null(wavelengths)) { wavelengths <- x$wavelengths - if (is.null (y)) + } + if (is.null(y)) { y <- x$y + } x <- x$x } - debuglevel <- hy.getOption ("debuglevel") + debuglevel <- hy.getOption("debuglevel") - if ((length (x) != length (y)) | (length (x) != length (wavelengths))) - stop ("x, y, and wavelength need to have the same length.") + if ((length(x) != length(y)) | (length(x) != length(wavelengths))) { + stop("x, y, and wavelength need to have the same length.") + } - if (is.null (ispc)) - ispc <- row (y) - else + if (is.null(ispc)) { + ispc <- row(y) + } else { ispc <- ispc[row(y)] - - pts <- data.frame (ispc = rep (NA, 50), wl = NA, spc = NA) + } + + pts <- data.frame(ispc = rep(NA, 50), wl = NA, spc = NA) pos <- 1 - - while (! is.null (tmp <- locator (n = 1))){ - wl <- approx (x, wavelengths, tmp$x, rule = 2)$y # return wl_min / wl_max for outside pts. + + while (!is.null(tmp <- locator(n = 1))) { + wl <- approx(x, wavelengths, tmp$x, rule = 2)$y # return wl_min / wl_max for outside pts. if (debuglevel == 2L) { - points (tmp$x, tmp$y, pch = ".", col = "red") - rect (tmp$x - tol.wl, tmp$y - tol.spc, tmp$x + tol.wl, tmp$y + tol.spc, - border = "red", col = NA) + points(tmp$x, tmp$y, pch = ".", col = "red") + rect(tmp$x - tol.wl, tmp$y - tol.spc, tmp$x + tol.wl, tmp$y + tol.spc, + border = "red", col = NA + ) } i.window <- wavelengths >= wl - tol.wl & # window to search for the closest spectrum - wavelengths <= wl + tol.wl & - y >= tmp$y - tol.spc & - y <= tmp$y + tol.spc + wavelengths <= wl + tol.wl & + y >= tmp$y - tol.spc & + y <= tmp$y + tol.spc - if (! any (i.window)){ - if (warn) - warning ("No spectra in specified window.") - else + if (!any(i.window)) { + if (warn) { + warning("No spectra in specified window.") + } else { pos <- pos + 1 + } if (debuglevel == 1L) { - points (tmp$x, tmp$y, pch = ".", col = "red") - rect (tmp$x - tol.wl, tmp$y - tol.spc, tmp$x + tol.wl, tmp$y + tol.spc, - border = "red", col = NA) + points(tmp$x, tmp$y, pch = ".", col = "red") + rect(tmp$x - tol.wl, tmp$y - tol.spc, tmp$x + tol.wl, tmp$y + tol.spc, + border = "red", col = NA + ) } - } else { - + ## find spectrum closest to clicked point. ## x and y distances are scaled according to tolerance. tmp <- ((wl - wavelengths [i.window]) / tol.wl)^2 + - ((tmp$y - y [i.window]) / tol.spc)^2 - tmp <- which (i.window) [which.min (tmp)] + ((tmp$y - y [i.window]) / tol.spc)^2 + tmp <- which(i.window) [which.min(tmp)] - pts [pos, "ispc"] <- ispc [tmp] # closest spectrum; - # this will grow the data.frame if necessary - # no time concern with hand-clicked points + pts [pos, "ispc"] <- ispc [tmp] # closest spectrum; + # this will grow the data.frame if necessary + # no time concern with hand-clicked points ## search for the max (min) of spectrum pt within tmp$x +- tol.wl - i.window <- which (ispc == ispc [tmp] & - wavelengths >= wl - tol.wl & - wavelengths <= wl + tol.wl) - - pts [pos, 2 : 3] <- point.fn (wl = wavelengths [i.window], - spc = y [i.window], - wlclick = wl) - + i.window <- which(ispc == ispc [tmp] & + wavelengths >= wl - tol.wl & + wavelengths <= wl + tol.wl) + + pts [pos, 2:3] <- point.fn( + wl = wavelengths [i.window], + spc = y [i.window], + wlclick = wl + ) + ## label the point - if (! is.null (formatter)){ - lab <- formatter (pts [pos, 1], pts [pos, 2], pts [pos, 3]) - - text (approx (wavelengths, x, pts [pos, 2], rule = 2), - pts [pos, 3], labels = lab, cex = cex, adj = adj, srt = srt, ...) + if (!is.null(formatter)) { + lab <- formatter(pts [pos, 1], pts [pos, 2], pts [pos, 3]) + + text(approx(wavelengths, x, pts [pos, 2], rule = 2), + pts [pos, 3], + labels = lab, cex = cex, adj = adj, srt = srt, ... + ) } pos <- pos + 1 } - - } - pts [seq_len (pos - 1),] + pts [seq_len(pos - 1), ] } ##' @rdname spc-identify @@ -211,47 +219,44 @@ spc.identify <- function (x, y = NULL, wavelengths = NULL, ispc = NULL, ##' @param spc the intensity to label ##' @param wlclick the clicked wavelength ##' @export -spc.point.max <- function (wl, spc, wlclick){ - i <- which.max (spc) - c (wl = wl [i], spc = spc [i]) +spc.point.max <- function(wl, spc, wlclick) { + i <- which.max(spc) + c(wl = wl [i], spc = spc [i]) } ##' @rdname spc-identify ##' @export -spc.point.default <- function (wl, spc, wlclick){ - i <- round (approx (wl, seq_along (wl), wlclick, rule = 2)$y) - c (wl = wl [], spc = spc [i]) +spc.point.default <- function(wl, spc, wlclick) { + i <- round(approx(wl, seq_along(wl), wlclick, rule = 2)$y) + c(wl = wl [], spc = spc [i]) } ##' @rdname spc-identify ##' @export -spc.point.min <- function (wl, spc, wlclick){ - i <- which.min (spc) - c (wl = wl [i], spc = spc [i]) +spc.point.min <- function(wl, spc, wlclick) { + i <- which.min(spc) + c(wl = wl [i], spc = spc [i]) } ##' @rdname spc-identify ##' @export -spc.point.sqr <- function (wl, spc, wlclick, delta = 1L){ - i <- which.max (spc) +spc.point.sqr <- function(wl, spc, wlclick, delta = 1L) { + i <- which.max(spc) - ## points (wl [i], spc [i]) - if (i > 1L && i < length (wl)) { - i <- i + (-delta : delta) - i <- i %in% seq_along (wl) # make sure the indices exist - - p <- outer (wl [i], 0 : 2, "^") # Vandermonde matrix - p <- qr.solve (p, spc [i]) + ## points (wl [i], spc [i]) + if (i > 1L && i < length(wl)) { + i <- i + (-delta:delta) + i <- i %in% seq_along(wl) # make sure the indices exist - i <- -p [2] / p [3] / 2 + p <- outer(wl [i], 0:2, "^") # Vandermonde matrix + p <- qr.solve(p, spc [i]) - ## lines (wl, outer (wl, 0 : 2, "^") %*% p, col = "red") - c (wl = i, spc = sum (p * c(1, i, i^2))) + i <- -p [2] / p [3] / 2 + ## lines (wl, outer (wl, 0 : 2, "^") %*% p, col = "red") + c(wl = i, spc = sum(p * c(1, i, i^2))) } else { - - c (wl = wl [i], spc = spc [i]) - + c(wl = wl [i], spc = spc [i]) } } @@ -261,16 +266,12 @@ spc.point.sqr <- function (wl, spc, wlclick, delta = 1L){ ##' @param digits how many digits of the wavelength should be displayed? ##' @rdname spc-identify ##' @export -spc.label.default <- function (ispc, wl, spc, digits = 3){ - sprintf(" %i, %s ", ispc, format (wl, digits = digits)) +spc.label.default <- function(ispc, wl, spc, digits = 3) { + sprintf(" %i, %s ", ispc, format(wl, digits = digits)) } ##' @rdname spc-identify ##' @export -spc.label.wlonly <- function (ispc, wl, spc, digits = 3){ - sprintf(" %s ", format (wl, digits = digits)) +spc.label.wlonly <- function(ispc, wl, spc, digits = 3) { + sprintf(" %s ", format(wl, digits = digits)) } - - - - diff --git a/hyperSpec/R/spc.loess.R b/hyperSpec/R/spc.loess.R index 20d393fa1..7198f76e1 100644 --- a/hyperSpec/R/spc.loess.R +++ b/hyperSpec/R/spc.loess.R @@ -1,16 +1,16 @@ ##' loess smoothing interpolation for spectra ##' Spectra can be smoothed and interpolated on a new wavelength axis using ##' \code{\link[stats]{loess}}. -##' +##' ##' Applying \code{\link[stats]{loess}} to each of the spectra, an interpolation onto a new ##' wavelength axis is performed. At the same time, the specta are smoothed in order to increase the ##' signal : noise ratio. See \code{\link[stats]{loess}} and \code{\link[stats]{loess.control}} on ##' the parameters that control the amount of smoothing. -##' +##' ##' @param spc the \code{hyperSpec} object ##' @param newx wavelengh axis to interpolate on ##' @param enp.target,surface,... parameters for \code{\link[stats]{loess}} and -##' \code{\link[stats]{loess.control}}. +##' \code{\link[stats]{loess.control}}. ##' @return a new \code{hyperspec} object. ##' @rdname spc-loess ##' @export @@ -18,42 +18,44 @@ ##' @seealso \code{\link[stats]{loess}}, \code{\link[stats]{loess.control}} ##' @keywords manip datagen ##' @examples -##' +##' ##' plot (flu, col = "darkgray") ##' plot (spc.loess(flu, seq (420, 470, 5)), add = TRUE, col = "red") -##' +##' ##' flu [[3, ]] <- NA_real_ ##' smooth <- spc.loess(flu, seq (420, 470, 5)) ##' smooth [[, ]] ##' plot (smooth, add = TRUE, col = "blue") -##' -spc.loess <- function (spc, newx, enp.target = nwl (spc) / 4, - surface = "direct", ...){ - - .loess <- function (y, x){ - if (all (is.na (y))) +##' +spc.loess <- function(spc, newx, enp.target = nwl(spc) / 4, + surface = "direct", ...) { + .loess <- function(y, x) { + if (all(is.na(y))) { NA - else - loess (y ~ x, enp.target = enp.target, surface = surface, ...) + } else { + loess(y ~ x, enp.target = enp.target, surface = surface, ...) + } } - .predict <- function (loess, x){ - if (!is (loess, "loess") && is.na (loess)) - rep (NA_real_, length (x)) - else - predict (loess, x) + .predict <- function(loess, x) { + if (!is(loess, "loess") && is.na(loess)) { + rep(NA_real_, length(x)) + } else { + predict(loess, x) + } } - - chk.hy (spc) - validObject (spc) - loess <- apply (t (spc[[]]), 2, .loess, spc@wavelength) + chk.hy(spc) + validObject(spc) + + loess <- apply(t(spc[[]]), 2, .loess, spc@wavelength) - spc@data$spc <- t (sapply (loess, .predict, newx)) + spc@data$spc <- t(sapply(loess, .predict, newx)) .wl(spc) <- newx - if (any (is.na (spc@data$spc))) - warning ("NAs were generated. Probably newx was outside the spectral range covered by spc.") + if (any(is.na(spc@data$spc))) { + warning("NAs were generated. Probably newx was outside the spectral range covered by spc.") + } spc } diff --git a/hyperSpec/R/spc.rubberband.R b/hyperSpec/R/spc.rubberband.R index 45b698b5a..c9ac201b0 100644 --- a/hyperSpec/R/spc.rubberband.R +++ b/hyperSpec/R/spc.rubberband.R @@ -1,7 +1,7 @@ ##' Rubberband baseline ##' ##' Baseline with support points determined from a convex hull of the spectrum. -##' +##' ##' Use \code{debuglevel >= 1} to obtain debug plots, either directly via function argument or by setting hyperSpec's \code{debuglevel} option. ##' @title Rubberband baseline correction ##' @param spc hyperSpec object @@ -14,9 +14,9 @@ ##' @rdname spc-rubberband ##' @author Claudia Beleites ##' @seealso \code{\link[hyperSpec]{spc.fit.poly}}, \code{\link[hyperSpec]{spc.fit.poly.below}} -##' +##' ##' \code{vignette ("baseline")} -##' +##' ##' \code{\link[hyperSpec]{hy.setOptions}} ##' ##' @note This function is still experimental @@ -25,16 +25,17 @@ ##' plot (paracetamol [,, 175 ~ 1800]) ##' bl <- spc.rubberband (paracetamol [,, 175 ~ 1800], noise = 300, df = 20) ##' plot (bl, add = TRUE, col = 2) -##' +##' ##' plot (paracetamol [,, 175 ~ 1800] - bl) -spc.rubberband <- function (spc, ..., upper = FALSE, noise = 0, spline = TRUE){ - spc <- orderwl (spc) +spc.rubberband <- function(spc, ..., upper = FALSE, noise = 0, spline = TRUE) { + spc <- orderwl(spc) if (upper) spc@data$spc <- -spc@data$spc - - spc@data$spc <- .rubberband (spc@wavelength, spc@data$spc, - noise = noise, spline = spline, ...) + + spc@data$spc <- .rubberband(spc@wavelength, spc@data$spc, + noise = noise, spline = spline, ... + ) if (upper) spc@data$spc <- -spc@data$spc @@ -42,104 +43,103 @@ spc.rubberband <- function (spc, ..., upper = FALSE, noise = 0, spline = TRUE){ } ##' @importFrom grDevices chull -.rubberband <- function (x, y, noise, spline, ..., debuglevel = hy.getOption ("debuglevel")){ - for (s in seq_len (nrow (y))){ - use <- which (!is.na (y [s,])) - - pts <- chull (x [use], y [s,use]) +.rubberband <- function(x, y, noise, spline, ..., debuglevel = hy.getOption("debuglevel")) { + for (s in seq_len(nrow(y))) { + use <- which(!is.na(y [s, ])) + + pts <- chull(x [use], y [s, use]) pts <- use [pts] - - if (debuglevel >= 1L){ - plot (x, y [s, ], type = "l") - points (x [pts], y [s, pts], pch = 1, col = matlab.dark.palette (length (pts))) + + if (debuglevel >= 1L) { + plot(x, y [s, ], type = "l") + points(x [pts], y [s, pts], pch = 1, col = matlab.dark.palette(length(pts))) } ## `chull` returns points in cw order ## => points between ncol (y) and 1 are lower part of hull - imax <- which.max (pts) - 1 - + imax <- which.max(pts) - 1 + ## if necessary, rotate pts so that ncol (y) is at position 1 - if (imax > 0L) - pts <- c (pts [- seq_len (imax)], pts [seq_len (imax)]) + if (imax > 0L) { + pts <- c(pts [-seq_len(imax)], pts [seq_len(imax)]) + } ## now keep only pts until column index 1 - pts <- pts [1 : which.min (pts)] - - ## check whether first and last point are minima, + pts <- pts [1:which.min(pts)] + + ## check whether first and last point are minima, ## if not remove them. ## If they are minima, 2nd and 2nd last point do not appear in pts - ## last point: + ## last point: if (pts [2] == pts [1] - 1) pts <- pts [-1] - + ## now sort ascending (anyways needed later on) - pts <- rev (pts) - + pts <- rev(pts) + ## fist point: if (pts [2] == pts [1] + 1) pts <- pts [-1] - - if (debuglevel >= 1L){ - points (x [pts], y [s, pts], pch = 19, col = matlab.dark.palette (length (pts)), cex = 0.7) + + if (debuglevel >= 1L) { + points(x [pts], y [s, pts], pch = 19, col = matlab.dark.palette(length(pts)), cex = 0.7) } - tmp <- approx (x = x [pts], y = y [s, pts], xout= x, method="linear")$y - - if (spline){ - pts <- which (y [s,] <= tmp + noise) + tmp <- approx(x = x [pts], y = y [s, pts], xout = x, method = "linear")$y + + if (spline) { + pts <- which(y [s, ] <= tmp + noise) - if (length (pts) > 3) - tmp <- predict (smooth.spline (x[pts], y[s, pts], ...)$fit, x, 0)$y - else - tmp <- spline (x [pts], y [s, pts], xout = x)$y - + if (length(pts) > 3) { + tmp <- predict(smooth.spline(x[pts], y[s, pts], ...)$fit, x, 0)$y + } else { + tmp <- spline(x [pts], y [s, pts], xout = x)$y + } } - + y [s, ] <- tmp - } - - y + + y } -.test (spc.rubberband) <- function (){ - context ("spc.rubberband") - +.test(spc.rubberband) <- function() { + context("spc.rubberband") + ## use data that yields fairly stable baseline solution - paracetamol <- paracetamol [,, 300 ~ 550] - + paracetamol <- paracetamol [, , 300 ~ 550] + test_that("spectrum containing NA inside", { tmp <- paracetamol - tmp [[,, 400]] <- NA - - coefs <- spc.rubberband (tmp) + tmp [[, , 400]] <- NA + + coefs <- spc.rubberband(tmp) expect_equal( - coefs [[,, !is.na (tmp)]], - spc.rubberband(paracetamol [,, !is.na (tmp)]) [[]] + coefs [[, , !is.na(tmp)]], + spc.rubberband(paracetamol [, , !is.na(tmp)]) [[]] ) - - ## bug was: all coefficients were silently 0 - expect_true (all (abs (coefs [[]]) > sqrt (.Machine$double.eps))) + + ## bug was: all coefficients were silently 0 + expect_true(all(abs(coefs [[]]) > sqrt(.Machine$double.eps))) }) - - test_that ("spectrum containing NA at first wavelength (issue #95)", { + + test_that("spectrum containing NA at first wavelength (issue #95)", { tmp <- paracetamol - tmp [[,, 1, wl.index = TRUE]] <- NA + tmp [[, , 1, wl.index = TRUE]] <- NA - coefs <- spc.rubberband (tmp) + coefs <- spc.rubberband(tmp) expect_equal( - coefs [[,, !is.na (tmp)]], - spc.rubberband(paracetamol [,, !is.na (tmp)]) [[]] + coefs [[, , !is.na(tmp)]], + spc.rubberband(paracetamol [, , !is.na(tmp)]) [[]] ) }) - test_that ("spectrum containing NA at end", { + test_that("spectrum containing NA at end", { tmp <- paracetamol [1] - tmp [[,, nwl (paracetamol), wl.index = TRUE]] <- NA - - coefs <- spc.rubberband (tmp) + tmp [[, , nwl(paracetamol), wl.index = TRUE]] <- NA + + coefs <- spc.rubberband(tmp) expect_equal( - coefs [[,, !is.na (tmp)]], - spc.rubberband(paracetamol [1,, !is.na (tmp)]) [[]] + coefs [[, , !is.na(tmp)]], + spc.rubberband(paracetamol [1, , !is.na(tmp)]) [[]] ) }) - -} \ No newline at end of file +} diff --git a/hyperSpec/R/spc.spline.R b/hyperSpec/R/spc.spline.R index d44bbcdad..a3dab3018 100644 --- a/hyperSpec/R/spc.spline.R +++ b/hyperSpec/R/spc.spline.R @@ -9,7 +9,7 @@ ##' @rdname spc-spline ##' @author Claudia Beleites ##' @seealso \code{\link[hyperSpec]{spc.loess}} -##' +##' ##' \code{\link[stats]{smooth.spline}} ##' @note This function is still experimental ##' @export @@ -20,34 +20,35 @@ ##' wl (paracetamol [,, 2200 ~ max]), ##' df = 4, spar = 1) ##' plot (smooth, col = "red", add = TRUE) -##' +##' ##' plot (p - smooth) -##' -spc.smooth.spline <- function (spc, newx = wl (spc), ...){ - - .spline <- function (x, y, newx){ - pts <- ! is.na (y) - fit <- smooth.spline (x [pts], y [pts], ...)$fit - predict (fit, newx, deriv = 0)$y +##' +spc.smooth.spline <- function(spc, newx = wl(spc), ...) { + .spline <- function(x, y, newx) { + pts <- !is.na(y) + fit <- smooth.spline(x [pts], y [pts], ...)$fit + predict(fit, newx, deriv = 0)$y } - spc <- orderwl (spc) #includes chk.hy and validObject + spc <- orderwl(spc) # includes chk.hy and validObject - newspc <- matrix (NA_real_, ncol = length (newx), nrow = nrow (spc)) - i <- rowSums (is.na (spc@data$spc)) < nwl (spc) + newspc <- matrix(NA_real_, ncol = length(newx), nrow = nrow(spc)) + i <- rowSums(is.na(spc@data$spc)) < nwl(spc) - newspc [i, ] <- t (apply (spc@data$spc [i,, drop = FALSE], 1, - .spline, x = spc@wavelength, newx = newx)) + newspc [i, ] <- t(apply(spc@data$spc [i, , drop = FALSE], 1, + .spline, + x = spc@wavelength, newx = newx + )) - if (any (is.na (newspc [i, ]))) - warning ("NAs generated. Probably newx was outside the spectral range covered by spc.") + if (any(is.na(newspc [i, ]))) { + warning("NAs generated. Probably newx was outside the spectral range covered by spc.") + } spc@data$spc <- newspc .wl(spc) <- newx - - validObject (spc) - + + validObject(spc) + spc } - diff --git a/hyperSpec/R/split.R b/hyperSpec/R/split.R index 5aefad581..2c68e4d6e 100644 --- a/hyperSpec/R/split.R +++ b/hyperSpec/R/split.R @@ -1,22 +1,22 @@ -.split <- function (x, f, drop = TRUE){ - validObject (x) - - hyperlist <- split (seq (x, index = TRUE), f, drop) - - for (i in seq_along (hyperlist)){ - hyperlist [[i]] <- x [hyperlist [[i]], ] - } - - hyperlist +.split <- function(x, f, drop = TRUE) { + validObject(x) + + hyperlist <- split(seq(x, index = TRUE), f, drop) + + for (i in seq_along(hyperlist)) { + hyperlist [[i]] <- x [hyperlist [[i]], ] + } + + hyperlist } ##' Split a hyperSpec object according to groups ##' \code{split} divides the \code{hyperSpec} object into a list of ##' \code{hyperSpec} objects according to the groups given by \code{f}. -##' +##' ##' The \code{hyperSpec} objects in the list may be bound together again by ##' \code{\link{bind} ("r", list_of_hyperSpec_objects)}. -##' +##' ##' @name split ##' @rdname split ##' @aliases split split-methods split,ANY-method split,hyperSpec-method @@ -32,18 +32,18 @@ ##' @keywords methods ##' @export ##' @examples -##' +##' ##' dist <- pearson.dist (chondro[[]]) ##' dend <- hclust (dist, method = "ward") ##' z <- cutree (dend, h = 0.15) -##' +##' ##' clusters <- split (chondro, z) ##' length (clusters) -##' +##' ##' # difference in cluster mean spectra ##' plot (apply (clusters[[2]], 2, mean) - apply (clusters[[1]], 2, mean)) -##' -##' +##' +##' -setMethod ("split", signature = signature (x = "hyperSpec"), .split) +setMethod("split", signature = signature(x = "hyperSpec"), .split) diff --git a/hyperSpec/R/split.string.R b/hyperSpec/R/split.string.R index 1c4f3d059..296a34c4f 100644 --- a/hyperSpec/R/split.string.R +++ b/hyperSpec/R/split.string.R @@ -1,32 +1,37 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### split.string - split string at pattern ### ### -split.string <- function (x, separator, trim.blank = TRUE, remove.empty = TRUE) { - pos <- gregexpr (separator, x) - if (length (pos) == 1 && pos [[1]] == -1) - return (x) +split.string <- function(x, separator, trim.blank = TRUE, remove.empty = TRUE) { + pos <- gregexpr(separator, x) + if (length(pos) == 1 && pos [[1]] == -1) { + return(x) + } pos <- pos [[1]] - pos <- matrix (c (1, pos + attr (pos, "match.length"), - pos - 1, nchar (x)), - ncol = 2) + pos <- matrix(c( + 1, pos + attr(pos, "match.length"), + pos - 1, nchar(x) + ), + ncol = 2 + ) - if (pos [nrow (pos), 1] > nchar (x)) - pos <- pos [- nrow (pos), ] + if (pos [nrow(pos), 1] > nchar(x)) { + pos <- pos [-nrow(pos), ] + } - x <- apply (pos, 1, function (p, x) substr (x, p [1], p [2]), x) + x <- apply(pos, 1, function(p, x) substr(x, p [1], p [2]), x) - if (trim.blank){ + if (trim.blank) { blank.pattern <- "^[[:blank:]]*([^[:blank:]]+.*[^[:blank:]]+)[[:blank:]]*$" - x <- sub (blank.pattern, "\\1", x) + x <- sub(blank.pattern, "\\1", x) } - if (remove.empty){ - x <- x [sapply (x, nchar) > 0] + if (remove.empty) { + x <- x [sapply(x, nchar) > 0] } x diff --git a/hyperSpec/R/splitdots.R b/hyperSpec/R/splitdots.R index 6905b5262..7401b3d4d 100644 --- a/hyperSpec/R/splitdots.R +++ b/hyperSpec/R/splitdots.R @@ -2,34 +2,38 @@ ## ##' @noRd -.split.dots <- function (dots, functions, drop = TRUE){ - fun.names <- paste ("^", names (functions), "[.]", sep = "") - dot.names <- names (dots) +.split.dots <- function(dots, functions, drop = TRUE) { + fun.names <- paste("^", names(functions), "[.]", sep = "") + dot.names <- names(dots) ## sort args to functions according to functionname.argumentname - args <- lapply (fun.names, grep, dot.names) - nomatch <- setdiff (seq_along (dots), unlist (args)) + args <- lapply(fun.names, grep, dot.names) + nomatch <- setdiff(seq_along(dots), unlist(args)) ## for now: - if (length (nomatch) > 0) - stop ("unmatched arguments: ", - paste (dot.names [nomatch], dots [nomatch], sep = " = ", collapse =", ") - ) + if (length(nomatch) > 0) { + stop( + "unmatched arguments: ", + paste(dot.names [nomatch], dots [nomatch], sep = " = ", collapse = ", ") + ) + } - args <- lapply (args, function (args, dots) dots [args], dots) - names (args) <- names (functions) + args <- lapply(args, function(args, dots) dots [args], dots) + names(args) <- names(functions) ## drop the function indicating part of the argument names - args <- mapply (function (args, fname) { - names (args) <- gsub (fname, "", names (args)) - args - }, - args, fun.names) - if (drop) - args [sapply (args, length) > 0] - else + args <- mapply( + function(args, fname) { + names(args) <- gsub(fname, "", names(args)) + args + }, + args, fun.names + ) + if (drop) { + args [sapply(args, length) > 0] + } else { args + } } ## TODO: tests - diff --git a/hyperSpec/R/subset.R b/hyperSpec/R/subset.R index eba06f8f3..ae1919920 100644 --- a/hyperSpec/R/subset.R +++ b/hyperSpec/R/subset.R @@ -1,10 +1,10 @@ -.subset <- function (x, ...){ - validObject (x) - x@data <- subset (x@data, ...) - validObject (x) - - x +.subset <- function(x, ...) { + validObject(x) + x@data <- subset(x@data, ...) + validObject(x) + + x } @@ -19,5 +19,5 @@ ##' @return hyperSpec object containing the respective subset of spectra. ##' @author Claudia Beleites ##' @seealso \code{\link[base]{subset}} -##' @export -setMethod ("subset", signature = signature (x = "hyperSpec"), .subset) +##' @export +setMethod("subset", signature = signature(x = "hyperSpec"), .subset) diff --git a/hyperSpec/R/sweep.R b/hyperSpec/R/sweep.R index 8cb70adbb..d81cd12ca 100644 --- a/hyperSpec/R/sweep.R +++ b/hyperSpec/R/sweep.R @@ -1,25 +1,27 @@ -.sweep <- function (x, MARGIN, STATS, FUN = "-", - check.margin = TRUE, ...){ - validObject (x) - - if (is (STATS, "hyperSpec")){ - validObject (STATS) - STATS <- STATS@data$spc - } else if (is (STATS, "function")) { - STATS <- apply (x, MARGIN, STATS)@data$spc - } - - x@data$spc <- sweep (x = x@data$spc, MARGIN = MARGIN, STATS = STATS, - FUN = FUN, check.margin = check.margin, ...) - - x +.sweep <- function(x, MARGIN, STATS, FUN = "-", + check.margin = TRUE, ...) { + validObject(x) + + if (is(STATS, "hyperSpec")) { + validObject(STATS) + STATS <- STATS@data$spc + } else if (is(STATS, "function")) { + STATS <- apply(x, MARGIN, STATS)@data$spc + } + + x@data$spc <- sweep( + x = x@data$spc, MARGIN = MARGIN, STATS = STATS, + FUN = FUN, check.margin = check.margin, ... + ) + + x } ##' Sweep Summary Statistic out of an hyperSpec Object ##' \code{\link[base]{sweep}} for \code{hyperSpec} objects. -##' +##' ##' Calls \code{\link[base]{sweep}} for the spectra matrix. -##' +##' ##' \code{sweep} is useful for some spectra preprocessing, like offset ##' correction, substraction of background spectra, and normalization of the ##' spectra. @@ -33,7 +35,7 @@ ##' along. ##' @param STATS the summary statistic to sweep out. Either a vector or a ##' \code{hyperSpec} object. -##' +##' ##' hyperSpec offers a non-standard convenience function: if \code{STATS} is a ##' function, this function is applied first (with the same \code{MARGIN}) to ##' compute the statistic. However, no further arguments to the apply @@ -48,32 +50,32 @@ ##' @author C. Beleites ##' @seealso \code{\link[base]{sweep}} ##' @keywords methods -##' @export +##' @export ##' @examples -##' +##' ##' ## Substract the background / slide / blank spectrum ##' # the example data does not have spectra of the empty slide, ##' # so instead the overall composition of the sample is substracted ##' background <- apply (chondro, 2, quantile, probs = 0.05) ##' corrected <- sweep (chondro, 2, background, "-") ##' plot (corrected, "spcprctl5") -##' +##' ##' ## Offset correction ##' offsets <- apply (chondro, 1, min) ##' corrected <- sweep (chondro, 1, offsets, "-") ##' plot (corrected, "spcprctl5") -##' +##' ##' ## Min-max normalization (on max amide I) ##' # the minimum is set to zero by the offset correction. ##' factor <- apply (corrected, 1, max) ##' mm.corrected <- sweep (corrected, 1, factor, "/") ##' plot (mm.corrected, "spcprctl5") -##' +##' ##' ## convenience: give function to compute STATS: ##' mm.corrected2 <- sweep (corrected, 1, max, "/") ##' plot (mm.corrected2) -##' +##' ##' ## checking ##' stopifnot (all (mm.corrected2 == mm.corrected)) -##' -setMethod ("sweep", signature = signature (x = "hyperSpec"), .sweep) +##' +setMethod("sweep", signature = signature(x = "hyperSpec"), .sweep) diff --git a/hyperSpec/R/trellis.factor.key.R b/hyperSpec/R/trellis.factor.key.R index 8dd909d30..9795ef54a 100644 --- a/hyperSpec/R/trellis.factor.key.R +++ b/hyperSpec/R/trellis.factor.key.R @@ -2,10 +2,10 @@ ##' Modifies a list of lattice arguments (as for \code{\link[lattice]{levelplot}}, etc.) according to ##' the factor levels. The colorkey will shows all levels (including unused), and the drawing colors ##' will be set accordingly. -##' +##' ##' \code{trellis.factor.key} is used during \code{levelplot}-based plotting of factors (for ##' hyperSpec objects) unless \code{transform.factor = FALSE} is specified. -##' +##' ##' @param f the factor that will be color-coded ##' @param levelplot.args a list with levelplot arguments ##' @return the modified list with levelplot arguments. @@ -15,36 +15,42 @@ ##' @export ##' @importFrom lattice level.colors ##' @examples -##' +##' ##' chondro$z <- factor (rep (c("a", "a", "d", "c"), ##' length.out = nrow (chondro)), ##' levels = letters [1 : 4]) -##' +##' ##' str (trellis.factor.key (chondro$z)) -##' +##' ##' plotmap (chondro, z ~ x * y) -##' +##' ##' ## switch off using trellis.factor.key: ##' ## note that the factor levels are collapsed to c(1, 2, 3) rather than ##' ## c (1, 3, 4) ##' plotmap (chondro, z ~ x * y, transform.factor = FALSE) -##' +##' ##' plotmap (chondro, z ~ x * y, ##' col.regions = c ("gray", "red", "blue", "dark green")) -##' +##' ##' @importFrom utils modifyList -trellis.factor.key <- function (f, levelplot.args = list ()) { - at <- seq (0, nlevels (f)) + .5 - - if (is.null (levelplot.args$col.regions)) - cols <- level.colors (seq_along (levels (f)), at) - else - cols <- level.colors (seq_along (levels (f)), at, levelplot.args$col.regions) - - modifyList (list (at = at, - col.regions = cols, - colorkey = list (lab = list (at = seq_along (levels (f)), - lab = levels (f)))), - levelplot.args) - +trellis.factor.key <- function(f, levelplot.args = list()) { + at <- seq(0, nlevels(f)) + .5 + + if (is.null(levelplot.args$col.regions)) { + cols <- level.colors(seq_along(levels(f)), at) + } else { + cols <- level.colors(seq_along(levels(f)), at, levelplot.args$col.regions) + } + + modifyList( + list( + at = at, + col.regions = cols, + colorkey = list(lab = list( + at = seq_along(levels(f)), + lab = levels(f) + )) + ), + levelplot.args + ) } diff --git a/hyperSpec/R/units.R b/hyperSpec/R/units.R index db1494cea..d708627f3 100644 --- a/hyperSpec/R/units.R +++ b/hyperSpec/R/units.R @@ -1,3 +1,3 @@ -.wn.shift <- expression (Delta*tilde(nu) / cm^-1) -.wn <- expression (tilde(nu) / cm^-1) -.wl <- expression (lambda / nm) +.wn.shift <- expression(Delta * tilde(nu) / cm^-1) +.wn <- expression(tilde(nu) / cm^-1) +.wl <- expression(lambda / nm) diff --git a/hyperSpec/R/unittest.R b/hyperSpec/R/unittest.R index 5502430ed..86c72150d 100644 --- a/hyperSpec/R/unittest.R +++ b/hyperSpec/R/unittest.R @@ -15,25 +15,26 @@ ##' ##' hy.unittest () ##' -hy.unittest <- function (){ - if (!requireNamespace("testthat", quietly=TRUE)) { +hy.unittest <- function() { + if (!requireNamespace("testthat", quietly = TRUE)) { warning("testthat required to run the unit tests.") return(NA) } - if (! "package:testthat" %in% search ()) + if (!"package:testthat" %in% search()) { attachNamespace("testthat") + } - tests <- eapply(env = getNamespace ("hyperSpec"), FUN = get.test, all.names=TRUE) - tests <- tests [! sapply (tests, is.null)] + tests <- eapply(env = getNamespace("hyperSpec"), FUN = get.test, all.names = TRUE) + tests <- tests [!sapply(tests, is.null)] reporter <- SummaryReporter$new() lister <- ListReporter$new() reporter <- MultiReporter$new(reporters = list(reporter, lister)) with_reporter(reporter = reporter, start_end_reporter = TRUE, { - for (t in seq_along(tests)){ - lister$start_file(names (tests [t])) - tests [[t]] () + for (t in seq_along(tests)) { + lister$start_file(names(tests [t])) + tests [[t]]() } get_reporter()$.end_context() }) @@ -43,18 +44,18 @@ hy.unittest <- function (){ ##' @noRd { - `.test<-` <- function (f, value) { - attr (f, "test") <- value + `.test<-` <- function(f, value) { + attr(f, "test") <- value f } - - skip_if_not_fileio_available <- function () { - skip_if_not (file.exists("fileio"), message = "file import test files not installed") + + skip_if_not_fileio_available <- function() { + skip_if_not(file.exists("fileio"), message = "file import test files not installed") } } ##' get test that is attached to object as "test" attribute ##' @noRd -get.test <- function (object) - attr (object, "test") - +get.test <- function(object) { + attr(object, "test") +} diff --git a/hyperSpec/R/validate.R b/hyperSpec/R/validate.R index 934a51f62..d02d5a345 100644 --- a/hyperSpec/R/validate.R +++ b/hyperSpec/R/validate.R @@ -1,11 +1,13 @@ -.validate <- function (object) { - ncol <- ncol (object@data$spc) - - if (is.null (ncol)) - ncol <- 0 - - if (length (object@wavelength) != ncol) - return ("Length of wavelength vector differs from number of data points per spectrum.") +.validate <- function(object) { + ncol <- ncol(object@data$spc) - TRUE - } + if (is.null(ncol)) { + ncol <- 0 + } + + if (length(object@wavelength) != ncol) { + return("Length of wavelength vector differs from number of data points per spectrum.") + } + + TRUE +} diff --git a/hyperSpec/R/vandermonde.R b/hyperSpec/R/vandermonde.R index ce2ad36e2..7d9ac8d18 100644 --- a/hyperSpec/R/vandermonde.R +++ b/hyperSpec/R/vandermonde.R @@ -12,15 +12,16 @@ ##' @author C. Beleites ##' @export ##' @include unittest.R -vanderMonde <- function (x, order, ...){ - if (nargs () > 2) - stop ('Unknown arguments: ', names (c (...))) +vanderMonde <- function(x, order, ...) { + if (nargs() > 2) { + stop("Unknown arguments: ", names(c(...))) + } - outer (x, 0 : order, `^`) + outer(x, 0:order, `^`) } ##' @noRd -setGeneric ("vanderMonde") +setGeneric("vanderMonde") ##' @param normalize.wl function to transorm the wavelengths before evaluating the polynomial (or ##' other function). \code{\link[hyperSpec]{normalize01}} maps the wavelength range to the interval @@ -37,44 +38,44 @@ setGeneric ("vanderMonde") ##' plot (vanderMonde (flu, 2, normalize.wl = I)) ##' ##' -setMethod ("vanderMonde", signature = signature (x = "hyperSpec"), - function (x, order, ..., normalize.wl = normalize01){ - validObject (x) +setMethod("vanderMonde", + signature = signature(x = "hyperSpec"), + function(x, order, ..., normalize.wl = normalize01) { + validObject(x) - wl <- normalize.wl (x@wavelength) + wl <- normalize.wl(x@wavelength) - x <- decomposition (x, t (vanderMonde (wl, order)), scores = FALSE, ...) - x$.vdm.order <- 0 : order - x -}) + x <- decomposition(x, t(vanderMonde(wl, order)), scores = FALSE, ...) + x$.vdm.order <- 0:order + x + } +) -.test (vanderMonde) <- function (){ - context ("vanderMonde") +.test(vanderMonde) <- function() { + context("vanderMonde") - test_that("vector against manual calculation",{ - expect_equal (vanderMonde (c (1 : 3, 5), 2), - matrix (c (1, 1, 1, 1, 1, 2, 3, 5, 1, 4, 9, 25), nrow = 4) + test_that("vector against manual calculation", { + expect_equal( + vanderMonde(c(1:3, 5), 2), + matrix(c(1, 1, 1, 1, 1, 2, 3, 5, 1, 4, 9, 25), nrow = 4) ) }) - test_that("default method doesn't provide normalization",{ - expect_error (vanderMonde (1, 0, normalize.wl = normalize01)) + test_that("default method doesn't provide normalization", { + expect_error(vanderMonde(1, 0, normalize.wl = normalize01)) }) - test_that ("hyperSpec objects", { - expect_true (chk.hy (vanderMonde (flu, 0))) - expect_true (validObject (vanderMonde (flu, 0))) + test_that("hyperSpec objects", { + expect_true(chk.hy(vanderMonde(flu, 0))) + expect_true(validObject(vanderMonde(flu, 0))) - tmp <- vanderMonde (paracetamol, 3, normalize.wl = I) - dimnames (tmp$spc) <- NULL - expect_equal (tmp [[]], t (vanderMonde (wl (paracetamol), 3))) + tmp <- vanderMonde(paracetamol, 3, normalize.wl = I) + dimnames(tmp$spc) <- NULL + expect_equal(tmp [[]], t(vanderMonde(wl(paracetamol), 3))) - tmp <- vanderMonde (paracetamol, 3, normalize.wl = normalize01) - dimnames (tmp$spc) <- NULL - expect_equal (tmp[[]], t (vanderMonde (normalize01 (wl (paracetamol)), 3))) + tmp <- vanderMonde(paracetamol, 3, normalize.wl = normalize01) + dimnames(tmp$spc) <- NULL + expect_equal(tmp[[]], t(vanderMonde(normalize01(wl(paracetamol)), 3))) }) } - - - diff --git a/hyperSpec/R/wc.R b/hyperSpec/R/wc.R index f083a0eee..eca42cc73 100644 --- a/hyperSpec/R/wc.R +++ b/hyperSpec/R/wc.R @@ -12,46 +12,55 @@ ##' @export ##' @author C. Beleites ##' @importFrom utils read.table -wc <- function (file, flags = c("lines", "words", "bytes")){ - .Deprecated(new = "count_lines", - msg = "wc() is soft-deprecated: while it will not be removed in the near future, use it at your own risk. The functionality is not routinely tested.") - - output <- try (system2 ("wc", args = "--help", stdout = TRUE, stderr = TRUE), silent = TRUE) - if (class (output) == "try-error") - return (NULL) +wc <- function(file, flags = c("lines", "words", "bytes")) { + .Deprecated( + new = "count_lines", + msg = "wc() is soft-deprecated: while it will not be removed in the near future, use it at your own risk. The functionality is not routinely tested." + ) + + output <- try(system2("wc", args = "--help", stdout = TRUE, stderr = TRUE), silent = TRUE) + if (class(output) == "try-error") { + return(NULL) + } + + output <- paste("wc", paste("--", flags, sep = "", collapse = " "), file) + output <- read.table(pipe(output)) + colnames(output) <- c(flags, "file") - output <- paste ("wc", paste ("--", flags, sep = "", collapse = " "), file) - output <- read.table(pipe (output)) - colnames (output) <- c(flags, "file") - output } -.test (wc) <- function (){ - context ("wc") +.test(wc) <- function() { + context("wc") tmpfile <- tempfile() - on.exit (unlink (tmpfile)) + on.exit(unlink(tmpfile)) writeLines("blabla\nblubb", con = tmpfile) test_that("wc defaults", { skip_if_not_fileio_available() # see issue #97 - suppressWarnings(res <- wc (tmpfile)) - - if (is.null (res)) - skip ("wc not available") + suppressWarnings(res <- wc(tmpfile)) + + if (is.null(res)) { + skip("wc not available") + } - if (.Platform$OS.type == "windows") - expect_equal(res, data.frame (lines = 2, - words = 2, - bytes = 15, ## additional CR bytes on windows. - file = tmpfile)) - else - expect_equal(res, data.frame (lines = 2, - words = 2, - bytes = 13, - file = tmpfile)) + if (.Platform$OS.type == "windows") { + expect_equal(res, data.frame( + lines = 2, + words = 2, + bytes = 15, ## additional CR bytes on windows. + file = tmpfile + )) + } else { + expect_equal(res, data.frame( + lines = 2, + words = 2, + bytes = 13, + file = tmpfile + )) + } }) @@ -59,11 +68,11 @@ wc <- function (file, flags = c("lines", "words", "bytes")){ test_that("wc --lines", { skip_if_not_fileio_available() # see issue #97 - suppressWarnings(res <- wc (tmpfile, flags = "lines")) - if (is.null (res)) - skip ("wc not available") + suppressWarnings(res <- wc(tmpfile, flags = "lines")) + if (is.null(res)) { + skip("wc not available") + } - expect_equal(res, data.frame (lines = 2, file = tmpfile)) + expect_equal(res, data.frame(lines = 2, file = tmpfile)) }) - -} \ No newline at end of file +} diff --git a/hyperSpec/R/wl.R b/hyperSpec/R/wl.R index 5075eee6e..8d4c9ae6a 100644 --- a/hyperSpec/R/wl.R +++ b/hyperSpec/R/wl.R @@ -33,21 +33,21 @@ ##' ##' wl (laser) ##' -wl <- function (x){ - chk.hy (x) - validObject (x) +wl <- function(x) { + chk.hy(x) + validObject(x) x@wavelength } -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### .wl ### ### -".wl<-" <- function (x, value){ +".wl<-" <- function(x, value) { x@wavelength <- value - spc <- .fix_spc_colnames (x) + spc <- .fix_spc_colnames(x) x } @@ -77,32 +77,31 @@ wl <- function (x){ ##' wl (chondro) <- list (wl = 1e7 / (1e7/785 - wl (chondro)), label = expression (lambda / nm)) ##' plot (chondro [1]) ##' -"wl<-" <- function (x, label = NULL, digits = 6, value){ +"wl<-" <- function(x, label = NULL, digits = 6, value) { + chk.hy(x) + validObject(x) - chk.hy (x) - validObject (x) - - if (is.list (value)){ + if (is.list(value)) { label <- value$label value <- value$wl } - .wl (x) <- value + .wl(x) <- value x@label$.wavelength <- label - validObject (x) + validObject(x) x } -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ##' Convert different wavelength units -##' -##' The following units can be converted into each other: -##' \emph{nm}, \emph{\eqn{cm^{-1}}{inverse cm}}, \emph{eV}, \emph{THz} and -##' \emph{Raman shift} +##' +##' The following units can be converted into each other: +##' \emph{nm}, \emph{\eqn{cm^{-1}}{inverse cm}}, \emph{eV}, \emph{THz} and +##' \emph{Raman shift} ##' ##' @param points data for conversion ##' @param src source unit @@ -110,18 +109,20 @@ wl <- function (x){ ##' @param laser laser wavelength (required for work with Raman shift) ##' @author R. Kiselev ##' @export -##' @examples +##' @examples ##' wlconv (3200, "Raman shift", "nm", laser = 785.04) ##' wlconv( 785, "nm", "invcm") -wlconv <- function(points, src, dst, laser=NULL){ +wlconv <- function(points, src, dst, laser = NULL) { SRC <- .fixunitname(src) DST <- .fixunitname(dst) - if (SRC == DST) + if (SRC == DST) { return(points) + } - if ((SRC == "raman" | DST == "raman") & is.null(laser)) + if ((SRC == "raman" | DST == "raman") & is.null(laser)) { stop("Working with Raman shift requires knowledge of laser wavelength") + } f <- paste0(SRC, "2", DST) f <- get(f) @@ -132,127 +133,133 @@ wlconv <- function(points, src, dst, laser=NULL){ ##' @param ... ignored ##' @describeIn wlconv conversion \strong{nanometers} -> \strong{Raman shift (relative wavenumber)} ##' @export -nm2raman <- function(x, laser) 1e7*(1/laser - 1/x) +nm2raman <- function(x, laser) 1e7 * (1 / laser - 1 / x) ##' @describeIn wlconv conversion \strong{nanometers} -> \strong{inverse cm (absolute wavenumber)} ##' @export -nm2invcm <- function(x, ...) 1e7/x +nm2invcm <- function(x, ...) 1e7 / x ##' @describeIn wlconv conversion \strong{nanometers} -> \strong{electronvolt} ##' @export -nm2ev <- function(x, ...) 1e9*h*c/(q*x) +nm2ev <- function(x, ...) 1e9 * h * c / (q * x) ##' @describeIn wlconv conversion \strong{nm} -> \strong{frequency in THz} ##' @export -nm2freq <- function(x, ...) 1e-3*c/x +nm2freq <- function(x, ...) 1e-3 * c / x ##' @describeIn wlconv conversion \strong{inverse cm (absolute wavenumber)} -> \strong{Raman shift (relative wavenumber)} ##' @export -invcm2raman <- function(x, laser) 1e7/laser - x +invcm2raman <- function(x, laser) 1e7 / laser - x ##' @describeIn wlconv conversion \strong{inverse cm (absolute wavenumber)} -> \strong{nanometers} ##' @export -invcm2nm <- function(x, ...) 1e7/x +invcm2nm <- function(x, ...) 1e7 / x ##' @describeIn wlconv conversion \strong{inverse cm (absolute wavenumber)} -> \strong{electronvolt} ##' @export -invcm2ev <- function(x, ...) 100*x*c*h/q +invcm2ev <- function(x, ...) 100 * x * c * h / q ##' @describeIn wlconv conversion \strong{inverse cm (absolute wavenumber)} -> \strong{frequency in THz} ##' @export -invcm2freq <- function(x, ...) nm2freq(invcm2nm(x)) +invcm2freq <- function(x, ...) nm2freq(invcm2nm(x)) ##' @describeIn wlconv conversion \strong{Raman shift (relative wavenumber)} -> \strong{inverse cm (absolute wavenumber)} ##' @export -raman2invcm <- function(x, laser) 1e7/laser - x +raman2invcm <- function(x, laser) 1e7 / laser - x ##' @describeIn wlconv conversion \strong{Raman shift (relative wavenumber)} -> \strong{nanometers} ##' @export -raman2nm <- function(x, laser) 1e7/(1e7/laser - x) +raman2nm <- function(x, laser) 1e7 / (1e7 / laser - x) ##' @describeIn wlconv conversion \strong{Raman shift (relative wavenumber)} -> \strong{electronvolt} ##' @export -raman2ev <- function(x, laser) 100*h*c*(1e7/laser - x)/q +raman2ev <- function(x, laser) 100 * h * c * (1e7 / laser - x) / q ##' @describeIn wlconv conversion \strong{Raman shift (relative wavenumber)} -> \strong{frequency in THz} ##' @export -raman2freq <- function(x, laser) nm2freq(raman2nm(x, laser)) +raman2freq <- function(x, laser) nm2freq(raman2nm(x, laser)) ##' @describeIn wlconv conversion \strong{electronvolt} -> \strong{Raman shift (relative wavenumber)} ##' @export -ev2raman <- function(x, laser) 1e7/laser - x*q/(100*h*c) +ev2raman <- function(x, laser) 1e7 / laser - x * q / (100 * h * c) ##' @describeIn wlconv conversion \strong{electronvolt} -> \strong{inverse cm (absolute wavenumber)} ##' @export -ev2invcm <- function(x, ...) q*x/(100*h*c) +ev2invcm <- function(x, ...) q * x / (100 * h * c) ##' @describeIn wlconv conversion \strong{electronvolt} -> \strong{nanometers} ##' @export -ev2nm <- function(x, ...) 1e9*h*c/(q*x) +ev2nm <- function(x, ...) 1e9 * h * c / (q * x) ##' @describeIn wlconv conversion \strong{electronvolt} -> \strong{frequency in THz} ##' @export -ev2freq <- function(x, ...) nm2freq(ev2nm(x)) +ev2freq <- function(x, ...) nm2freq(ev2nm(x)) ##' @describeIn wlconv conversion \strong{frequency in THz} -> \strong{nanometers} ##' @export -freq2nm <- function(x, ...) 1e-3*c/x +freq2nm <- function(x, ...) 1e-3 * c / x ##' @describeIn wlconv conversion \strong{frequency in THz} -> \strong{inverse cm (absolute wavenumber)} ##' @export -freq2invcm <- function(x, ...) nm2invcm(freq2nm(x)) +freq2invcm <- function(x, ...) nm2invcm(freq2nm(x)) ##' @describeIn wlconv conversion \strong{frequency in THz} -> \strong{electronvolt} ##' @export -freq2ev <- function(x, ...) nm2ev(freq2nm(x)) +freq2ev <- function(x, ...) nm2ev(freq2nm(x)) ##' @describeIn wlconv conversion \strong{frequency in THz} -> \strong{Raman shift (relative wavenumber)} ##' @export -freq2raman <- function(x, laser) nm2raman(freq2nm(x), laser) +freq2raman <- function(x, laser) nm2raman(freq2nm(x), laser) # Bring the argument to a conventional name -.fixunitname <- function(unit){ +.fixunitname <- function(unit) { unit <- gsub(" .*$", "", tolower(unit)) - if (unit %in% c("raman", "stokes", "rel", "rel.", "relative", "rel.cm-1", "rel.cm")) + if (unit %in% c("raman", "stokes", "rel", "rel.", "relative", "rel.cm-1", "rel.cm")) { return("raman") - if (unit %in% c("invcm", "energy", "wavenumber", "cm-1", "inverted", "cm")) + } + if (unit %in% c("invcm", "energy", "wavenumber", "cm-1", "inverted", "cm")) { return("invcm") - if (unit %in% c("nm", "nanometer", "wavelength")) + } + if (unit %in% c("nm", "nanometer", "wavelength")) { return("nm") - if (unit %in% c("ev", "electronvolt")) + } + if (unit %in% c("ev", "electronvolt")) { return("ev") - if (unit %in% c("freq", "frequency", "thz", "terahertz")) + } + if (unit %in% c("freq", "frequency", "thz", "terahertz")) { return("freq") - if (unit %in% c("pixel", "px", "sensor")) + } + if (unit %in% c("pixel", "px", "sensor")) { return("px") - if (unit == "file") + } + if (unit == "file") { return(unit) + } stop(paste0("'", unit, "': Unknown unit type")) } # Some physical constants -q <- 1.60217656535e-19 # elementary charge -h <- 6.6260695729e-34 # Planck's constant -c <- 299792458 # speed of light - +q <- 1.60217656535e-19 # elementary charge +h <- 6.6260695729e-34 # Planck's constant +c <- 299792458 # speed of light diff --git a/hyperSpec/R/wl2i.R b/hyperSpec/R/wl2i.R index cb59e1708..1017bca5d 100644 --- a/hyperSpec/R/wl2i.R +++ b/hyperSpec/R/wl2i.R @@ -1,4 +1,4 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### .getindex ### @@ -7,19 +7,21 @@ ## extrapolate = TRUE returns first resp. last index for wavelength outside hyperSpec@wavelength. ## extrapolate = FALSE returns NA in this case -.getindex <- function (x, wavelength, extrapolate = TRUE){ - if (! extrapolate) { - wavelength [wavelength < min (x@wavelength)] <- -Inf - wavelength [wavelength > max (x@wavelength)] <- +Inf - } - tmp <- wavelength [is.finite (wavelength)] - if (length (tmp) > 0) { - tmp <- sapply (tmp, - function (x, y) which.min (abs (x - y)), - x@wavelength) - wavelength [is.finite (wavelength)] <- tmp - } - wavelength +.getindex <- function(x, wavelength, extrapolate = TRUE) { + if (!extrapolate) { + wavelength [wavelength < min(x@wavelength)] <- -Inf + wavelength [wavelength > max(x@wavelength)] <- +Inf + } + tmp <- wavelength [is.finite(wavelength)] + if (length(tmp) > 0) { + tmp <- sapply( + tmp, + function(x, y) which.min(abs(x - y)), + x@wavelength + ) + wavelength [is.finite(wavelength)] <- tmp + } + wavelength } ##' Conversion between Wavelength and Spectra Matrix Column @@ -28,21 +30,21 @@ ##' ##' If \code{wavelength} is numeric, each of its elements is converted to the respective index. ##' Values outside the range of \code{x@@wavelength} become \code{NA}. -##' +##' ##' If the range is given as a formula (i.e. \code{start ~ end}, a sequence -##' +##' ##' index corresponding to start : index corresponding to end -##' +##' ##' is returned. If the wavelengths are not ordered, that may lead to chaos. In this case, call ##' \code{\link[hyperSpec]{orderwl}} first. -##' +##' ##' Two special variables can be used: \code{min} and \code{max}, corresponding to the lowest and ##' highest wavelength of \code{x}, respectively. -##' +##' ##' start and end may be complex numbers. The resulting index for a complex x is then -##' +##' ##' index (Re (x)) + Im (x) -##' +##' ##' @aliases wl2i ##' @param x a \code{hyperSpec} object ##' @param wavelength the wavelengths to be converted into column indices, @@ -54,165 +56,175 @@ ##' @author C. Beleites ##' @export ##' @examples -##' +##' ##' flu ##' wl2i (flu, 405 : 407) ##' wl2i (flu, 405 ~ 407) -##' -##' ## beginning of the spectrum to 407 nm +##' +##' ## beginning of the spectrum to 407 nm ##' wl2i (flu, min ~ 407) -##' -##' ## 2 data points from the beginning of the spectrum to 407 nm +##' +##' ## 2 data points from the beginning of the spectrum to 407 nm ##' wl2i (flu, min + 2i ~ 407) -##' -##' ## the first 3 data points +##' +##' ## the first 3 data points ##' wl2i (flu, min ~ min + 2i) -##' -##' ## from 490 nm to end of the spectrum +##' +##' ## from 490 nm to end of the spectrum ##' wl2i (flu, 490 ~ max) -##' -##' ## the last 8 data points +##' +##' ## the last 8 data points ##' wl2i (flu, max - 7i ~ max) -##' +##' ##' ## get 450 nm +- 3 data points -##' wl2i (flu, 450 - 3i ~ 450 + 3i) -##' -##' wl2i (flu, 300 : 400) ## all NA: +##' wl2i (flu, 450 - 3i ~ 450 + 3i) +##' +##' wl2i (flu, 300 : 400) ## all NA: ##' wl2i (flu, 600 ~ 700) ## NULL: completely outside flu's wavelength range -##' +##' ##' @importFrom lazyeval lazy lazy_eval is_formula f_eval_lhs f_eval_rhs -wl2i <- function (x, wavelength = stop ("wavelengths are required."), unlist = TRUE){ - chk.hy (x) - validObject (x) - +wl2i <- function(x, wavelength = stop("wavelengths are required."), unlist = TRUE) { + chk.hy(x) + validObject(x) + ## wavelength may have been forced already before. ## in that case, no special evaluation can be done. - ## However, we cannot know whether we have the experession forced already or not, + ## However, we cannot know whether we have the experession forced already or not, ## so we have to try - try ({ - wavelength <- lazy (wavelength) - - wavelength <- lazy_eval (wavelength, - data = list (max = max (x@wavelength), min = min (x@wavelength), - maxwl = max (x@wavelength), minwl = min (x@wavelength))) - }, silent = TRUE) + try( + { + wavelength <- lazy(wavelength) + + wavelength <- lazy_eval(wavelength, + data = list( + max = max(x@wavelength), min = min(x@wavelength), + maxwl = max(x@wavelength), minwl = min(x@wavelength) + ) + ) + }, + silent = TRUE + ) ## make sure we have a list of ranges to be converted - if (! is.list (wavelength)) - wavelength <- list (wavelength) - - results <- list () - - for (r in seq_along (wavelength)){ - + if (!is.list(wavelength)) { + wavelength <- list(wavelength) + } + + results <- list() + + for (r in seq_along(wavelength)) { + ## ~ sequence vs. scalars and : sequences - if (is_formula (wavelength [[r]])){ + if (is_formula(wavelength [[r]])) { from <- f_eval_lhs(wavelength [[r]]) to <- f_eval_rhs(wavelength [[r]]) - } else { + } else { ## sequence with : or scalar from <- NULL to <- wavelength [[r]] } - + ## conversion to indices - if (is.logical (to)) - to <- seq_len (nwl (x)) [to] - else - to <- .getindex (x, Re (to), extrapolate = FALSE) + Im (to) + if (is.logical(to)) { + to <- seq_len(nwl(x)) [to] + } else { + to <- .getindex(x, Re(to), extrapolate = FALSE) + Im(to) + } - if (is.null (from)) { + if (is.null(from)) { results [[r]] <- to - results [[r]][! is.finite(results [[r]])] <- NA + results [[r]][!is.finite(results [[r]])] <- NA } else { - from <- .getindex (x, Re (from), extrapolate = FALSE) + Im (from) + from <- .getindex(x, Re(from), extrapolate = FALSE) + Im(from) ## completely outside range - results [[r]] <- NULL - + results [[r]] <- NULL + ## start outside left if (from == -Inf) from <- 1 - + ## end outside right - if (to == Inf) to <- nwl (x) - - if (is.finite(from) && is.finite(to)){ - ## crop indices to range: + if (to == Inf) to <- nwl(x) + + if (is.finite(from) && is.finite(to)) { + ## crop indices to range: ## outside range indices can happen with complex wavelength specifications like min - 1i if (from < 1L) from <- 1L - if (to > nwl (x)) to <- nwl (x) - - results [[r]] <- seq (from, to) + if (to > nwl(x)) to <- nwl(x) + + results [[r]] <- seq(from, to) } } } - if (unlist) - unlist (results) - else + if (unlist) { + unlist(results) + } else { results + } } -.test (wl2i) <- function (){ - context ("wl2i") +.test(wl2i) <- function() { + context("wl2i") test_that(": sequence of wavelengths", { - skip ("skip") - expect_equal(wl2i (flu, 405 : 407), c (1, 3, 5)) + skip("skip") + expect_equal(wl2i(flu, 405:407), c(1, 3, 5)) }) - + test_that("~ sequence of indices", { - expect_equal(wl2i (flu, 405 ~ 407), 1 : 5) + expect_equal(wl2i(flu, 405 ~ 407), 1:5) }) - + test_that("min special variables", { - expect_equal(wl2i (flu, min ~ 407), 1 : 5) - expect_equal(wl2i (flu, min + 2i ~ 407), 3 : 5) - expect_equal(wl2i (flu, min ~ min + 2i), 1 : 3) + expect_equal(wl2i(flu, min ~ 407), 1:5) + expect_equal(wl2i(flu, min + 2i ~ 407), 3:5) + expect_equal(wl2i(flu, min ~ min + 2i), 1:3) }) - + test_that("max special variables", { - expect_equal(wl2i (flu, 493 ~ max), 177 : 181) - expect_equal(wl2i (flu, max - 7i ~ max - 2i), 174 : 179) + expect_equal(wl2i(flu, 493 ~ max), 177:181) + expect_equal(wl2i(flu, max - 7i ~ max - 2i), 174:179) }) - + test_that("complex numbers for indices", { - expect_equal(wl2i (flu, 450 - 3i ~ 450 + 3i), 88 : 94) - + expect_equal(wl2i(flu, 450 - 3i ~ 450 + 3i), 88:94) + ## hitting range - expect_equal (wl2i (flu, min - 1i ~ max + 1i), seq_len (nwl (flu))) - + expect_equal(wl2i(flu, min - 1i ~ max + 1i), seq_len(nwl(flu))) }) test_that("logical indices", { - expect_equal(wl2i (flu, c (TRUE, TRUE, TRUE, rep (FALSE, nwl (flu) - 3))), 1 : 3) + expect_equal(wl2i(flu, c(TRUE, TRUE, TRUE, rep(FALSE, nwl(flu) - 3))), 1:3) }) - - + + test_that("behavior outside spectral range", { ## completely outside range - tmp <- wl2i (flu, 300 : 400) - expect_true (all (is.na (tmp))) - expect_equal(length (tmp), 101) + tmp <- wl2i(flu, 300:400) + expect_true(all(is.na(tmp))) + expect_equal(length(tmp), 101) + + expect_true(is.null(wl2i(flu, 600 ~ 700))) - expect_true (is.null (wl2i (flu, 600 ~ 700))) - ## one side outside - expect_equal (wl2i (flu, 400 ~ 407), 1 : 5) - expect_equal (wl2i (flu, 490 ~ 500), 171 : 181) - + expect_equal(wl2i(flu, 400 ~ 407), 1:5) + expect_equal(wl2i(flu, 490 ~ 500), 171:181) + ## enclosing range - expect_equal (wl2i (flu, 400 ~ 500), seq_len (nwl (flu))) + expect_equal(wl2i(flu, 400 ~ 500), seq_len(nwl(flu))) }) - + test_that("list of ranges", { - expect_equal(wl2i (flu, c (300 : 400, 405 ~ 407, min ~ min + 2i)), - c (wl2i (flu, 300 : 400), wl2i (flu, 405 ~ 407), wl2i (flu, min ~ min + 2i))) - - expect_equal (wl2i (flu, c (min ~ min + 5i, 405 ~ 407), unlist = TRUE), c (1:6, 1:5)) - expect_equal (wl2i (flu, c (min ~ min + 5i, 405 ~ 407), unlist = FALSE), list (1:6, 1:5)) + expect_equal( + wl2i(flu, c(300:400, 405 ~ 407, min ~ min + 2i)), + c(wl2i(flu, 300:400), wl2i(flu, 405 ~ 407), wl2i(flu, min ~ min + 2i)) + ) + + expect_equal(wl2i(flu, c(min ~ min + 5i, 405 ~ 407), unlist = TRUE), c(1:6, 1:5)) + expect_equal(wl2i(flu, c(min ~ min + 5i, 405 ~ 407), unlist = FALSE), list(1:6, 1:5)) }) - - test_that ("inside extraction", {}) + + test_that("inside extraction", {}) } ##' @rdname wl2i @@ -220,15 +232,15 @@ wl2i <- function (x, wavelength = stop ("wavelengths are required."), unlist = T ##' @return \code{i2wl} returns a numeric with the wavelengths ##' @export ##' @examples -##' +##' ##' i2wl (chondro, 17:20) -##' -i2wl <- function (x, i){ - chk.hy (x) - validObject (x) +##' +i2wl <- function(x, i) { + chk.hy(x) + validObject(x) x@wavelength [i] } ## check for wrong complex invocation -## grepl("[(][[:digit:].]+[+-][[:digit:].]+i[)]", deparse (substitute (1i %~% max - 3i | 2800 %~% 3000, list (max = 3000)))) \ No newline at end of file +## grepl("[(][[:digit:].]+[+-][[:digit:].]+i[)]", deparse (substitute (1i %~% max - 3i | 2800 %~% 3000, list (max = 3000)))) diff --git a/hyperSpec/R/wleval.R b/hyperSpec/R/wleval.R index 869fc66c7..dc577fcaf 100644 --- a/hyperSpec/R/wleval.R +++ b/hyperSpec/R/wleval.R @@ -14,62 +14,76 @@ ##' @author C. Beleites ##' @examples ##' plot (wl.eval (laser, exp = function (x) exp (-x))) -wl.eval <- function (x, ..., normalize.wl = I){ - chk.hy (x) - validObject (x) +wl.eval <- function(x, ..., normalize.wl = I) { + chk.hy(x) + validObject(x) - fun <- list (...) + fun <- list(...) - wl <- normalize.wl (x@wavelength) + wl <- normalize.wl(x@wavelength) - x <- decomposition (x, t (sapply (fun, function (f) f (wl))), scores = FALSE) - x$.f <- if (is.null (names (fun))) - rep (NA, length (fun)) - else - names (fun) + x <- decomposition(x, t(sapply(fun, function(f) f(wl))), scores = FALSE) + x$.f <- if (is.null(names(fun))) { + rep(NA, length(fun)) + } else { + names(fun) + } x } ##' @include unittest.R -.test (wl.eval) <- function (){ - context ("wl.eval") +.test(wl.eval) <- function() { + context("wl.eval") test_that("error on function not returning same length as input", { - expect_error (wl.eval (flu, function (x) 1)) + expect_error(wl.eval(flu, function(x) 1)) }) test_that("wl.eval against manual evaluation", { - expect_equivalent (wl.eval (flu, function (x) rep (5, length (x)), normalize.wl = normalize01) [[]], - matrix (rep (5, nwl (flu)), nrow = 1)) - - expect_equivalent (wl.eval (flu, function (x) x), - vanderMonde(flu, 1)[2]) - - expect_equivalent (wl.eval (flu, function (x) exp (-x)) [[]], - matrix (exp (-flu@wavelength), nrow = 1)) + expect_equivalent( + wl.eval(flu, function(x) rep(5, length(x)), normalize.wl = normalize01) [[]], + matrix(rep(5, nwl(flu)), nrow = 1) + ) + + expect_equivalent( + wl.eval(flu, function(x) x), + vanderMonde(flu, 1)[2] + ) + + expect_equivalent( + wl.eval(flu, function(x) exp(-x)) [[]], + matrix(exp(-flu@wavelength), nrow = 1) + ) }) test_that("normalization", { - expect_equivalent (wl.eval (flu, function (x) rep (5, length (x)), normalize.wl = normalize01) [[]], - matrix (rep (5, nwl (flu)), nrow = 1)) - - expect_equivalent (wl.eval (flu, function (x) x, normalize.wl = normalize01) [[]], - matrix (seq (0, 1, length.out = nwl (flu)), nrow = 1)) - - expect_equivalent (wl.eval (flu, function (x) exp (x), normalize.wl = normalize01) [[]], - matrix (exp (seq (0, 1, length.out = nwl (flu))), nrow = 1)) + expect_equivalent( + wl.eval(flu, function(x) rep(5, length(x)), normalize.wl = normalize01) [[]], + matrix(rep(5, nwl(flu)), nrow = 1) + ) + + expect_equivalent( + wl.eval(flu, function(x) x, normalize.wl = normalize01) [[]], + matrix(seq(0, 1, length.out = nwl(flu)), nrow = 1) + ) + + expect_equivalent( + wl.eval(flu, function(x) exp(x), normalize.wl = normalize01) [[]], + matrix(exp(seq(0, 1, length.out = nwl(flu))), nrow = 1) + ) }) test_that("multiple functions", { - expect_equivalent (wl.eval (flu, function (x) rep (1, length (x)), function (x) x), - vanderMonde(flu, 1)) - + expect_equivalent( + wl.eval(flu, function(x) rep(1, length(x)), function(x) x), + vanderMonde(flu, 1) + ) }) test_that("function names", { - tmp <- wl.eval (flu, f = function (x) x, g = function (x) exp (-x)) + tmp <- wl.eval(flu, f = function(x) x, g = function(x) exp(-x)) - expect_equal(tmp$.f, c ("f", "g")) + expect_equal(tmp$.f, c("f", "g")) }) } diff --git a/hyperSpec/R/write.txt.long.R b/hyperSpec/R/write.txt.long.R index 3cee20ae9..34720e5d0 100644 --- a/hyperSpec/R/write.txt.long.R +++ b/hyperSpec/R/write.txt.long.R @@ -1,4 +1,4 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### write.txt.long ### @@ -23,77 +23,91 @@ ##' @rdname textio ##' @export ##' @importFrom utils write.table -write.txt.long <- function (object, - file = "", - order = c (".rownames", ".wavelength"), - na.last = TRUE, decreasing = FALSE, - quote = FALSE, sep = "\t", - row.names = FALSE, - cols = NULL, - col.names = TRUE, - col.labels = FALSE, # use labels instead of column names? - append = FALSE, - ...){ - validObject (object) - - col.spc <- match ("spc", colnames (object@data)) - - X <- as.long.df (object, rownames = TRUE) - - if (!is.null (order)){ - if (is.character (order)) { - tmp <- match (order, colnames (X)) - if (any (is.na (tmp))) - stop ("write.txt.long: no such columns: ", - paste (order [is.na (tmp)], collapse = ", ")) - order <- tmp +write.txt.long <- function(object, + file = "", + order = c(".rownames", ".wavelength"), + na.last = TRUE, decreasing = FALSE, + quote = FALSE, sep = "\t", + row.names = FALSE, + cols = NULL, + col.names = TRUE, + col.labels = FALSE, # use labels instead of column names? + append = FALSE, + ...) { + validObject(object) + + col.spc <- match("spc", colnames(object@data)) + + X <- as.long.df(object, rownames = TRUE) + + if (!is.null(order)) { + if (is.character(order)) { + tmp <- match(order, colnames(X)) + if (any(is.na(tmp))) { + stop( + "write.txt.long: no such columns: ", + paste(order [is.na(tmp)], collapse = ", ") + ) } + order <- tmp + } - if (length (decreasing) < length (order)) - decreasing <- rep (decreasing, length.out = length (order)) + if (length(decreasing) < length(order)) { + decreasing <- rep(decreasing, length.out = length(order)) + } - order.data <- as.list (X [, order, drop = FALSE]) + order.data <- as.list(X [, order, drop = FALSE]) - for (i in seq_along (order)){ - if (is.factor(order.data [[i]])) - order.data [[i]] <- rank (order.data [[i]], na.last = na.last | is.na (na.last)) + for (i in seq_along(order)) { + if (is.factor(order.data [[i]])) { + order.data [[i]] <- rank(order.data [[i]], na.last = na.last | is.na(na.last)) + } - if (decreasing [i]) - order.data [[i]] <- - order.data [[i]] + if (decreasing [i]) { + order.data [[i]] <- -order.data [[i]] + } } - X <- X[do.call ("order", - c (order.data, na.last = na.last | is.na (na.last), decreasing = FALSE) - ), ] + X <- X[do.call( + "order", + c(order.data, na.last = na.last | is.na(na.last), decreasing = FALSE) + ), ] } - if (is.na (na.last)) - X <- X[! is.na (X$spc), ] + if (is.na(na.last)) { + X <- X[!is.na(X$spc), ] + } - if (!is.null (cols)) + if (!is.null(cols)) { X <- X [, cols, drop = FALSE] + } - if (!row.names) + if (!row.names) { X$.rownames <- NULL - else - cln [match (".rownames", cln)] <- "row" - - if (col.names){ - if (col.labels){ - cln <- match (colnames (X), names (object@label)) - cln[!is.na (cln)] <- object@label [cln[!is.na(cln)]] - cln[is.na (cln)] <- colnames (X) [is.na(cln)] - cln <- sapply (cln, as.character) + } else { + cln [match(".rownames", cln)] <- "row" + } + + if (col.names) { + if (col.labels) { + cln <- match(colnames(X), names(object@label)) + cln[!is.na(cln)] <- object@label [cln[!is.na(cln)]] + cln[is.na(cln)] <- colnames(X) [is.na(cln)] + cln <- sapply(cln, as.character) } else { - cln <- colnames (X) + cln <- colnames(X) } - write.table (matrix (cln, nrow = 1), file = file, append = append, - quote = quote, sep = sep, row.names = FALSE, col.names = FALSE) + write.table(matrix(cln, nrow = 1), + file = file, append = append, + quote = quote, sep = sep, row.names = FALSE, col.names = FALSE + ) append <- TRUE } - - write.table (X, file, append = append, quote = quote, sep = sep, - row.names = FALSE, col.names = FALSE, ...) + + write.table(X, file, + append = append, quote = quote, sep = sep, + row.names = FALSE, col.names = FALSE, ... + ) } diff --git a/hyperSpec/R/write.txt.wide.R b/hyperSpec/R/write.txt.wide.R index 53577c39e..e413012b2 100644 --- a/hyperSpec/R/write.txt.wide.R +++ b/hyperSpec/R/write.txt.wide.R @@ -1,4 +1,4 @@ -###----------------------------------------------------------------------------- +### ----------------------------------------------------------------------------- ### ### write.txt.wide ### @@ -9,80 +9,94 @@ ##' @rdname textio ##' @export ##' @importFrom utils write.table -##' +##' -write.txt.wide <- function (object, - file = "", - cols = NULL, - quote = FALSE, sep = "\t", - row.names = FALSE, - col.names = TRUE, - header.lines = 1, # 1 or 2 line header? - # use labels instead of column names? - col.labels = if (header.lines == 1) FALSE else TRUE, - append = FALSE, - ...){ - validObject (object) +write.txt.wide <- function(object, + file = "", + cols = NULL, + quote = FALSE, sep = "\t", + row.names = FALSE, + col.names = TRUE, + header.lines = 1, # 1 or 2 line header? + # use labels instead of column names? + col.labels = if (header.lines == 1) FALSE else TRUE, + append = FALSE, + ...) { + validObject(object) - if (! is.null (cols)) + if (!is.null(cols)) { object <- object [, cols] + } - if (col.names){ - col.spc <- match ("spc", colnames (object@data)) + if (col.names) { + col.spc <- match("spc", colnames(object@data)) - if (col.labels){ - cln <- match (colnames (object@data), names (object@label)) - cln[!is.na (cln)] <- object@label [cln[!is.na(cln)]] - cln[is.na (cln)] <- colnames (object@data) [is.na(cln)] - cln <- sapply (cln, as.character) - #cln [-col.spc] <- object@label [] + if (col.labels) { + cln <- match(colnames(object@data), names(object@label)) + cln[!is.na(cln)] <- object@label [cln[!is.na(cln)]] + cln[is.na(cln)] <- colnames(object@data) [is.na(cln)] + cln <- sapply(cln, as.character) + # cln [-col.spc] <- object@label [] } else { - cln <- colnames (object@data) + cln <- colnames(object@data) } - i <- seq_along (cln) + i <- seq_along(cln) - if (header.lines == 1){ - write.table (matrix (c(if (row.names) "" else NULL, - cln [i < col.spc], - object@wavelength, - cln [i > col.spc] - ), nrow = 1), - file = file, append = append, quote = quote, sep = sep, - row.names = FALSE, col.names = FALSE) - append = TRUE + if (header.lines == 1) { + write.table(matrix(c( + if (row.names) "" else NULL, + cln [i < col.spc], + object@wavelength, + cln [i > col.spc] + ), nrow = 1), + file = file, append = append, quote = quote, sep = sep, + row.names = FALSE, col.names = FALSE + ) + append <- TRUE } else if (header.lines == 2) { ## 1st line - write.table (matrix (c ( - if (row.names) "" else NULL, - cln [i < col.spc], - if (col.labels) cln [col.spc] else "", - rep ("", length (object@wavelength) - 1), - cln [i > col.spc]), nrow = 1), - file = file, append = append, quote = quote, sep = sep, - row.names = FALSE, col.names = FALSE) - append = TRUE + write.table(matrix(c( + if (row.names) "" else NULL, + cln [i < col.spc], + if (col.labels) cln [col.spc] else "", + rep("", length(object@wavelength) - 1), + cln [i > col.spc] + ), nrow = 1), + file = file, append = append, quote = quote, sep = sep, + row.names = FALSE, col.names = FALSE + ) + append <- TRUE ## 2nd line - write.table (matrix (c (if (row.names) (if (col.labels) as.character (object@label$.wavelength) - else "wavelength") - else NULL, - rep ("", sum (i < col.spc)), - object@wavelength, - rep ("", sum (i > col.spc)) - ), nrow = 1), - file = file, append = append, quote, sep, - row.names = FALSE, col.names = FALSE) - + write.table(matrix(c( + if (row.names) { + (if (col.labels) { + as.character(object@label$.wavelength) + } else { + "wavelength" + }) + } else { + NULL + }, + rep("", sum(i < col.spc)), + object@wavelength, + rep("", sum(i > col.spc)) + ), nrow = 1), + file = file, append = append, quote, sep, + row.names = FALSE, col.names = FALSE + ) } else { - stop ("Only 1 or 2 line headers supported.") + stop("Only 1 or 2 line headers supported.") } - } # no AsIs columns! - for (c in which (sapply (object@data, class) == "AsIs")) - class (object@data [[c]]) <- NULL - - write.table (object@data, file = file, append = append, quote = quote, sep = sep, - row.names = row.names, col.names = FALSE, ...) + for (c in which(sapply(object@data, class) == "AsIs")) { + class(object@data [[c]]) <- NULL + } + + write.table(object@data, + file = file, append = append, quote = quote, sep = sep, + row.names = row.names, col.names = FALSE, ... + ) } diff --git a/hyperSpec/R/y-pastenames.R b/hyperSpec/R/y-pastenames.R index 1eb08647d..f9e8ee677 100644 --- a/hyperSpec/R/y-pastenames.R +++ b/hyperSpec/R/y-pastenames.R @@ -1,17 +1,21 @@ -.pastenames <- function (...){ - if (nargs () == 1L & is.list (..1)) +.pastenames <- function(...) { + if (nargs() == 1L & is.list(..1)) { dots <- ..1 - else - dots <- list (...) + } else { + dots <- list(...) + } - names <- names (dots) - names <- sapply (names, - function (x){ - if (nchar (x) > 0L) - sprintf ("%s = ", x) - else - "" - }) + names <- names(dots) + names <- sapply( + names, + function(x) { + if (nchar(x) > 0L) { + sprintf("%s = ", x) + } else { + "" + } + } + ) - paste (names, dots, collapse = ", ", sep = "") + paste(names, dots, collapse = ", ", sep = "") } diff --git a/hyperSpec/R/zzz.R b/hyperSpec/R/zzz.R index beb7d55af..9a5a1bfec 100644 --- a/hyperSpec/R/zzz.R +++ b/hyperSpec/R/zzz.R @@ -1,17 +1,17 @@ -.onAttach <- function (libname, pkgname){ +.onAttach <- function(libname, pkgname) { unlockBinding(".options", asNamespace("hyperSpec")) desc <- utils::packageDescription("hyperSpec") vers <- paste("V. ", desc$Version) - packageStartupMessage ("Package ", desc$Package, ", version ", desc$Version, "\n\n", - "To get started, try\n", - ' vignette ("hyperspec")\n', - ' package?hyperSpec \n', - ' vignette (package = "hyperSpec")\n\n', - "If you use this package please cite it appropriately.\n", - " citation(\"hyperSpec\")\nwill give you the correct reference.", "\n\n", - "The project homepage is http://hyperspec.r-forge.r-project.org\n\n", - sep = "") + packageStartupMessage("Package ", desc$Package, ", version ", desc$Version, "\n\n", + "To get started, try\n", + ' vignette ("hyperspec")\n', + " package?hyperSpec \n", + ' vignette (package = "hyperSpec")\n\n', + "If you use this package please cite it appropriately.\n", + " citation(\"hyperSpec\")\nwill give you the correct reference.", "\n\n", + "The project homepage is http://hyperspec.r-forge.r-project.org\n\n", + sep = "" + ) } -