degroup.numeric <- function(x,
...,
means = NULL,
center = "mean",
suffix_demean = "_within",
suffix_groupmean = "_between") {
dat <- data.frame(x, ...)
x_name <- insight::safe_deparse(substitute(x))
colnames(dat)[1] <- x_name
if (is.null(means)) {
group_cols <- colnames(dat)[-1]
dat_degrouped <- degroup(dat,
select = colnames(dat)[1],
by = group_cols,
center = center,
suffix_demean = suffix_demean,
suffix_groupmean = suffix_groupmean,
append = TRUE)
cols <- colnames(dat_degrouped)
between_cols <- cols[grepl(suffix_groupmean, cols)]
within_cols <- cols[grepl(suffix_demean, cols)]
table_cols <- c(group_cols, between_cols)
means <- unique(dat_degrouped[table_cols])
out <- dat_degrouped[c(between_cols, within_cols)]
} else {
dat_groupmeans <- data_join(dat, means)
cols <- colnames(dat_groupmeans)
between_cols <- cols[grepl(suffix_groupmean, cols)]
# # Replace missing with grandmeans?
# if (anyNA(dat_groupmeans[between_cols])) {
# grand_means <- lapply(means[between_cols], mean, na.rm = TRUE)
#
# for (nm in names(grand_means)) {
# dat_groupmeans[is.na(dat_groupmeans[[nm]]),nm] <- grand_means[[nm]]
# }
# }
sum_group_means <- Reduce("+", dat_groupmeans[between_cols])
dat_groupmeans$x_within <- dat_groupmeans[[x_name]] - sum_group_means
out <- dat_groupmeans[c(between_cols, "x_within")]
colnames(out)[ncol(out)] <- paste0(x_name, suffix_demean)
out <- as.matrix(out)
}
out <- as.matrix(out)
rownames(out) <- NULL
attr(out, "means") <- means
class(out) <- c("dw_degroup", class(out))
out
}
demean.numeric <- function(x,
...,
means = NULL,
center = "mean",
suffix_demean = "_within",
suffix_groupmean = "_between") {
cl <- match.call()
cl[[1]] <- quote(datawizard::degroup)
cl$center <- "mean"
eval.parent(cl)
}
dat <- data.frame(
a = c(1, 2, 3, 4, 1, 2, 3, 4),
x = c(4, 3, 3, 4, 1, 2, 1, 2),
y = c(1, 2, 1, 2, 4, 3, 2, 1),
ID = c(1, 2, 3, 1, 2, 3, 1, 2)
)
makepredictcall.dw_degroup <- function(var, call) {
call$means <- attr(var, "means")
call
}
This will allow using
demean()ordegroup()inside a formula, which can then play nice with brms or marginaleffects etc...Code
Example: