Skip to content

Commit fbb1b15

Browse files
committed
see #812
1 parent e723924 commit fbb1b15

File tree

3 files changed

+31
-45
lines changed

3 files changed

+31
-45
lines changed

R/check_group_variation.R

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,15 @@
5050
#' These variables can have one of the following three labels:
5151
#' - _between_ - the variable is fixed (has exactly one unique, constant value)
5252
#' for each group.
53+
#' - _nested_ - the variable vary within each group, with each group having
54+
#' their own set of unique levels of the variable.
5355
#' - _within_ - the variable is _crossed_ with the grouping variable - each
5456
#' value appear within each group. The `tolerance_factor` argument controls if
5557
#' full balance is also required.
5658
#' - _both_ - the variable is partially nested within the grouping variable (or,
5759
#' when `tolerance_factor = "balanced"` the variable is fully crossed, but not
5860
#' perfectly balanced).
5961
#'
60-
#' Additionally, if variables are nested within the groups (i.e. variables vary
61-
#' within each group indicated in `by`, with each group having their own set of
62-
#' unique levels of the variable), a _nested_ label is added,
63-
#'
6462
#' ## Heterogeneity bias
6563
#' Variables that vary both within and between groups can cause a heterogeneity
6664
#' bias (_Bell and Jones, 2015_). It is recommended to center (person-mean
@@ -271,6 +269,7 @@ summary.check_group_variation <- function(x, ...) {
271269
"green"
272270
))
273271
}
272+
invisible(result)
274273
}
275274

276275

@@ -329,7 +328,13 @@ summary.check_group_variation <- function(x, ...) {
329328
complete <- stats::complete.cases(group, variable)
330329
group <- droplevels(as.factor(group[complete]))
331330
variable <- variable[complete]
332-
nested <- FALSE
331+
332+
# Is the variable fixed for each group?
333+
n_uniques <- tapply(variable, group, insight::n_unique)
334+
is_between <- all(n_uniques == 1L)
335+
if (is_between) {
336+
return("between")
337+
}
333338

334339
# Is the variable nested within each group?
335340
if (insight::check_if_installed("Matrix", reason = "for checking nested designs")) {
@@ -345,40 +350,33 @@ summary.check_group_variation <- function(x, ...) {
345350
"CsparseMatrix"
346351
)
347352
if (all(sm@p[2:(k + 1L)] - sm@p[1:k] <= 1L)) {
348-
nested <- TRUE
353+
return("nested")
349354
}
350355
}
351356

352-
# Is the variable fixed for each group?
353-
n_uniques <- tapply(variable, group, insight::n_unique)
354-
is_between <- all(n_uniques == 1L)
355-
if (is_between) {
356-
return(ifelse(nested, "between (nested)", "between"))
357-
}
358-
359357
# If each group has a different number of unique values,
360358
# then it is partially nested/crossed.
361359
if (!insight::has_single_value(n_uniques)) {
362-
return(ifelse(nested, "both (nested)", "both"))
360+
return("both")
363361
}
364362

365363
# Is the variable crossed?
366364
variable_levels <- unique(variable)
367365
has_all <- tapply(variable, group, function(v) all(variable_levels %in% v))
368366
if (!all(has_all)) {
369-
return(ifelse(nested, "both (nested)", "both"))
367+
return("both")
370368
}
371369

372370
if (tolerance_factor == "crossed") {
373-
return(ifelse(nested, "within (nested)", "within"))
371+
return("within")
374372
}
375373

376374
# Is the variable crossed and balanced?
377375
tab <- table(variable, group)
378376
is_balanced <- all(apply(tab, 2, insight::has_single_value))
379-
if (!is_balanced) {
380-
return(ifelse(nested, "both (nested)", "both"))
377+
if (is_balanced) {
378+
return("within")
381379
}
382380

383-
ifelse(nested, "within (nested)", "within")
381+
return("both")
384382
}

man/check_group_variation.Rd

Lines changed: 2 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-check_group_variation.R

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,25 @@
11
test_that("check_group_variation-1", {
2-
skip_if_not_installed("lme4")
3-
set.seed(11)
2+
43
group <- rep(LETTERS[1:3], each = 3)
54
variable1 <- rep(letters[1:3], each = 3)
5+
variable1b <- rep(letters[1:2], times = c(6, 3))
66
variable2 <- rep(letters[1:3], times = 3)
77
variable3 <- letters[1:9]
88
variable4 <- c(letters[1:5], letters[1:4])
99

10-
d <- data.frame(group, variable1, variable2, variable3, variable4)
10+
d <- data.frame(group, variable1, variable1b, variable2, variable3, variable4)
1111
out <- check_group_variation(d, by = "group")
1212

13-
out2 <- c(
14-
variable1 = lme4::isNested(variable1, group),
15-
variable2 = lme4::isNested(variable2, group),
16-
variable3 = lme4::isNested(variable3, group),
17-
variable4 = lme4::isNested(variable4, group)
18-
)
1913
expect_equal(
2014
out,
2115
data.frame(
22-
group = c("group", "group", "group", "group"),
23-
variable = c("variable1", "variable2", "variable3", "variable4"),
24-
type = c("between (nested)", "within", "both (nested)", "both")
16+
group = c("group", "group", "group", "group", "group"),
17+
variable = c("variable1", "variable1b", "variable2", "variable3", "variable4"),
18+
type = c("between", "between", "within", "nested", "both")
2519
),
2620
ignore_attr = TRUE
2721
)
28-
expect_equal(
29-
endsWith(out$type, "(nested)"),
30-
out2,
31-
ignore_attr = TRUE
32-
)
22+
3323

3424
set.seed(111)
3525
dat <- data.frame(
@@ -59,7 +49,7 @@ test_that("check_group_variation-1", {
5949
data.frame(
6050
group = c("id", "id", "id", "id", "id", "id"),
6151
variable = c("between_num", "within_num", "both_num", "between_fac", "within_fac", "both_fac"),
62-
type = c("between", "within", "both", "between (nested)", "within", "both")
52+
type = c("between", "within", "both", "between", "within", "both")
6353
),
6454
ignore_attr = TRUE
6555
)
@@ -161,7 +151,7 @@ test_that("check_group_variation, multiple by", {
161151
data.frame(
162152
group = c("schoolid", "schoolid", "schoolid", "schoolid", "childid", "childid", "childid", "childid"),
163153
variable = c("lowinc", "female", "year", "math", "lowinc", "female", "year", "math"),
164-
type = c("between (nested)", "both", "within", "both", "between", "between", "within", "both")
154+
type = c("between", "both", "within", "both", "between", "between", "within", "both")
165155
),
166156
ignore_attr = TRUE
167157
)
@@ -179,7 +169,7 @@ test_that("check_group_variation, multiple by", {
179169
"schoolid", "lowinc", "female", "year", "math"
180170
),
181171
type = c(
182-
"both (nested)", "between (nested)", "both", "within", "both",
172+
"nested", "between", "both", "within", "both",
183173
"between", "between", "between", "within", "both"
184174
)
185175
),
@@ -239,10 +229,10 @@ test_that("check_group_variation, numeric_as_factor", {
239229
)
240230
expect_identical(
241231
out1$type,
242-
c("between (nested)", "both", "within", "both", "between", "between", "within", "both")
232+
c("between", "both", "within", "both", "between", "between", "within", "both")
243233
)
244234
expect_identical(
245235
out2$type,
246-
c("between (nested)", "both", "within", "both (nested)", "between", "between", "within", "both")
236+
c("between", "both", "within", "nested", "between", "between", "within", "both")
247237
)
248238
})

0 commit comments

Comments
 (0)