Nothing
#' vctrs type and casting methods for labelled survey vectors
#'
#' These methods define how
#' \code{retroharmonize_labelled_spss_survey} objects interact with
#' base vectors and with each other in vctrs-based operations such as
#' concatenation, binding, and coercion.
#'
#' They ensure that labelled survey vectors:
#' \itemize{
#' \item combine safely with numeric vectors,
#' \item cast consistently to base types,
#' \item error on incompatible coercions.
#' }
#'
#' These functions are part of the internal type system and are not
#' intended to be called directly by users.
#'
#' @name labelled_spss_survey_vctrs
#' @keywords internal
NULL
#' @keywords internal
vec_cast_named <- function(x, to, ...) {
# identical to haven:::vec_cast_named()
stats::setNames(vctrs::vec_cast(x, to, ...), names(x))
}
#' @rdname labelled_spss_survey_vctrs
#' @export
vec_ptype2.retroharmonize_labelled_spss_survey.double <- function(x,
y,
...) {
double()
}
#' @rdname labelled_spss_survey_vctrs
#' @export
vec_ptype2.double.retroharmonize_labelled_spss_survey <- function(x,
y,
...) {
double()
}
#' @rdname labelled_spss_survey_vctrs
#' @export
vec_ptype2.integer.retroharmonize_labelled_spss_survey <- function(x,
y,
...) {
double()
}
#' @rdname labelled_spss_survey_vctrs
#' @export
vec_ptype2.retroharmonize_labelled_spss_survey.integer <- function(x,
y,
...) {
double()
}
#' @rdname labelled_spss_survey_vctrs
#' @export
vec_cast.double.retroharmonize_labelled_spss_survey <- function(x,
to,
...) {
vctrs::vec_cast(vctrs::vec_data(x), to)
}
#' @rdname labelled_spss_survey_vctrs
#' @export
vec_cast.integer.retroharmonize_labelled_spss_survey <- function(x,
to,
...) {
vctrs::vec_cast(vctrs::vec_data(x), to)
}
#' @rdname labelled_spss_survey_vctrs
#' @export
vec_cast.character.retroharmonize_labelled_spss_survey <- function(
x,
to,
...
) {
if (is.character(x)) {
vctrs::vec_cast(vctrs::vec_data(x), to, ...)
} else {
stop_incompatible_cast(x, to, ...)
}
}
## Prototype --------------------------------------
# see registration.R
#' @export
vec_ptype2.retroharmonize_labelled_spss_survey.retroharmonize_labelled_spss_survey <- function(
x,
y,
...,
x_arg = "",
y_arg = ""
) {
data_type <- vec_ptype2(vec_data(x),
vctrs::vec_data(y),
x_arg = x_arg,
y_arg = y_arg
)
x_labels <- labelled::val_labels(x)
y_labels <- labelled::val_labels(y)
dots <- list2(...)
if (is.null(dots)) {
dots <- list(orig_name = "")
same_in <- paste0(
attr(x, "id"), " and ",
attr(y, "id"), "."
)
} else {
same_in <- paste0(
attr(x, "id"), "$", dots$orig_name, " and ",
attr(y, "id"), "$", dots$orig_name
)
}
if (length(x_labels) == 0 || length(y_labels) == 0) {
stop_incompatible_type(
x, y,
x_arg = dots$orig_name,
y_arg = paste(names(y_labels), collapse = ", "),
details = paste0(
"Must be labelled in ", dots$orig_name
)
)
}
if (!setequal(x_labels, y_labels)) {
stop_incompatible_type(
x, y,
x_arg = paste(names(x_labels), collapse = ", "),
y_arg = paste(names(y_labels), collapse = ", "),
details = paste0(
"The labelled numeric values must be the same in ", same_in
)
)
}
if (!setequal(names(x_labels), names(y_labels))) {
stop_incompatible_type(
x, y,
x_arg = paste(names(x_labels), collapse = ", "),
y_arg = paste(names(y_labels), collapse = ", "),
details = paste0(
"The labels must be the same in ", same_in
)
)
}
if (!setequal(attr(x, "na_values"), attr(y, "na_values"))) {
stop_incompatible_type(
x, y,
x_arg = paste(names(attr(x, "na_values")), collapse = ", "),
y_arg = paste(names(attr(y, "na_values")), collapse = ", "),
message = paste0(
"The na_values attributes are not the same in ",
same_in
)
)
}
if (!setequal(attr(x, "na_range"), attr(y, "na_range"))) {
stop_incompatible_type(
x, y,
x_arg = paste(names(attr(x, "na_range")), collapse = ", "),
y_arg = paste(names(attr(y, "na_range")), collapse = ", "),
message = paste0(
"The na_range attributes are not the same in ", same_in
)
)
}
x_labels <- vec_cast_named(attr(x, "labels"), data_type, x_arg = x_arg)
y_labels <- vec_cast_named(attr(y, "labels"), data_type, x_arg = y_arg)
x_label <- attr(x, "label")
y_label <- attr(y, "label")
x_id <- attr(x, "id")
y_id <- attr(y, "id")
x_attr_names <- names(attributes(x))
y_attr_names <- names(attributes(y))
x_orig_attr <- x_attr_names[which(x_attr_names == paste0(x_id, "_name"))]
y_orig_attr <- y_attr_names[which(y_attr_names == paste0(y_id, "_name"))]
x_orig_name <- as.character(attr(x, x_orig_attr[1]))
y_orig_name <- as.character(attr(y, y_orig_attr[1]))
name_orig <- paste(vec_c(x_orig_name, y_orig_name), collapse = ", ")
x_na_values <- attr(x, "na_values")
y_na_values <- attr(y, "na_values")
x_na_range <- attr(x, "na_range")
y_na_range <- attr(y, "na_range")
label <- x_label
if (!identical(x_label, y_label)) {
# strip labels if not compatible
if (is.null(x_label)) {
label <- y_label
}
}
id <- "multi-wave"
s1 <- attributes(x)
s2 <- attributes(y)
c_vector <- new_labelled_spss_survey(
x = vec_c(vctrs::vec_data(x), vctrs::vec_data(y)),
labels = x_labels,
label = label,
id = id,
na_values = x_na_values,
na_range = x_na_range,
name_orig = name_orig
)
for (x_attr in setdiff(names(s1), names(s2))) {
# Copy the history of x to the new vector
attr(c_vector, x_attr) <- attr(x, x_attr)
}
for (y_attr in setdiff(names(s2), names(s1))) {
# Copy the history of y to the new vector
attr(c_vector, y_attr) <- attr(y, y_attr)
}
c_vector
}
#' @export
vec_cast.retroharmonize_labelled_spss_survey.retroharmonize_labelled_spss_survey <- function(
x,
to, ...,
x_arg = "",
to_arg = ""
) {
out_data <- vec_cast(vctrs::vec_data(x),
vctrs::vec_data(to),
x_arg = x_arg,
to_arg = to_arg
)
x_labels <- labelled::val_labels(x)
x_label <- attr(x, "label")
to_label <- attr(to, "label")
x_id <- attr(x, "id")
to_id <- attr(to, "id")
x_attr_names <- names(attributes(x))
to_attr_names <- names(attributes(to))
x_orig_attr <- x_attr_names[which(x_attr_names == paste0(x_id, "_name"))]
to_orig_attr <- to_attr_names[which(to_attr_names == paste0(to_id, "_name"))]
x_orig_name <- as.character(attr(x, x_orig_attr[1]))
to_orig_name <- as.character(attr(to, to_orig_attr[1]))
name_orig <- paste(vec_c(x_orig_name, to_orig_name), collapse = ", ")
x_na_values <- attr(x, "na_values")
to_na_values <- attr(to, "na_values")
x_na_range <- attr(x, "na_range")
to_na_range <- attr(to, "na_range")
label <- x_label
if (!identical(x_label, to_label)) {
# strip labels if not compatible
if (is.null(x_label)) {
label <- to_label
}
}
id <- paste(vec_c(x_id, to_id), collapse = ", ")
out <- new_labelled_spss_survey(
out_data,
labels = x_labels,
label = label,
id = id,
na_values = x_na_values,
na_range = x_na_range,
name_orig = name_orig
)
# do we lose tagged na values? from haven
if (is.double(x) && !is.double(out)) {
lossy <- haven::is_tagged_na(x)
maybe_lossy_cast(out, x, to, lossy,
x_arg = x_arg,
to_arg = to_arg,
details = "Only doubles can hold tagged na values."
)
}
out
}
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.