blob: 7b129476eb7ab9042041dd33d6903720405519cd [file] [log] [blame]
# File src/library/utils/R/modifyList.R
# Part of the R package, https://www.R-project.org
#
# Copyright (C) 1995-2018 The R Core Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of the GNU General Public License is available at
# https://www.R-project.org/Licenses/
### Originates from Deepayan Sarkar as updateList() from 'lattice' package
modifyList <- function(x, val, keep.null = FALSE)
{
stopifnot(is.list(x), is.list(val))
xnames <- names(x)
vnames <- names(val)
## Will not update unnamed components. FIXME: What if names are repeated? Warn?
vnames <- vnames[nzchar(vnames)]
if (keep.null) {
for (v in vnames) {
x[v] <-
if (v %in% xnames && is.list(x[[v]]) && is.list(val[[v]]))
list(modifyList(x[[v]], val[[v]], keep.null = keep.null))
else val[v]
}
}
else {
for (v in vnames) {
x[[v]] <-
if (v %in% xnames && is.list(x[[v]]) && is.list(val[[v]]))
modifyList(x[[v]], val[[v]], keep.null = keep.null)
else val[[v]]
}
}
x
}
## Originally from package 'nlme' -- used in its lmList() and nlsList():
## Collect errors from a list 'x',
## produce a "summary warning" and keep that as "warningMsg" attribute
warnErrList <- function(x, warn = TRUE, errValue = NULL) {
errs <- vapply(x, inherits, NA, what = "error")
if(any(errs)) {
v.err <- x[errs]
e.call <- paste(deparse(conditionCall(v.err[[1]])), collapse = "\n")
tt <- table(vapply(v.err, conditionMessage, ""))
msg <-
if(length(tt) == 1L)
sprintf(ngettext(tt[[1L]],
"%d error caught in %s: %s",
"%d times caught the same error in %s: %s"),
tt[[1L]], e.call, names(tt)[[1L]])
else ## at least two different errors caught
paste(gettextf(
"%d errors caught in %s. The error messages and their frequencies are",
sum(tt), e.call),
paste(capture.output(sort(tt)), collapse="\n"), sep="\n")
if(warn)
warning(msg, call. = FALSE, domain = NA)
x[errs] <- list(errValue)
attr(x, "warningMsg") <- msg
}
x
}