grimmer_map() applies grimmer() to every row of a data
frame with means, standard deviations, and sample sizes.
Call audit() on the output for summary statistics. grim_plot_grid()
accepts it as well.
Usage
grimmer_map(
data,
digits_x,
digits_sd,
x = NULL,
sd = NULL,
n = NULL,
...,
items_averaged,
data_type,
sd_meaning = c("sd_sample", "sd_pop", "sd_sample_or_pop", "se"),
rounding = "up_or_down",
threshold = 5,
symmetric = FALSE
)Arguments
- data
Data frame with columns
x,sd, andn, and optionallyitems_averaged,data_type,digits_x, anddigits_sd. Any other columns are returned alongside the results.- digits_x, digits_sd
Integer. The number of decimal places in
xandsd, including trailing zeros. There are no defaults, since a numeric value does not keep them (1.40is1.4). Either a single number for the whole column or one number per row ofdata. If left out, they are taken fromdigits_xanddigits_sdcolumns ofdata.- x, sd, n
Optionally, the names of the columns in
datathat contain these values, if they differ from the defaults.- ...
These dots must be empty. Every argument after them must be named in full.
- items_averaged, data_type
As in
grim_map(), forxandsd.- rounding, threshold, symmetric, sd_meaning
Passed on to
grimmer(), whose section Defaults explains the defaults.
Value
A tibble with these columns:
x,sd,n: the inputs.items_averaged: the number of items averaged into each score.data_type: the kind of data, as given.digits_x,digits_sd: the numbers of decimal places, as given.consistency: GRIMMER consistency ofx,sd,n, anditems_averaged.NAfor a case that cannot be decided, such as one with a missing value.reason:"Passed all"if consistent, or"Continuous data"if the test does not apply; otherwise the test that failed, or why the case cannot be decided.Any other columns from
data.
The reason column refers to GRIM and the GRIMMER tests of Allard (2018):
The reconstructed sum of squared observations must be a whole number, and one that
nwhole numbers with the reconstructed sum can reach: at least the sum of squares of these numbers as close together as possible. Forn < 5, some larger sums of squares are impossible, too.The reconstructed SD must match the reported one. Test 1 implies this, so it is never a reason.
The parity of the reconstructed sum of squared observations must match that of the reconstructed sum of the values.
A negative sd gives "Negative SD".
Under sd_meaning = "sd_sample_or_pop", a consistent value set gives
"Passed all (sample SD)" or, if it passes as a population SD only,
"Passed all (population SD)". If the two conventions fail for different
reasons, the reason names both, and audit() counts the sample SD's,
as under the default sd_meaning.
The tibble has the class scrutiny_grimmer_map, which is recognized by
audit() and grim_plot_grid().
Summaries with audit()
audit() on grimmer_map() output
returns a tibble with one row and these columns:
all_cases: total number of value sets.incon_cases: number of GRIMMER-inconsistent value sets.emp_incon: proportion of GRIMMER-inconsistent value sets.fail_grim: number of value sets that fail GRIM.fail_test1,fail_test3: number of value sets that fail GRIMMER's first or third test. Test 2 is implied by test 1, so it never fails.
References
Allard, A. (2018). Analytic-GRIMMER: a new way of testing the possibility of standard deviations. https://aurelienallard.netlify.app/post/anaytic-grimmer-possibility-standard-deviations/
Anaya, J. (2016). The GRIMMER test: A method for testing the validity of reported measures of variability. PeerJ Preprints. https://peerj.com/preprints/2400v1/
See also
explain_map() and explain_print() to explain each row's
result in plain words.
Examples
# Use `grimmer_map()` on data like these:
pigs5
#> # A tibble: 12 × 3
#> x sd n
#> <dbl> <dbl> <dbl>
#> 1 7.22 5.3 38
#> 2 4.74 6.55 31
#> 3 5.23 2.55 35
#> 4 2.57 2.57 30
#> 5 6.77 2.18 33
#> 6 2.68 2.59 34
#> 7 7.01 6.68 35
#> 8 7.38 3.65 32
#> 9 3.14 5.32 33
#> 10 6.89 4.18 37
#> 11 5 2.18 31
#> 12 0.24 6.43 34
# The `consistency` column shows whether the values to its left are
# GRIMMER-consistent. If they aren't, the `reason` column gives the reason:
pigs5 |>
grimmer_map(
digits_x = 2,
digits_sd = 2,
items_averaged = 1,
data_type = "integer"
)
#> # A tibble: 12 × 9
#> # GRIMMER: default settings
#> x sd n items_averaged data_type digits_x digits_sd consistency
#> <dbl> <dbl> <int> <int> <chr> <int> <int> <lgl>
#> 1 7.22 5.3 38 1 integer 2 2 FALSE
#> 2 4.74 6.55 31 1 integer 2 2 TRUE
#> 3 5.23 2.55 35 1 integer 2 2 FALSE
#> 4 2.57 2.57 30 1 integer 2 2 TRUE
#> 5 6.77 2.18 33 1 integer 2 2 FALSE
#> 6 2.68 2.59 34 1 integer 2 2 TRUE
#> 7 7.01 6.68 35 1 integer 2 2 FALSE
#> 8 7.38 3.65 32 1 integer 2 2 TRUE
#> 9 3.14 5.32 33 1 integer 2 2 FALSE
#> 10 6.89 4.18 37 1 integer 2 2 TRUE
#> 11 5 2.18 31 1 integer 2 2 TRUE
#> 12 0.24 6.43 34 1 integer 2 2 TRUE
#> # ℹ 1 more variable: reason <chr>
# Get summaries with `audit()`:
pigs5 |>
grimmer_map(
digits_x = 2,
digits_sd = 2,
items_averaged = 1,
data_type = "integer"
) |>
audit()
#> # A tibble: 1 × 6
#> all_cases incon_cases emp_incon fail_grim fail_test1 fail_test3
#> <int> <int> <dbl> <int> <int> <int>
#> 1 12 5 0.417 4 0 1
# Explain the results in plain words:
pigs5 |>
grimmer_map(
digits_x = 2,
digits_sd = 2,
items_averaged = 1,
data_type = "integer"
) |>
explain_print(1:2)
#> GRIMMER test: x = 7.22, sd = 5.30, n = 38, items_averaged = 1, data_type = "integer"
#>
#> The mean was reported as 7.22, with 2 decimal places. Before rounding (assuming
#> either rounding up from 5 or down from 5), it could have been anything from
#> 7.215 to 7.225.
#>
#> The mean of 38 integers is their sum divided by 38. So the sum must be from
#> 7.215 * 38 = 274.17 to 7.225 * 38 = 274.55.
#>
#> A sum of integers is itself an integer, but there is no integer in this range.
#> The nearest ones are 274 and 275. They give 274 / 38 = 7.2105 and
#> 275 / 38 = 7.2368, which round to 7.21 and 7.24, not to 7.22. Since the mean
#> alone is impossible, the SD doesn't need to be checked.
#>
#> ==> Inconsistent
#>
#> GRIMMER test: x = 4.74, sd = 6.55, n = 31, items_averaged = 1, data_type = "integer"
#>
#> The mean was reported as 4.74, with 2 decimal places. Before rounding (assuming
#> either rounding up from 5 or down from 5), it could have been anything from
#> 4.735 to 4.745.
#>
#> The mean of 31 integers is their sum divided by 31. So the sum must be from
#> 4.735 * 31 = 146.785 to 4.745 * 31 = 147.095.
#>
#> A sum of integers is itself an integer, and 147 is in this range:
#> 147 / 31 = 4.7419, which rounds to 4.74.
#>
#> The SD was reported as 6.55, with 2 decimal places. Before rounding, it could
#> have been anything from 6.545 to 6.555.
#>
#> Together, the sum and the SD determine the sum of squares, which is what you
#> get by squaring each of the 31 values and adding them up. It is
#> (31 - 1) * SD^2 + sum^2 / 31. The values are integers, so their squares are
#> integers, too, and so is the sum of squares. What's more, an integer and its
#> square are either both odd or both even. So the sum of squares must be odd if
#> the sum is odd, and even if the sum is even.
#>
#> With a sum of 147, the sum of squares is from
#> 30 * 6.545^2 + 147^2 / 31 = 1982.1753 to 30 * 6.555^2 + 147^2 / 31 = 1986.1053.
#> The integers from 1983 to 1986 are in this range, so one of them is odd, like
#> 147.
#>
#> ==> Consistent
#>
