Nothing
#' Update a code found in a directed graph based on a Klass-classification
#'
#' @inheritParams find_dates
#' @inheritParams klass_node
#'
#' @param output Either a character vector, containing one or more of the items
#' in the list below, or \code{TRUE} to include all columns.
#'
#' \describe{
#' \item{\code{"code"}}{The Klass code.}
#' \item{\code{"name"}}{The Klass name.}
#' \item{\code{"validFrom"}}{The date that the code is valid from.}
#' \item{\code{"validTo"}}{The date that the code is valid to.}
#' \item{\code{"split"}}{Logical: Does the code split into two or more codes?}
#' \item{\code{"combined"}}{Logical: Does two or more codes become this code?}
#' \item{\code{"nextCode"}}{If \code{split == FALSE}, gives the code this code changed into. \code{NA} otherwise.}
#' }
#'
#' @param combine \code{TRUE} or \code{FALSE}. See the return section.
#'
#' @param report \code{TRUE} or \code{FALSE}. See the return section.
#'
#' @return If \code{report == TRUE} and \code{length(output) > 1 | TRUE}, the
#' result will be a \code{data.frame} with number of rows equal to the number
#' of codes in the sequence of changes between the input code and output code.
#' The columns in the \code{data.frame} are specified with \code{output}.
#'
#' If \code{report == TRUE} and \code{length(output) == 1}, the result will be
#' a character vector with length equal to the number of codes in the sequence
#' of changes between the input code and output code. The contents of the
#' character vector is specified with \code{output}.
#'
#' If \code{report == FALSE} and \code{length(output) > 1 | TRUE} the result
#' will be a \code{data.frame} with one row representing the last code
#' in the change sequence and columns specified by \code{output}. If a code
#' has been split, the result will be \code{NA}. If \code{combine == FALSE}
#' and a code is the result of a combination of codes, the result will be
#' \code{NA}.
#'
#' If \code{report == FALSE} and \code{length(output) == 1}, the result will
#' be a character vector of length one, containing information about the
#' updated code specified by \code{output}. If a code has been split, the
#' result will be \code{NA}. If \code{combine == FALSE} and a code is the
#' result of a combination of codes, the result will be \code{NA}.
#'
#' @seealso See [update_klass] for updating multiple codes in one function call.
#'
#' @keywords internal
update_code <- function(graph,
code,
date = NA,
output = "code",
combine = TRUE,
report = FALSE) {
result <- update_klass_node(
graph = graph,
node = klass_node(graph, code, date = date)
)
nextCodes <- mapply(
function(node, split) {
if (split | length(node) == 0) {
return(NA_character_)
} else if (length(node) > 1) {
return(paste0(node$code, collapse = "/"))
} else {
return(node$code)
}
},
node = result$nextNodes,
split = result$split,
SIMPLIFY = TRUE
)
report_df <- data.frame(
code = result$code,
name = result$label,
validFrom = result$validFrom,
validTo = result$validTo,
split = result$split,
combined = result$combined,
nextCode = unname(nextCodes)
)
if (report) {
return(report_df[, output])
} else if (any(report_df$split) |
(!combine & any(report_df$combined)) |
length(result) == 0) {
return(NA)
} else {
return(report_df[length(result), output])
}
}
#' Update multiple Klass codes to a desired date.
#'
#' @param codes Codes to be updated.
#'
#' @param dates Optional. Can be used to specify what date each of the codes was
#' valid in. Supply a character vector of either length 1 to specify the same
#' valid date for all codes, or of the same length as \code{codes} to specify
#' valid dates for each code. The character vector(s) should have a format
#' coercible by \code{\link[base]{as.Date}}, e.g. \code{YYYY-MM-DD}. The
#' function will return an error if a code was not valid at the specified
#' date.
#'
#' @param date Optional. Can be used to specify the date the codes should be
#' updated to, e.g. if you have codes that are valid in year \code{T}, but
#' want to change the codes to the corresponding version in year \code{T-1}.
#' If unspecified (the default), the function will update codes to the most
#' recent version.
#'
#' @param graph Optional. A graph object generated by \code{\link{klass_graph}}.
#' If you're making multiple calls to [update_klass], you can save some time by
#' generating the graph beforehand and reusing it for each call to
#' [update_klass] with this parameter. If providing the graph directly, you do
#' not need to provide the \code{classification} and \code{date} parameters.
#'
#' @inheritParams klass_graph
#'
#' @inheritParams update_code
#'
#' @return If \code{output = "code"}, a vector of length \code{length(codes)}
#' containing either a code if the update is successful or \code{NA} if the
#' code has been split. If \code{combine = FALSE}, a code being combined with
#' another code will also return \code{NA}.
#'
#' If \code{output == TRUE}, a list of length \code{length(codes)} containing
#' \code{data.frame}s detailing the codes visited through the node search. The
#' tables have the following columns.
#'
#' ---
#'
#' If \code{report == TRUE} and \code{length(output) > 1 | TRUE}, the result
#' will be a list of \code{data.frame}s with number of rows equal to the
#' number of codes in the sequence of changes between the input codes and
#' output codes. The columns in the \code{data.frame}s are specified with
#' \code{output}.
#'
#' If \code{report == TRUE} and \code{length(output) == 1}, the result will be
#' a list of character vectors with length equal to the number of codes in the
#' sequence of changes between the input code and output code. The contents of
#' the character vectors is specified with \code{output}.
#'
#' If \code{report == FALSE} and \code{length(output) > 1 | TRUE} the result
#' will be a list of \code{data.frame}s with one row representing the last
#' code in the change sequence and columns specified by \code{output}. If a
#' code has been split, the result will be \code{NA}. If \code{combine ==
#' FALSE} and a code is the result of a combination of codes, the result will
#' be \code{NA}.
#'
#' If \code{report == FALSE} and \code{length(output) == 1}, the result will
#' be a character vector containing information about the updated codes
#' specified by \code{output}. If a code has been split, the result will be
#' \code{NA}. If \code{combine == FALSE} and a code is the result of a
#' combination of codes, the result will be \code{NA}.
#'
#' @export
#'
#' @examples
#' library(klassR)
#' codes <- get_klass(131, date = "2020-01-01")[["code"]]
#'
#' \dontrun{
#' updated_codes <- update_klass(codes,
#' dates = "2020-01-01",
#' classification = 131
#' )
#' }
#'
update_klass <- function(codes,
dates = NA,
classification = NULL,
date = NULL,
graph = klass_graph(classification, date),
output = "code",
report = FALSE,
combine = TRUE) {
if (!methods::hasArg(graph) & !methods::hasArg(classification)) {
stop(
"\nPlease provide either:\n",
"- A graph with the `graph` argument\n",
"- A classification ID with the `classification` argument"
)
}
# TODO Optimize by making a table of input codes, updating those, and
# returning an expanded vector based on input
simplify <- length(output) == 1 & !isTRUE(output) & !report
result <- mapply(
FUN = update_code,
code = codes,
date = dates,
SIMPLIFY = simplify,
MoreArgs = list(
graph = graph,
output = output,
combine = combine,
report = report
)
)
return(result)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.