Nothing
# To report test coverage, run
# devtools::test_coverage()
makeData <- function(N = 40) {
set.seed(1)
data <- data.frame(Measurement = c(rnorm(N, mean = 100, sd = 25),
rnorm(N, mean = 100, sd = 50),
rnorm(N, mean = 120, sd = 25),
rnorm(N, mean = 80, sd = 50),
rnorm(N, mean = 100, sd = 12),
rnorm(N, mean = 100, sd = 50)),
Group = c(rep("ZControl1", N),
rep("Control2", N),
rep("Group1", N),
rep("Group2", N),
rep("Group3", N),
rep("Group4", N)),
Gender = rep(c(rep('Male', N/2), rep('Female', N/2)), 6),
ID = rep(1:N, 6)
)
# Shuffle
data[sample(nrow(data)), ]
}
makeES1 <- function() {
set.seed(1)
data <- makeData()
DurgaDiff(data[data$Group %in% c("ZControl1", "Group1"),], data.col = "Measurement", group.col = "Group", R = 1000)
}
makePairedData <- function(addSomeNAs = FALSE, reverseGroups = FALSE) {
N <- 40
set.seed(1)
data <- data.frame(Measurement = c(rnorm(N, mean = 100, sd = 25),
rnorm(N, mean = 100, sd = 50),
rnorm(N, mean = 120, sd = 25),
rnorm(N, mean = 80, sd = 50),
rnorm(N, mean = 100, sd = 12),
rnorm(N, mean = 100, sd = 50)),
Group = c(rep("ZControl1", N),
rep("Control2", N),
rep("Group1", N),
rep("Group2", N),
rep("Group3", N),
rep("Group4", N)),
Sex = rep(c(rep('Male', N/2), rep('Female', N/2)), 6),
ID = rep(1:N, 6)
)
if (addSomeNAs)
data[c(1, 4, 10, 65), 1] <- NA
# Shuffle
data <- data[sample(nrow(data)), ]
if (reverseGroups) {
DurgaDiff(data[data$Group %in% c("ZControl1", "Group1"),],
groups = c("ZControl1", "Group1"),
na.rm = addSomeNAs,
data.col = "Measurement", group.col = "Group", R = 1000,
id.col = "ID")
} else {
DurgaDiff(data[data$Group %in% c("ZControl1", "Group1"),],
na.rm = addSomeNAs,
data.col = "Measurement", group.col = "Group", R = 1000,
id.col = "ID")
}
}
compareDiffs <- function(d1, d2, tolerance = 0.1) {
expect_equal(d1$groups, d2$groups)
expect_equal(d1$group.names, d2$group.names)
expect_equal(d1$effect.type, d2$effect.type)
expect_equal(length(d1$group.differences), length(d2$group.differences))
for (i in seq_len(length(d1$group.differences))) {
pd1 <- d1$group.differences[[i]]
pd2 <- d2$group.differences[[i]]
expect_equal(pd1$groups, pd2$groups)
expect_equal(pd1$t0, pd2$t0)
expect_equal(pd1$R, pd2$R)
expect_equal(pd1$bca[, 1], pd2$bca[, 1])
# Columns 3 and 4 can vary randomly
expect_equal(pd1$bca[, c(4, 5)], pd2$bca[, c(4, 5)], tolerance = tolerance)
}
}
plotWithBrackets <- function(d) {
ylim <- extendrange(d$data[[d$data.col]])
ylim[2] <- extendrange(ylim, f = nrow(d$group.statistics) * 0.05)[2]
labelFn <- function(diff) sprintf("%.2g %g%% CI [%.2g, %.2g]",diff$t0, diff$bca[1] * 100, diff$bca[4], diff$bca[5])
DurgaPlot(d, ef.size = FALSE, bty = "n", ylim = ylim) |>
DurgaBrackets(labels = labelFn)
}
##########################################################################
# Tests start here ####
test_that("multiple groups + contrasts", {
n <- 30
df <- data.frame(group = c(rep(c("G1", "G2", "G3"), each = n)),
group2 = c(rep(c("A", "B"), each = 3 * n / 2)),
val = c(rnorm(n, 1), rnorm(n, 2), rnorm(n, 3)))
d <- expect_error(DurgaDiff(df, "val", c("group", "group2")), NA)
expect_equal(length(d$group.differences), 6)
# Group names should be compoiste groups after combining the two group columns
plotFn <- plotWithBrackets
plotFn <- identity
d <- expect_error(DurgaDiff(df, "val", c("group", "group2"), contrasts = c("G2, A - G1, A", "G3, B - G2, B", "G2, B - G2, A")), NA)
expect_equal(length(d$group.differences), 3)
# Attempting to use the comma-separated string version should fail due to ambiguity
expect_error(DurgaDiff(df, "val", c("group", "group2"), contrasts = c("G2, A - G1, A, G3, B - G2, B")))
# Matrix form should work
contrasts <- matrix(c("G2, A", "G1, A", "G3, B", "G2, B", "G2, B", "G2, A"), nrow = 2)
d <- DurgaDiff(df, "val", c("group", "group2"), contrasts = contrasts)
expect_equal(length(d$group.differences), 3)
})
test_that("wide to long", {
n <- 10
dfw <- data.frame(control = rnorm(n), treatment = rnorm(n, 0.2), id = seq_len(n))
dfl <- wideToLong(dfw, c("control", "treatment"))
expect_equal(nrow(dfl), 2 * n)
# The generated id values should be the same as ours
expect_equal(dfl$id.1, dfl$id)
# Group values should all be one of "control", "treatment"
expect_true(all(unique(dfl$group) %in% c("control", "treatment")))
# Specifying a NULL id col should be the same as not specifying one
dfln <- wideToLong(dfw, c("control", "treatment"), NULL)
expect_equal(dfln, dfl)
# Specifying an id column means a new one should not be generated
dfli <- wideToLong(dfw, c("control", "treatment"), "id")
expect_equal(names(dfli), c("id", "group", "value"))
expect_equal(unique(dfli$group), c("control", "treatment"))
# Unpaired in wide format
n1 <- 20
n2 <- 14
dfw <- data.frame(control = rnorm(n1), treatment = c(rnorm(n2, 0.2), rep(NA, n1 - n2)))
dfl <- wideToLong(dfw, c("control", "treatment"), NULL)
expect_equal(unique(dfl$group), c("control", "treatment"))
# Paired
dp <- DurgaDiff(dfw, groups = c("control", "treatment"), na.rm = TRUE)
expect_true(dp$paired.data)
# When paired, any ids without matched values a removed from the data set
expect_equal(sum(dp$data$group == "control"), min(n1, n2))
expect_equal(sum(dp$data$group == "treatment"), min(n1, n2))
# Unpaired
du <- DurgaDiff(dfw, groups = c("control", "treatment"), id.col = NULL, na.rm = TRUE)
expect_true(!du$paired.data)
# When unpaired, unmatched values remain, only NAs are removed
expect_equal(sum(du$data$group == "control"), n1)
expect_equal(sum(du$data$group == "treatment"), n2)
# 3 groups
n <- 20
df3 <- data.frame(control = rnorm(n), g1 = rnorm(n, 1), g2 = rnorm(n, 2))
d3 <- DurgaDiff(df3, groups = c("control", "g1", "g2"))
#DurgaPlot(d3, bty = "n") |> DurgaBrackets()
expect_equal(d3$group.names, c("control", "g1", "g2"))
expect_equal(unique(d3$data$group), c("control", "g1", "g2"))
expect_equal(length(d3$group.differences), 3)
du3 <- DurgaDiff(df3, groups = c("control", "g1", "g2"), id.col = NULL)
#DurgaPlot(du3, bty = "n") |> DurgaBrackets()
expect_equal(du3$group.names, c("control", "g1", "g2"))
expect_equal(unique(du3$data$group), c("control", "g1", "g2"))
expect_equal(length(du3$group.differences), 3)
# # How can I use wide format but include another column in the groups?
# dfw <- data.frame(control = rnorm(n), treatment = rnorm(n, 1.2), id = seq_len(n),
# species = sample(c("Sp 1", "Sp 2", "Sp 3"), n, replace = TRUE))
# # ANSWER: There is no builtin solution. First convert wide to long, then pass
# # to DurgaDiff and specify the 2nd group variable
# dfl <- wideToLong(dfw, c("control", "treatment"))
# DurgaDiff(dfl, "value", c("group", "species")) |> DurgaPlot()
})
test_that("Combine vars", {
df <- data.frame(v1 = c("A", "A", "B", "B"),
v2 = c("C", "D", "C", "D"))
expect_equal(combineVariables(df, c("v1", "v2")), c("A & C", "A & D", "B & C", "B & D"))
df <- data.frame(a = rep(1:3, each = 4), b = rep(1:4, 3))
expect_equal(combineVariables(df, 1:2), c("1 & 1", "1 & 2", "1 & 3", "1 & 4", "2 & 1", "2 & 2", "2 & 3",
"2 & 4", "3 & 1", "3 & 2", "3 & 3", "3 & 4"))
# Pathological case. Ideally this test would pass, but it has not been implemented to work, so don't run the test
# df <- data.frame(t = c("a", "a", "a & b", "b & c", "a"),
# s = c("b", "b & c", "c", "c", "b & c"))
# expect_true(all(table(combineVariables(df, 1:2)) == 1))
})
test_that("Group interactions", {
set.seed(1)
n <- 40
df2 <- data.frame(group = rep(c("A", "B"), each = n),
sex = sample(c("Female", "Male"), 2 * n, replace = TRUE))
df2$val <- ifelse(df2$group == "A", 1, 2) +
ifelse(df2$sex == "Female", 1, 0) +
rnorm(2 * n)
par(mfrow = c(2, 2))
# Define interaction by specifying 2 group variables
da <- DurgaDiff(df2, "val", c("group", "sex"))
expect_equal(length(da$groups), 4)
expect_equal(length(da$group.differences), 6)
DurgaPlot(da, bty = "n", ylim = c(-1.5, 6), ef.size = FALSE, main = "Auto interaction") |> DurgaBrackets()
# Manual interaction
df2$group_sex <- combineVariables(df2, c("group", "sex"), ", ")
dm <- DurgaDiff(df2, "val", "group_sex")
expect_equal(length(dm$groups), 4)
expect_equal(length(dm$group.differences), 6)
DurgaPlot(dm, bty = "n", ylim = c(-1.5, 6), ef.size = FALSE, main = "Manual interaction") |> DurgaBrackets()
compareDiffs(da, dm)
# 3 groups
set.seed(1)
n <- 100
df3 <- data.frame(group = rep(c("A", "B"), each = n),
sex = sample(c("Female", "Male"), 2 * n, replace = TRUE),
filter = sample(c("Filter", "No filter"), 2 * n, replace = TRUE))
df3$val <- ifelse(df3$group == "A", 5, 7) +
ifelse(df3$sex == "Female", 1, 0) +
ifelse(df3$filter == "Yes", 0.6, 0) +
rnorm(2 * n)
da <- DurgaDiff(df3, "val", c("group", "sex", "filter"))
expect_equal(length(da$groups), 8)
expect_equal(length(da$group.differences), 28)
DurgaPlot(da, bty = "n", main = "Auto interaction")
# Manual interaction
df3$group_sex <- combineVariables(df3, c("group", "sex", "filter"), ", ")
dm <- DurgaDiff(df3, "val", "group_sex")
expect_equal(length(dm$groups), 8)
expect_equal(length(dm$group.differences), 28)
DurgaPlot(dm, bty = "n", main = "Manual interaction")
compareDiffs(da, dm)
# Formula interface
set.seed(1)
par(mfrow = c(1, 2))
# Define interaction by specifying 2 group variables
f2 <- expect_error(DurgaDiff(val ~ group*sex, df2), NA)
expect_equal(length(f2$groups), 4)
expect_equal(length(f2$group.differences), 6)
DurgaPlot(f2, bty = "n", main = "Formula interface")
# Define interaction by specifying 3 group variables
f3 <- expect_error(DurgaDiff(val ~ group + sex + filter, df3), NA)
DurgaPlot(f3, bty = "n", main = "Formula interface")
})
test_that("Paired vs unpaired", {
set.seed(1)
n <- 10
effSz <- 1
ind <- rnorm(n, 10, 10)
df <- data.frame(value = c(ind, ind + effSz + rnorm(n, 0, 1)),
group = rep(c("A", "B"), each = n), id = rep(1:n, 2))
dpd <- DurgaDiff(df, "value", "group", "id", effect.type = "cohens d")
dud <- DurgaDiff(df, "value", "group", effect.type = "cohens d")
# Cohen's d should be identical for paired and unpaired
expect_equal(dpd$group.differences[[1]]$t0, dud$group.differences[[1]]$t0)
# CI width should be less for paired than unpaired
expect_lt(diff(dpd$group.differences[[1]]$bca[4:5]), diff(dud$group.differences[[1]]$bca[4:5]))
# Expect bias-correction to change a bit due to different degrees of freedom
dpg <- DurgaDiff(df, "value", "group", "id", effect.type = "hedges g")
dug <- DurgaDiff(df, "value", "group", effect.type = "hedges g")
expect_false(isTRUE(all.equal(dpg$group.differences[[1]]$t0, dug$group.differences[[1]]$t0)))
# CI width should be less for paired than unpaired
expect_lt(diff(dpg$group.differences[[1]]$bca[4:5]), diff(dug$group.differences[[1]]$bca[4:5]))
# Bias correction should have almost no effect for large sample sizes
n <- 500
ind <- rnorm(n, 10, 10)
df <- data.frame(value = c(ind, ind + effSz + rnorm(n, 0, 1)),
group = rep(c("A", "B"), each = n), id = rep(1:n, 2))
dpg <- DurgaDiff(df, "value", "group", "id", effect.type = "hedges g")
dug <- DurgaDiff(df, "value", "group", effect.type = "hedges g")
# Don't expect identical but pretty close
expect_true(isTRUE(all.equal(dpg$group.differences[[1]]$t0, dug$group.differences[[1]]$t0, tolerance = 1e-4, scale = 1)))
})
test_that("Effect size visible", {
es <- 20
set.seed(1)
vA <- rnorm(10)
df <- data.frame(group = c(rep("A", 10), rep("B", 10)), val = c(vA, vA + es + rnorm(10, 0.5)), id = rep(1:10, 2))
# This requires a human to check that the plot is valid
expect_error(DurgaPlot(DurgaDiff(val ~ group, df, effect.type = "cohens d"), main = "Is effect size entirely visible?"), NA)
expect_error(DurgaPlot(DurgaDiff(val ~ group, df, id.col = "id", effect.type = "cohens d"), main = "Is effect size entirely visible?"), NA)
#plot(cohens_d(dabestr::dabest(df, group, val, idx = c("A", "B"))))
#plot(cohens_d(dabestr::dabest(df, group, val, idx = c("A", "B"), paired = TRUE, id.column = id)))
})
test_that("paired with groups", {
data <- structure(list(Spider = c("A1", "A11", "A12", "A13", "A14", "A2", "A3", "A4", "A5", "A6", "A7", "A9", "B2", "B3", "C1", "C2", "D3", "E1", "E10", "E11", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "F1", "F2", "F3", "G01", "G02", "G03 ", "G04", "G05", "G06", "G07", "G08 ", "G09", "G10", "G11", "G12", "G13", "G14", "G15", "G16", "G17", "G18", "G19", "G20", "H01", "H02", "H03", "H04", "H05", "H06 ", "H07", "H08", "H09", "H10", "H11", "H12", "H13", "H14", "H16", "I01", "I02", "I03", "I04", "I05", "I06", "I07", "I08", "I09", "I10", "I11", "A1", "A11", "A12", "A13", "A14", "A2", "A3", "A4", "A5", "A6", "A7", "A9", "B2", "B3", "C2", "D3", "E1", "E11", "E2", "E3", "E5", "E6", "E7", "E8", "E9", "F1", "F2", "F3", "G01", "G02", "G03 ", "G04", "G05", "G06", "G07", "G08 ", "G09", "G10", "G11", "G12", "G15", "G16", "G17", "G18", "G19", "H01", "H02", "H03", "H04", "H05", "H06 ", "H07", "H08", "H09", "H10", "H11", "H13", "H14", "H15", "H16", "I01", "I02", "I03", "I04", "I05", "I06", "I07", "I09", "I10", "I11", "A1", "A11", "A12", "A13", "A2", "A3", "A4", "A5", "A6", "A7", "A9", "B2", "B3", "C2", "D3", "E1", "E3", "E5", "E6", "E7", "E8", "E9", "F1", "F2", "F3", "G03 ", "G04", "G06", "G07", "G08 ", "G09", "G10", "G12", "G13", "G14", "G15", "G16", "G17", "G18", "G19", "G20", "H01", "H02", "H03", "H04", "H05", "H06 ", "H09", "H10", "H11", "H12", "H13", "H14", "H15", "I01", "I02", "I03", "I04", "I05", "I06", "I07", "I08", "I09", "I10", "I11", "A1", "A11", "A12", "A13", "A14", "A3", "A4", "A5", "A6", "A7", "A9", "B2", "B3", "C2", "E5", "E6", "E7", "E8", "E9", "F1", "F3", "G01", "G04", "G06", "G07", "G08 ", "G09", "G10", "H01", "H02", "H03", "H04", "H06 ", "H09", "H10", "H11", "H12", "H13", "H14", "H15"),
Wrap = c(185.75, 81.25, 99.07, 301.11, 111.7, 141.6, 156.4, 276.14, 49.51, 278.94, 279.22, 170.69, 93.82, 663.66, 83.94, 155.05, 69.26, 81.62, 92.87, 36.92, 143.82, 59.84, 165.04, 56.52, 156.91, 69.26, 70.28, 99.11, 523.59, 111.91, 168.2, 631.32, 341.04, 110.86, 197.9, 289.96, 372.66, 423.38, 459.65, 120.76, 82.51, 151.3, 190.98, 68.71, 20.3, 54.18, 75.85, 80.64, 74.43, 36.4, 66.74, 108.52, 62.86, 89.06, 631.77, 219.78, 144.55, 62.01, 62.08, 371.95, 233.48, 135.79, 151.9, 210.16, 239.6, 347.78, 144.8, 177.46, 145.5, 124.84, 95.25, 119.38, 277.49, 77, 129.55, 164.2, 225.38, 131.59, 376.31, 147.63, 246.17, 148.48, 158.91, 149.49, 123.72, 131.69, 121.09, 121.72, 108.95, 224.66, 74.31, 143.31, 300.31, 318.36, 43.14, 92.9, 67.48, 131.74, 42.59, 76.07, 301.75, 38.75, 316.33, 95.66, 126.45, 171.76, 304.77, 105.25, 208.41, 257.78, 32.41, 193.61, 118.46, 90.07, 420.58, 151.14, 340.76, 77.67, 95.17, 124.56, 71.13, 130.84, 160.56, 350.49, 34.07, 468.27, 257.55, 117.44, 113.99, 95.45, 181.4, 145.99, 197.04, 139.07, 380.36, 131.72, 248.03, 297.9, 77.07, 72.37, 100.41, 641.88, 70.42, 91.82, 200.94, 83.34, 257.72, 194.93, 160.14, 104.9, 157.38, 146.97, 107.91, 197.39, 125.3, 509.2, 247.17, 343.11, 293.38, 385.48, 237.19, 256.04, 263.29, 129.2, 175.92, 86.63, 97.96, 97.59, 102.42, 204.43, 398.39, 111.3, 62.04, 64.15, 73.39, 7.04, 91.56, 190.14, 86.57, 57.65, 85.45, 98.11, 52.84, 43.77, 36.91, 134.45, 59.39, 365.75, 80.97, 156.96, 80.52, 142.83, 105.88, 83.21, 154.51, 151.05, 101.14, 124.24, 71.53, 183.64, 54.16, 100.55, 58.28, 59.27, 175.66, 195.94, 203.02, 112.22, 221.76, 176.28, 201.72, 64.77, 46.92, 87.95, 41.39, 67.25, 54.22, 45.99, 51.69, 38.44, 66.77, 68.12, 70.05, 197.7, 124.19, 475.43, 153.2, 143.39, 215.45, 152.27, 393.36, 108.23, 190.35, 123.31, 142.69, 111.12, 53.67, 105.46, 123.39, 119.8, 81.22, 60.74, 83.96, 95.81, 84.77, 170.54, 163.63, 156.01, 173.24, 161.43, 127.645, 164.02),
Prey_difficulty = c("difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "difficult", "difficult", "difficult", "difficult", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "easy", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "easy", "easy", "easy", "easy", "easy", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult", "difficult")),
class = "data.frame", row.names = c(NA, -252L))
ts14 <- c("A1", "A11", "A12", "A13", "A3", "A4", "A5", "A6", "A7", "A9",
"B2", "B3", "C2", "E5", "E6", "E7", "E8", "E9", "F1", "F3", "G04",
"G06", "G07", "G08 ", "G09", "G10", "H01", "H02", "H03", "H04",
"H06 ", "H09", "H10", "H11", "H13", "H14")
# Order of groups should not affect errors
expect_error(DurgaDiff(data[data$Spider %in% ts14, ], "Wrap", "Prey_difficulty", id = "Spider"), "5 Spiders")
expect_error(DurgaDiff(data[data$Spider %in% ts14, ], "Wrap", "Prey_difficulty", id = "Spider", groups = c("difficult", "easy")), "5 Spiders")
expect_error(DurgaDiff(data[data$Spider %in% ts14, ], "Wrap", "Prey_difficulty", id = "Spider", groups = c("easy", "difficult")), "5 Spiders")
})
# TODO
# test_that("No CI", {
# df <- data.frame(val = rnorm(10000), grp = rep(c("G1", "G2"), exch = 5000))
# d <- DurgaDiff(df, 1, 2, R = 5000)
# })
test_that("transparency", {
expect_equal(DurgaTransparent("red", 0.8), "#FF000033")
expect_equal(DurgaTransparent("#ff0000", 0.8), "#FF000033")
expect_equal(DurgaTransparent("red", 0.8, TRUE), "#FF000033")
expect_equal(DurgaTransparent("red", 0.8, FALSE), "#FF000033")
expect_equal(DurgaTransparent("#ff0000cc", 0.8), "#FF000033")
expect_equal(DurgaTransparent("#ff0000cc", 0.8, TRUE), "#FF000029")
expect_equal(DurgaTransparent("#ff0000cc", 0.8, FALSE), "#FF000033")
})
test_that("expand contrasts", {
.makeX <- function(g) matrix(g, nrow = 2)
expect_equal(expandContrasts("g1 - g2, g3 - g4", c("g1", "g2", "g3", "g4")), .makeX(c("g1", "g2", "g3", "g4")), ignore_attr = TRUE)
expect_error(expandContrasts("g1 - g2, g3 - g5", c("g1", "g2", "g3", "g4")))
expect_error(expandContrasts("g1 - g1", c("g1", "g2", "g3", "g4")))
expect_equal(expandContrasts(" g1-g2 ", c("g1", "g2")), .makeX(c("g1", "g2")), ignore_attr = TRUE)
expect_equal(expandContrasts(" g1 -g2 ", c("g2", "g1")), .makeX(c("g1", "g2")), ignore_attr = TRUE)
expect_equal(expandContrasts(" g2 - g1 ", c("g2", "g1")), .makeX(c("g2", "g1")), ignore_attr = TRUE)
expect_equal(expandContrasts("g1 - g2", c("g4", "g1", "g2")), .makeX(c("g1", "g2")), ignore_attr = TRUE)
expect_equal(expandContrasts("g1 - g2", c("g4", "g2", "g1")), .makeX(c("g1", "g2")), ignore_attr = TRUE)
expect_equal(expandContrasts(". - g1", c("g1", "g2", "g3")), .makeX(c("g2", "g1", "g3", "g1")), ignore_attr = TRUE)
expect_equal(expandContrasts(". - g2", c("g1", "g2", "g3")), .makeX(c("g1", "g2", "g3", "g2")), ignore_attr = TRUE)
expect_equal(expandContrasts("g3-.", c("g1", "g2", "g3")), .makeX(c("g3", "g1", "g3", "g2")), ignore_attr = TRUE)
expect_equal(expandContrasts("*", c("g1", "g2")), .makeX(c("g2", "g1")), ignore_attr = TRUE)
expect_equal(expandContrasts("*", c("g2", "g1")), .makeX(c("g1", "g2")), ignore_attr = TRUE)
expect_equal(expandContrasts("*", c("g1")), NULL, ignore_attr = TRUE)
expect_equal(expandContrasts(" g1 - g11 ", c("g1", "g11")), .makeX(c("g1", "g11")), ignore_attr = TRUE)
expect_equal(expandContrasts(" g1 - g11 ", c("g11", "g1")), .makeX(c("g1", "g11")), ignore_attr = TRUE)
expect_equal(expandContrasts(" g11 - g1 ", c("g1", "g11")), .makeX(c("g11", "g1")), ignore_attr = TRUE)
expect_equal(expandContrasts(" . - g1", c("g1", "g11")), .makeX(c("g11", "g1")), ignore_attr = TRUE)
expect_equal(expandContrasts(" . - g1", c("g1", "g11", "g111")), .makeX(c("g11", "g1", "g111", "g1")), ignore_attr = TRUE)
expect_equal(expandContrasts(" g1 - .", c("g1", "g11")), .makeX(c("g1", "g11")), ignore_attr = TRUE)
expect_equal(expandContrasts(" g1 - . ", c("g1", "g11", "g111")), .makeX(c("g1", "g11", "g1", "g111")), ignore_attr = TRUE)
expect_error(expandContrasts(" . - . ", c("g1", "g11")))
expect_equal(expandContrasts("g1 - g2", c("g1", "g2", "g3", "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g1", "g2")))
expect_equal(expandContrasts("G1 - G2", c("g1", "g2", "g3", "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g1", "g2")))
expect_equal(expandContrasts("g2 - g1", c("g1", "g2", "g3", "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g2", "g1")))
expect_equal(expandContrasts("G2 - G1", c("g1", "g2", "g3", "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g2", "g1")))
expect_equal(expandContrasts("G2 - g1", c("g1", "g2", "g3", "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g2", "g1")))
expect_equal(expandContrasts("g3 - g2", c("g1", "g2", "g3", "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g3", "g2")))
expect_equal(expandContrasts("G3 - G2", c("g1", "g2", "g3", "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g3", "g2")))
expect_equal(expandContrasts("g4 - g1", c("g1", "g2", "g3", "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g4", "g1")))
expect_equal(expandContrasts("G4 - G1, g3-G2", c("g1", "g2", "g3", "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g4", "g1", "g3", "g2")))
expect_equal(expandContrasts(c("G4 - G1", "g3-G2"), c("g1", "g2", "g3", "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g4", "g1", "g3", "g2")))
expect_equal(expandContrasts("g2 - g1", c("g1", "g2", "g3", "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g2", "g1")))
expect_equal(expandContrasts("g2 - g1", c(G1 = "g1", G2 = "g2", G3 = "g3", G4 = "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g2", "g1")))
expect_equal(expandContrasts("G2 - G1", c(G1 = "g1", G2 = "g2", G3 = "g3", G4 = "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g2", "g1")))
expect_equal(expandContrasts(c("G2 - G1", "G3 - G1"), c(G1 = "g1", G2 = "g2", G3 = "g3", G4 = "g4"), c("G1", "G2", "G3", "G4")), .makeX(c("g2", "g1", "g3", "g1")))
})
test_that("group names and contrasts", {
data <- makeData()
groups <- c(Ctrl = "ZControl1", `G 1` = "Group1", `G 2` = "Group2")
d <- DurgaDiff(data, "Measurement", "Group", groups = groups)
DurgaDiff(data, "Measurement", "Group", groups = groups, contrasts = "*")
# Contrasts with data values
DurgaDiff(data, "Measurement", "Group", groups = groups, contrasts = c("Group2 - Group1"))
# Contrasts with group labels
DurgaDiff(data, "Measurement", "Group", groups = groups, contrasts = c("G 2 - G 1"))
# Contrasts with mixture of labels and data values
DurgaDiff(data, "Measurement", "Group", groups = groups, contrasts = c("G 2 - Group1"))
# Each pair of plots in a row should be identical. One uses group data value, the other uses group label
# Seems to be a bug? in R, restoring mfrow after DurgaPlot changes the margins!
mar <- par("mar")
op <- par(mfrow = c(2, 2))
on.exit(par(op))
expect_error(DurgaPlot(d, contrasts = "Group1 - ZControl1", main = "1 contrast"), NA)
expect_error(DurgaPlot(d, contrasts = "G 1 - Ctrl", main = "1 contrast"), NA)
expect_error(DurgaPlot(d, contrasts = "Group1 - ZControl1, Group2 - ZControl1", main = "2 contrasts"), NA)
expect_error(DurgaPlot(d, contrasts = "G 1 - Ctrl, G 2 - Ctrl", main = "2 contrasts"), NA)
par(mar = mar)
})
test_that("matrix data", {
n <- 20
m <- matrix(c(val = rnorm(n), sample(1:3, n, replace = TRUE)), nrow = n)
d <- DurgaDiff(m, 1, 2)
expect_error(DurgaPlot(d), NA)
})
test_that("violin symbology", {
op <- par(mfrow = c(1, 2))
data <- makeData()
d <- DurgaDiff(data, 1, 2, groups = c("ZControl1", "Group1", "Group2"))
expect_error(DurgaPlot(d, main = "Default symbology"), NA)
expect_error(DurgaPlot(d, main = "Custom violins", violin.params = list(lwd = 2, ljoin = 2, density = 10)), NA)
par(op)
})
test_that("violin no fill", {
data <- makeData()
d <- DurgaDiff(data, 1, 2, groups = c("ZControl1", "Group3", "Group4"))
expect_error(DurgaPlot(d, main = "No violin fill", violin.width = 2, violin.fill = F, violin.params = list(lwd = 2),
ef.size.violin.fill = F, ef.size.violin.shape = "full"), NA)
})
test_that("contrast plots", {
data <- makeData()
groups <- c("ZControl1", "Group1", "Group2", "Group3")
# Default contrasts
d <- DurgaDiff(data, "Measurement", "Group", groups = groups)
ng <- length(d$groups)
expect_equal(length(d$group.differences), ng * (ng - 1) / 2)
DurgaPlot(d, main = "Default contrasts")
# 2 contrasts
contrasts <- "Group1 - ZControl1, Group2 - ZControl1, Group3 - ZControl1"
d <- DurgaDiff(data, "Measurement", "Group", groups = groups, contrasts = contrasts)
expect_equal(length(d$group.differences), 3)
expect_equal(d$group.differences[[1]]$groups[1], "Group1")
expect_equal(d$group.differences[[1]]$groups[2], "ZControl1")
expect_equal(d$group.differences[[2]]$groups[1], "Group2")
expect_equal(d$group.differences[[2]]$groups[2], "ZControl1")
expect_equal(d$group.differences[[3]]$groups[1], "Group3")
expect_equal(d$group.differences[[3]]$groups[2], "ZControl1")
DurgaPlot(d, violin = F, central.tendency.width = 0.1, central.tendency.symbol = "segment", central.tendency.params = , main = "Explicit contrasts")
# Shorthand for same as above
d <- DurgaDiff(data, "Measurement", "Group", groups = groups, contrasts = ". - ZControl1")
expect_equal(length(d$group.differences), 3)
expect_equal(d$group.differences[[1]]$groups[1], "Group1")
expect_equal(d$group.differences[[1]]$groups[2], "ZControl1")
expect_equal(d$group.differences[[2]]$groups[1], "Group2")
expect_equal(d$group.differences[[2]]$groups[2], "ZControl1")
expect_equal(d$group.differences[[3]]$groups[1], "Group3")
expect_equal(d$group.differences[[3]]$groups[2], "ZControl1")
DurgaPlot(d, points.method = "jitter", main = "Explicit contrast shorthand")
# Invalid contrasts
expect_error(DurgaDiff(data, "Measurement", "Group", groups = groups, contrasts = 1))
expect_error(DurgaPlot(d, contrasts = 1))
# Just 1 contrast
data <- makeData()
d <- DurgaDiff(data, "Measurement", "Group", groups = groups)
DurgaPlot(d, contrasts = c(`Diff` = "Group3 - Group2"), main = "Plot 1 labelled diff")
DurgaPlot(d, contrasts = c(`Diff` = "Group2 - Group3"), mai = "Plot negative diff")
d <- DurgaDiff(data, "Measurement", "Group", groups = groups, effect.type = "cohens d")
DurgaPlot(d, contrasts = c(`Diff` = "Group3 - Group2"), main = "Plot 1 Cohen's")
DurgaPlot(d, contrasts = c(`Diff` = "Group2 - Group3"), mai = "Plot negative Cohen's")
# Single contrast in diff
d <- DurgaDiff(data, "Measurement", "Group", groups = c("Group3", "Group2"))
DurgaPlot(d, main = "Restricted groups in diff")
d <- DurgaDiff(data, "Measurement", "Group", groups = c("Group3", "Group2"), effect.type = "cohens d")
DurgaPlot(d, main = "Restricted groups in diff Cohen's")
})
test_that("group stats", {
checkGroup <- function(gs, vals, popMean) {
gs <- unname(gs)
expect_equal(gs[1], mean(vals))
expect_equal(gs[2], median(vals))
expect_equal(gs[3], sd(vals))
expect_equal(gs[4], sd(vals) / sqrt(length(vals)))
expect_lt(gs[5], popMean)
expect_gt(gs[6], popMean)
}
# Test single group at a time
set.seed(3)
mean <- 50
sd <- 17
ns <- c(10, 20, 80, 200)
for (n in ns) {
v <- rnorm(n, mean, sd)
df <- data.frame(v, rep("g", length(v)))
d <- DurgaDiff(df, 1, 2)
checkGroup(d$group.statistics, v, mean)
}
# Now combine all groups into one data set
set.seed(1)
df <- do.call(rbind, lapply(ns, function(n) data.frame(val = rnorm(n, mean, sd), group = rep(sprintf("g%03d", n), n))))
d <- DurgaDiff(df, 1, 2)
for (i in seq_along(ns)) {
gn <- sprintf(sprintf("g%03d", ns[i]))
checkGroup(d$group.statistics[i, ], df$val[df$group == gn], mean)
}
# For debugging
if (FALSE) {
DurgaPlot(d, violin = F, points.method = "jitter", ef.size = F, central.tendency.dx = 0.15, error.bars.type = "CI")
abline(h = mean, col = "lightgrey")
DurgaPlot(d, add = T, violin = F, points = F, ef.size = F, central.tendency.dx = 0.25, error.bars.type = "SD")
DurgaPlot(d, add = T, violin = F, points = F, ef.size = F, central.tendency.dx = 0.35, error.bars.type = "SE")
}
})
test_that("print", {
d <- makeES1()
# This is a regex
expected <- paste0("Bootstrapped effect size\\n",
" Measurement ~ Group\\n",
"Groups:\\n",
" mean median sd se CI\\.lower CI\\.upper n\\n",
"Group1 122\\.9210 118\\.8367 21\\.31850 3\\.370750 116\\.84544 130\\.4658 40\\n",
"ZControl1 102\\.3007 103\\.2276 22\\.16668 3\\.504859 95\\.36523 108\\.6278 40\\n",
"Unpaired Difference of means \\(R = 1000, bootstrap CI method = bca\\):\\n",
" ZControl1 - Group1: -20\\.6203, 95% CI \\[-29\\.[0-9]+, -11\\.[0-9]+\\]")
expect_output(print(d), expected)
# Print mismatched lines
if (FALSE) {
got <- capture.output(print(d))
expLines <- gsub("\\\\", "", strsplit(expected, "\\\\n")[[1]])
matched <- got == expLines
print(got[!matched])
print(expLines[!matched])
}
checkSummaryMatches <- function(d1, d2) {
d1s <- capture.output(print(d1))
d2s <- capture.output(print(d2))
# Crude check - just remove all numbers
d1s <- sub("[0-9].*", "", d1s)
d2s <- sub("[0-9].*", "", d2s)
expect_equal(d1s, d2s)
}
# Check that formula output matches non-formula
set.seed(1) # Avoid white-space differences caused by different printed precisions
d1 <- DurgaDiff(petunia, 1, 2)
d2 <- DurgaDiff(height ~ group, petunia)
checkSummaryMatches(d1, d2)
# Paired
set.seed(1) # Avoid white-space differences caused by different printed precisions
d1 <- DurgaDiff(insulin, 1, 2, 3)
d2 <- DurgaDiff(sugar ~ treatment, insulin, id.col = "id")
checkSummaryMatches(d1, d2)
d <- DurgaDiff(log(sugar) ~ treatment, insulin, id.col = "id")
s <- capture.output(print(d))
expect_equal(s[2], " log(sugar) ~ treatment")
# Spaces in names
`Scapus length` <- rnorm(40, 10)
`Group name` <- sample(c("Group one", "Group two", "Group three"), 40, replace = TRUE)
# Just check it doesn't crash
expect_error(capture.output(print(DurgaDiff(`Scapus length` ~ `Group name`))), NA)
expect_error(capture.output(print(DurgaDiff(log(`Scapus length`) ~ `Group name`))), NA)
})
test_that("contrasts", {
data <- makeData()
# Default contrasts
d <- DurgaDiff(data, "Measurement", "Group")
ng <- length(d$groups)
expect_equal(length(d$group.differences), ng * (ng - 1) / 2)
# All in 1 string
contrasts = "Group1 - ZControl1, Group2 - ZControl1, Group3 - ZControl1, Group4 - ZControl1"
d <- DurgaDiff(data, "Measurement", "Group", contrasts = contrasts)
expect_equal(length(d$group.differences), 4)
expect_equal(d$group.differences[[1]]$groups[1], "Group1")
expect_equal(d$group.differences[[1]]$groups[2], "ZControl1")
expect_equal(d$group.differences[[2]]$groups[1], "Group2")
expect_equal(d$group.differences[[2]]$groups[2], "ZControl1")
expect_equal(d$group.differences[[3]]$groups[1], "Group3")
expect_equal(d$group.differences[[3]]$groups[2], "ZControl1")
expect_equal(d$group.differences[[4]]$groups[1], "Group4")
expect_equal(d$group.differences[[4]]$groups[2], "ZControl1")
contrasts = c("Group1 - ZControl1", "Group2 - ZControl1", "Group3 - ZControl1", "Group4 - ZControl1")
d2 <- DurgaDiff(data, "Measurement", "Group", contrasts = contrasts)
expect_equal(length(d2$group.differences), 4)
expect_equal(d2$group.differences[[1]]$groups[1], "Group1")
expect_equal(d2$group.differences[[1]]$groups[2], "ZControl1")
compareDiffs(d2, d)
contrasts <- matrix(c("Group1", "ZControl1", "Group2", "ZControl1", "Group3", "ZControl1", "Group4", "ZControl1"), nrow = 2)
d2 <- DurgaDiff(data, "Measurement", "Group", contrasts = contrasts)
expect_equal(length(d2$group.differences), 4)
expect_equal(d2$group.differences[[1]]$groups[1], "Group1")
expect_equal(d2$group.differences[[1]]$groups[2], "ZControl1")
compareDiffs(d2, d, tolerance = 1)
expect_error(DurgaDiff(data, "Measurement", "Group", contrasts = "Group2:ZControl"))
expect_error(DurgaDiff(data, "Measurement", "Group", contrasts = "ZControl"))
expect_error(DurgaDiff(data, "Measurement", "Group", contrasts = "Group 2 - Group 1"))
# Allow "" as meaning no contrasts
d <- DurgaDiff(data, "Measurement", "Group", contrasts = "")
# Wildcard contrasts
d <- DurgaDiff(data, "Measurement", "Group", effect.type = "cohens d", contrasts = "*")
ng <- length(unique(data$Group))
expect_equal(length(d$group.differences), ng * (ng - 1) / 2)
})
test_that("difference effect types", {
n <- 100
set.seed(1)
realDiff <- 1
df <- data.frame(val = c(rnorm(n, mean = 10), rnorm(n, mean = 10 + realDiff)),
group = c(rep("Control", n), rep("Group", n)),
id = c(1:n, 1:n))
# Check all effect types
expect_error(DurgaDiff(df, effect.type = "wrong", data.col = 1, group.col = 2)) # Should throw an error
expect_error(DurgaDiff(df, effect.type = "mean", data.col = 1, group.col = 2), NA)
expect_error(DurgaDiff(df, effect.type = "cohens d", data.col = 1, group.col = 2), NA)
expect_error(DurgaDiff(df, effect.type = "hedges g", data.col = 1, group.col = 2), NA)
expect_error(DurgaDiff(df, effect.type = "mean", id.col = "id", data.col = 1, group.col = 2), NA)
expect_error(DurgaDiff(df, effect.type = "cohens d", id.col = "id", data.col = 1, group.col = 2), NA)
expect_error(DurgaDiff(df, effect.type = "hedges g", id.col = "id", data.col = 1, group.col = 2), NA)
# Check unstandardised diff (diff of means)
d <- DurgaDiff(df, data.col = 1, group.col = 2, effect.type = "mean")
pwd <- d$group.difference[[1]]
expect_equal(pwd$groups[1], "Group")
expect_equal(pwd$groups[2], "Control")
expect_lt(pwd$t0, realDiff)
expect_lt(pwd$bca[4], realDiff)
expect_gt(pwd$bca[5], realDiff)
# Check Cohen's D
d <- DurgaDiff(df, data.col = 1, group.col = 2, effect.type = "cohens d")
pwd <- d$group.difference[[1]]
expect_equal(pwd$groups[1], "Group")
expect_equal(pwd$groups[2], "Control")
expect_equal(pwd$t0, 0.918991, tolerance = 0.0001) # Cohen's d
expect_lt(pwd$bca[4], 0.918991) # Should be positive but small
expect_gt(pwd$bca[5], 0.918991)
# Save Cohen's d for later
cohensD <- pwd$t0
# Swap groups
d <- DurgaDiff(df, groups = c("Group", "Control"), data.col = 1, group.col = 2, effect.type = "cohens d")
pwd <- d$group.difference[[1]]
expect_equal(pwd$groups[1], "Control")
expect_equal(pwd$groups[2], "Group")
expect_equal(pwd$t0, -0.918991, tolerance = 0.0001) # Cohen's d
expect_lt(pwd$bca[4], -0.918991) # Should be negative but small
expect_gt(pwd$bca[5], -0.918991)
# Check Hedges' g
d <- DurgaDiff(df, data.col = 1, group.col = 2, effect.type = "hedges g")
pwd <- d$group.difference[[1]]
expect_equal(pwd$groups[1], "Group")
expect_equal(pwd$groups[2], "Control")
# Estimate Hedges' g by correcting Cohen's d (Lakens 2013, p. 3 eqn 4)
n1 <- d$group.statistics[2,"n"]
n2 <- d$group.statistics[1,"n"]
hedgesG <- cohensD * (1 - 3 / (4 * (n1 + n2) - 9)) # Approximate method
expect_equal(pwd$t0, hedgesG, tolerance = 0.0001)
expect_lt(pwd$bca[4], 0.918991) # Should be positive but small
expect_gt(pwd$bca[5], 0.918991)
# Swap groups
d <- DurgaDiff(df, groups = c("Group", "Control"), data.col = 1, group.col = 2, effect.type = "hedges g")
pwd <- d$group.difference[[1]]
expect_equal(pwd$groups[1], "Control")
expect_equal(pwd$groups[2], "Group")
expect_equal(pwd$t0, -hedgesG, tolerance = 0.0001)
expect_lt(pwd$bca[4], -hedgesG) # Should be negative but small
expect_gt(pwd$bca[5], -hedgesG)
### Paired effect sizes ###
# Check unstandardised diff
d <- DurgaDiff(df, data.col = 1, group.col = 2, id.col = 3, effect.type = "mean")
pwd <- d$group.difference[[1]]
expect_equal(pwd$groups[1], "Group")
expect_equal(pwd$groups[2], "Control")
expect_lt(pwd$t0, realDiff)
expect_lt(pwd$bca[4], realDiff)
expect_gt(pwd$bca[5], realDiff)
# Check Cohen's D
d <- DurgaDiff(df, data.col = 1, group.col = 2, id.col = 3, effect.type = "cohens d_z")
pwd <- d$group.difference[[1]]
expect_equal(pwd$groups[1], "Group")
expect_equal(pwd$groups[2], "Control")
diffs <- df$val[df$group == "Group"] - df$val[df$group == "Control"]
cohensD <- mean(diffs) / sd(diffs)
expect_equal(pwd$t0, cohensD)
expect_lt(pwd$bca[4], cohensD) # Should be positive but small
expect_gt(pwd$bca[5], cohensD)
d <- DurgaDiff(df, data.col = 1, group.col = 2, id.col = 3, effect.type = "hedges g_z")
pwd <- d$group.difference[[1]]
expect_equal(pwd$groups[1], "Group")
expect_equal(pwd$groups[2], "Control")
# Estimate Hedges' g by using Hedges' approximate method to correct Cohen's d (Cummings 2012, eqn 11.13)
hedgesG <- cohensD * (1 - (3 / (4 * (n - 1) - 1)))
expect_equal(pwd$t0, hedgesG, tolerance = 1.5 * 10e-6)
expect_lt(pwd$bca[4], hedgesG) # Should be positive but small
expect_gt(pwd$bca[5], hedgesG)
})
test_that("group factors", {
n <- 100
df <- data.frame(val = c(rnorm(n), rnorm(n, mean = 1)),
group = factor(c(rep("Control", n), rep("Treatment", n))),
id = c(1:n, 1:n))
d <- DurgaDiff(df, effect.type = "mean", data.col = 1, group.col = 2)
pwd <- d$group.difference[[1]]
expect_equal(d$group.names, c("Control", "Treatment"))
expect_equal(pwd$groups[1], "Treatment")
expect_equal(pwd$groups[2], "Control")
# Check all effect types
expect_error(DurgaDiff(df, effect.type = "mean", data.col = 1, group.col = 2), NA)
expect_error(DurgaDiff(df, effect.type = "cohens d", data.col = 1, group.col = 2), NA)
expect_error(DurgaDiff(df, effect.type = "hedges g", data.col = 1, group.col = 2), NA)
expect_error(DurgaDiff(df, id.col = "id", data.col = 1, group.col = 2), NA)
})
test_that("difference handles NA", {
n <- 100
df <- data.frame(val = c(rnorm(n), rnorm(n, mean = 1)),
group = c(rep("Control", n), rep("Group", n)))
df[c(1, 4, 10, 65), 1] <- NA
# This should throw an error (something about na.rm)
expect_error(DurgaDiff(df, na.rm = FALSE, data.col = 1, group.col = 2), "na.rm")
# This should NOT throw an error
expect_error(DurgaDiff(df, na.rm = TRUE, data.col = 1, group.col = 2), NA)
# Check column name checks
expect_error(DurgaDiff(df, id.col = "id", na.rm = TRUE, data.col = 1, group.col = 2), "column name")
expect_error(DurgaDiff(df, data.col = "XXX", group.col = 2), "column name")
expect_error(DurgaDiff(df, data.col = 1, group.col = "XXX"), "column name")
})
test_that("two groups", {
N <- 40
df <- data.frame(Measurement = c(rnorm(N, mean = 100, sd = 25),
rnorm(N, mean = 120, sd = 25)),
Group = c(rep("Control", N),
rep("Treatment", N)),
Gender = rep(c(rep('Male', N/2), rep('Female', N/2)), 2),
ID = rep(1:N, 2)
)
d2 <- DurgaDiff(df, data.col = 1, group.col = 2)
# This should NOT throw an error
op <- par(mar = c(5, 4, 4, 4) + 0.1)
expect_error(DurgaPlot(d2, ef.size = TRUE, main = "Two groups, effect size default"), NA)
expect_error(DurgaPlot(d2, ef.size.pos = "right", main = "Two groups, effect size right"), NA)
par(op)
expect_error(DurgaPlot(d2, ef.size = FALSE, main = "Two groups, no effect size"), NA)
expect_error(DurgaPlot(d2, ef.size.position = "below", main = "Two groups, effect size below"), NA)
})
test_that("three groups", {
N <- 40
df <- data.frame(Measurement = c(rnorm(N, mean = 100, sd = 25),
rnorm(N, mean = 120, sd = 25),
rnorm(N, mean = 80, sd = 50)),
Group = c(rep("ZControl1", N),
rep("Group1", N),
rep("Group2", N)),
Gender = rep(c(rep('Male', N/2), rep('Female', N/2)), 3),
ID = rep(1:N, 3)
)
d3 <- DurgaDiff(df, data.col = 1, group.col = 2)
# This should NOT throw an error
expect_error(DurgaPlot(d3, bar = FALSE, box = FALSE, main = "Three groups"), NA)
expect_error(DurgaPlot(d3, violin.trunc = FALSE, main = "No violin truncation"), NA)
expect_error(DurgaPlot(d3, violin.trunc = 0.05, main = "0.05 violin truncation"), NA)
expect_error(DurgaPlot(d3, ef.size.violin = FALSE, main = "No effect size violin"), NA)
})
test_that("three groups with factor", {
N <- 40
# Use factor to control group order
df <- data.frame(Measurement = c(rnorm(N, mean = 100, sd = 25),
rnorm(N, mean = 120, sd = 25),
rnorm(N, mean = 80, sd = 50)),
Group = factor(c(rep("ZControl1", N),
rep("Group1", N),
rep("Group2", N)),
levels = c("ZControl1", "Group1", "Group2")),
Gender = rep(c(rep('Male', N/2), rep('Female', N/2)), 3),
ID = rep(1:N, 3)
)
d3 <- DurgaDiff(df, data.col = 1, group.col = 2)
# This should NOT throw an error
expect_error(DurgaPlot(d3, bar = FALSE, box = FALSE, main = "Group factor"), NA)
})
test_that("many groups", {
n <- 12
groupMean <- round(rnorm(n, mean = 20, sd = 8))
val <- c(sapply(groupMean, function(m) rnorm(n, m, 4)))
groups <- sapply(seq_len(n), function(i) paste0("G", i, "-", groupMean[i]))
trt <- c(sapply(seq_along(groupMean), function(i) rep(groups[i], n)))
df <- data.frame(Height = val, Treatment = trt)
d <- DurgaDiff(df, "Height", "Treatment", groups = groups)
op <- par(cex = 0.8)
expect_error(DurgaPlot(d, main = "1/3) Many groups"), NA)
expect_error(DurgaPlot(d, main = "2/3) Many groups, control-.", contrasts = paste(df$Treatment[1], "-.")), NA)
expect_error(DurgaPlot(d, main = "3/3) Many groups, .-control", contrasts = paste(" . - ", df$Treatment[1])), NA)
par(op)
})
test_that("plots work", {
#### This fails with "figure margins too large"
if (FALSE) {
N <- 40
set.seed(1)
data <- data.frame(Measurement = c(rnorm(N, mean = 100, sd = 25),
rnorm(N, mean = 100, sd = 50),
rnorm(N, mean = 120, sd = 25),
rnorm(N, mean = 80, sd = 50),
rnorm(N, mean = 100, sd = 12),
rnorm(N, mean = 100, sd = 50)),
Group = c(rep("ZControl1", N),
rep("Control2", N),
rep("Group1", N),
rep("Group2", N),
rep("Group3", N),
rep("Group4", N)),
Gender = rep(c(rep('Male', N/2), rep('Female', N/2)), 6),
ID = rep(1:N, 6)
)
# Shuffle
data <- data[sample(nrow(data)), ]
es <- DurgaDiff(data[data$Group %in% c("ZControl1", "Group1"),], data.col = "Measurement", group.col = "Group", R = 1000)
es2 <- DurgaDiff(data[data$Group %in% c("ZControl1", "Group1"),],
data.col = "Measurement", group.col = "Group", R = 1000,
id.col = "ID")
# Generate some plots
l <- layout(matrix(c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20), nrow = 4, ncol = 5, byrow = TRUE))
#layout.show(l)
#par(mfrow = c(2, 4))
#a)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = FALSE, box.fill = FALSE,
central.tendency = "median", error.bars.type = "CI", ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5))
#b)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = "white", box.fill = "white",
central.tendency = "median", error.bars = "SD", ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5),)
#c)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = "white", box.fill = "white",
central.tendency = "median", error.bars = "SE", ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5),)
#d)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = "white", box.fill = "white",
central.tendency.type = "mean", error.bars.type = "CI", ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5),)
#e)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = "white", box.fill = "white",
central.tendency.type = "mean", error.bars = "SD", ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5),)
#f)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = "white", box.fill = "white",
central.tendency.type = "mean", error.bars = "SE", ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5),)
#g)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = DurgaTransparent(c("red", "blue"), .5),
box.fill = "white", error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = FALSE)
#h)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = DurgaTransparent(c("red", "blue"), .5),
box.fill = "white", error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5))
#i)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = DurgaTransparent(c("red", "blue"), .5),
box.fill = DurgaTransparent(c("red", "blue"), .7), error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = FALSE)
#j)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = DurgaTransparent(c("red", "blue"), .5),
box.fill = DurgaTransparent(c("red", "blue"), .7), error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5))
#k)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin.shape = "left-half",
violin = DurgaTransparent(c("red", "blue"), .6),
violin.fill = DurgaTransparent(c("red", "blue"), .6),
box = "white",
box.fill = "white",
error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5))
#l)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin.shape = "left-half",
violin = DurgaTransparent(c("red", "blue"), .6),
violin.fill = DurgaTransparent(c("red", "blue"), .6),
box = DurgaTransparent(c("red", "blue"), .5),
box.fill = DurgaTransparent(c("red", "blue"), .7), error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = FALSE)
##m)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin.shape = "left-half",
violin = DurgaTransparent(c("red", "blue"), .6),
violin.fill = DurgaTransparent(c("red", "blue"), .6),
box = DurgaTransparent(c("red", "blue"), .5),
box.fill = DurgaTransparent(c("red", "blue"), .7), error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5))
#n)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin.shape = "right-half",
violin = DurgaTransparent(c("red", "blue"), .6),
violin.fill = DurgaTransparent(c("red", "blue"), .6),
box = "white",
box.fill = "white",
error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5))
#o)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin.shape = "right-half",
violin = DurgaTransparent(c("red", "blue"), .6),
violin.fill = DurgaTransparent(c("red", "blue"), .6),
box = DurgaTransparent(c("red", "blue"), .5),
box.fill = DurgaTransparent(c("red", "blue"), .7), error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = FALSE)
#p)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin.shape = "right-half",
violin = DurgaTransparent(c("red", "blue"), .6),
violin.fill = DurgaTransparent(c("red", "blue"), .6),
box = DurgaTransparent(c("red", "blue"), .5),
box.fill = DurgaTransparent(c("red", "blue"), .7), error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5))
#q)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin.shape = "full",
violin = DurgaTransparent(c("red", "blue"), .6),
violin.fill = DurgaTransparent(c("red", "blue"), .6),
box = DurgaTransparent(c("red", "blue"), .5),
box.fill = DurgaTransparent(c("red", "blue"), .7), error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = FALSE)
#r)
DurgaPlot(es2, bar = FALSE, bar.fill = FALSE, violin.shape = "full",
violin = DurgaTransparent(c("red", "blue"), .4),
violin.fill = DurgaTransparent(c("red", "blue"), .8),
box = DurgaTransparent(c("grey10"), .1),
box.fill = DurgaTransparent(c("red", "blue"), .7), error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = TRUE,
points = DurgaTransparent(c("red", "blue"), .5), paired = TRUE)
#s)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin.shape = "full",
violin = DurgaTransparent(c("red", "blue"), .6),
violin.fill = DurgaTransparent(c("red", "blue"), .6),
box = "white",
box.fill = "white",
error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5))
#t)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin.shape = "full",
violin = DurgaTransparent(c("red", "blue"), .6),
violin.fill = DurgaTransparent(c("red", "blue"), .6),
box = "white",
box.fill = "white",
error.bars.type = "CI",
central.tendency.type = "mean", central.tendency = FALSE, ef.size = FALSE,
points = FALSE)
}
expect_equal(1, 1)
})
test_that("box FALSE works", {
es <- makeES1()
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = FALSE, box.fill = FALSE,
central.tendency.type = "median", error.bars.type = "CI", error.bars.cross.width = 0.05,
ef.size = FALSE, points = DurgaTransparent(c("red", "blue"), .5),
main = "Violin FALSE, median, no effect size")
DurgaPlot(es, violin = FALSE, central.tendency = FALSE, error.bars = FALSE, ef.size = FALSE,
main = "No central tendency, error bar, effect size")
expect_equal(1, 1)
})
test_that("central tendency FALSE works", {
es <- makeES1()
expect_false(es$paired.data)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = "red", box.fill = "blue",
central.tendency = FALSE, error.bars.type = "CI", ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5), main = "Central tendency FALSE")
expect_equal(1, 1)
})
test_that("paired works", {
es <- makePairedData()
expect_true(es$paired.data)
DurgaPlot(es,
paired = DurgaTransparent("green", 0.5), paired.lty = 2,
bar = FALSE, bar.fill = FALSE, violin = FALSE, box = "red", box.fill = "blue",
central.tendency = FALSE, error.bars.type = "CI", ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5), main = "Paired")
DurgaPlot(es, violin = FALSE, ef.size = FALSE, paired.lwd = 3, main = "Paired, no violin, no effect size")
op <- par(mar = c(5, 4, 4, 4) + 0.1)
on.exit(par(op))
DurgaPlot(es, violin = FALSE, ef.size = TRUE, points = FALSE, main = "Paired, no violin, effect size, no points")
DurgaPlot(es, violin.shape = c("left", "right"), violin.width = 0.2, main = "Custom")
# Craft simple paired data to ensure that pair lines are correct
n <- 10
control <- sort(rnorm(n, 0))
before <- sort(rnorm(n, 3))
after <- sort(rnorm(n, 2.5))
treatments <- c("Control", "Before", "After")
df <- data.frame(Id = rep(seq_len(n), 3),
Treatment = rep(treatments, each = n),
Value = c(control, before, after))
# Shuffle
set.seed(1)
sortedD <- DurgaDiff(df, "Value", "Treatment", "Id", groups = treatments)
df <- df[sample(nrow(df)), ]
set.seed(1)
d <- DurgaDiff(df, "Value", "Treatment", "Id", groups = treatments)
# Shuffling the rows should not affect the results
compareDiffs(sortedD, d, tolerance = 0.1)
DurgaPlot(d, contrasts = "Before-Control, After - Before", ef.size = FALSE, violin = FALSE, points.dx = c(0.2, 0, -0.2), main = "No intersecting lines?")
expect_equal(1, 1)
})
test_that("paired (reversed groups) works", {
es <- makePairedData(reverseGroups = TRUE)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = "red", box.fill = "blue",
central.tendency = FALSE, error.bars.type = "CI", ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5), main = "Paired with reversed groups")
expect_equal(1, 1)
})
test_that("paired with NAs works", {
es <- makePairedData(addSomeNAs = TRUE)
DurgaPlot(es, bar = FALSE, bar.fill = FALSE, violin = FALSE, box = "red", box.fill = "blue",
central.tendency = FALSE, error.bars.type = "CI", ef.size = FALSE,
points = DurgaTransparent(c("red", "blue"), .5), main = "Paired with some NAs")
expect_equal(1, 1)
})
test_that("bar charts work", {
es <- makeES1()
DurgaPlot(es, bar = TRUE, violin = FALSE, box = FALSE, box.fill = "blue",
error.bars = FALSE, error.bars.type = "CI", ef.size = FALSE,
points = FALSE, main = "Bar chart, no error bars")
DurgaPlot(es, bar = TRUE, violin = FALSE, box = FALSE, box.fill = "blue",
error.bars = TRUE, error.bars.type = "CI", ef.size = FALSE,
points = FALSE, main = "Bar chart, error bars")
expect_equal(1, 1)
})
test_that("custom effect axis", {
n <- 100
df <- data.frame(val = c(rnorm(n, mean = 10), rnorm(n, mean = 10 + 1)),
group = rep(c("Control", "Group"), each = 2),
id = rep(1:n, each = 2))
ef.size.ticks = c("Large negative effect" = -0.8,
"Medium negative effect" = -0.5, "Small negative effect" = -0.2,
"No effect" = 0, "Small positive effect" = 0.2,
"Medium positive effect" = 0.5, "Large positive effect" = 0.8)
d <- DurgaDiff(df, effect.type = "cohens d", data.col = 1, group.col = 2)
op <- par(mar = c(5, 4, 4, 10) + 0.1)
on.exit(par(op))
expect_error(DurgaPlot(d, ef.size.ticks = ef.size.ticks, ef.size.params = list(las = 1), ef.size.label = "", main = "Cohen's with custom labels"), NA)
})
test_that("Axis las", {
n <- 100
df <- data.frame(val = c(rnorm(n, mean = 10), rnorm(n, mean = 10 + 1), rnorm(n, mean = 10 + 1.4)),
group = rep(c("Group1", "Group2", "Group3"), each = n))
d2 <- DurgaDiff(df, groups = c("Group1", "Group2"), data.col = 1, group.col = 2)
op <- par(mar = c(5, 4, 4, 4))
expect_error(DurgaPlot(d2, las = 1, ef.size.params = list(las = 1), main = "las horizontal"), NA)
par(op)
d3 <- DurgaDiff(df, data.col = 1, group.col = 2)
expect_error(DurgaPlot(d3, las = 1, ef.size.params = list(las = 1), main = "las horizontal"), NA)
})
test_that("Other data frame classes", {
n <- 40
df <- tibble::tibble(val = c(rnorm(n, mean = 10), rnorm(n, mean = 10 + 1), rnorm(n, mean = 10 + 1.4)),
group = rep(c("Group1", "Group2", "Group3"), each = n))
d <- DurgaDiff(df, data.col = 1, group.col = 2)
expect_error(DurgaPlot(d, main = "Tibble"), NA)
df <- data.table::data.table(val = c(rnorm(n, mean = 10), rnorm(n, mean = 10 + 1), rnorm(n, mean = 10 + 1.4)),
group = rep(c("Group1", "Group2", "Group3"), each = n))
d <- DurgaDiff(df, data.col = 1, group.col = 2)
expect_error(DurgaPlot(d, main = "Data.table"), NA)
})
test_that("point colours", {
n <- 40
df <- data.frame(val = c(rnorm(n, mean = 10), rnorm(n, mean = 10 + 1)),
group = rep(c("Group1", "Group2"), each = n),
sex = sample(factor(c("Male", "Female")), n, replace = TRUE))
d <- DurgaDiff(df, data.col = 1, group.col = 2)
expect_error(DurgaPlot(d, points = 1:2, main = "Group colours"), NA)
expect_error(DurgaPlot(d, points = 1:5, main = "Group colours (truncated palette)"), NA)
expect_error(DurgaPlot(d, points = as.numeric(df$sex) + 1, main = "Sex colours"), NA)
})
test_that("detect missing paired data", {
n <- 40
# Test whether missing paired data is detected correctly
set.seed(1)
df <- data.frame(val = c(rnorm(n, mean = 10), rnorm(n, mean = 10 + 1)),
group = rep(c("Group1", "Group2"), each = n),
id = rep(1:n, 2))
# If we take a random sample of rows, some will be missing their paired data
df <- df[sample(seq_len(nrow(df)), round(n / 2)), ]
expect_error(DurgaDiff(df, data.col = 1, group.col = 2, id.col = 3), "paired data")
})
test_that("plot contrasts", {
n <- 40
set.seed(1)
df <- data.frame(val = c(rnorm(n, mean = 10), rnorm(n, mean = 10 + 1)),
group = rep(c("Group1", "Group2"), each = n),
sex = sample(factor(c("Male", "Female")), n, replace = TRUE))
d <- DurgaDiff(df, data.col = 1, group.col = 2)
expect_error(DurgaPlot(d, points = 1:2, main = "1/3) Default contrast"), NA)
d <- DurgaDiff(df, data.col = 1, group.col = 2, contrasts = ". - Group1")
expect_error(DurgaPlot(d, points = 1:2, main = "2/3) DurgaDiff contrast"), NA)
d <- DurgaDiff(df, data.col = 1, group.col = 2)
expect_error(DurgaPlot(d, points = 1:2, main = "3/3) DurgaPlot contrast", contrasts = ". - Group1"), NA)
})
test_that("effect size position", {
n <- 20
set.seed(1)
df <- data.frame(val = c(rnorm(n, mean = 10), rnorm(n, mean = 10 + 0.8), rnorm(n, mean = 10 + 0.4)),
group = rep(c("Group1", "Group2", "Group3"), each = n),
sex = sample(factor(c("Male", "Female", "Juvenile")), n, replace = TRUE))
d <- DurgaDiff(df, data.col = 1, group.col = 2)
expect_error(DurgaPlot(d, contrasts = Filter(function(d) d$bca[4] > 0 || d$bca[5] < 0, d$group.differences),
main = "1/3) ef.size position default, filtered contrasts"), NA)
expect_error(DurgaPlot(d, ef.size.position = "below", contrasts = "Group3 - Group1", main = "2/3) ef.size below, 1 contrast"), NA)
expect_error(DurgaPlot(d, main = "3/3) ef.size default position, shorthand contrasts", contrasts = ". - Group1"), NA)
# Check missing contrast
d <- DurgaDiff(df, data.col = 1, group.col = 2, contrasts = "Group2 - Group1")
expect_error(DurgaPlot(d, contrasts = "Group3 - Group1"))
})
test_that("Grouped plot", {
# Attempt to reproduce Figure 1 in
# Ostap-Chec, M., Opalek, M., Stec, D., & Miler, K. (2021). Discontinued alcohol consumption elicits withdrawal symptoms in honeybees. Biology Letters, 17(6), 20210182. doi:10.1098/rsbl.2021.0182
op <- par(mar = c(4, 5, 1, 10.5) + 0.1, mfrow = c(2, 1))
on.exit(par(op))
cols <- RColorBrewer::brewer.pal(4, "Dark2")
set.seed(1)
for (i in 1:2) {
n <- 6
meansA <- c("water" = 5, "0.125%" = 5, "1.25%" = 5, "2%" = 12, "sugar" = 100)
groups <- c("no exposure", "short exposure", "exposure withheld", "constant exposure")
df <- data.frame(group = rep(groups, each = n),
prob = sapply(names(meansA), function(nm) pmin(100, rnorm(n * length(groups), meansA[nm], meansA[nm] / 2))),
check.names = FALSE)
# Convert wide to long format
rows <- lapply(names(meansA), function(nm) cbind.data.frame(group = df$group, treatment = rep(nm, nrow(df)), prob = df[[paste0("prob.", nm)]]))
long <- as.data.frame(do.call(rbind, rows))
long$combined <- paste(long$group, long$treatment)
cg <- sapply(names(meansA), function(t) paste(groups, t))
d <- DurgaDiff(long, "prob", "combined", groups = cg, contrasts = NULL)
ps <- expect_error(DurgaPlot(d, x.axis = FALSE, left.las = 1, left.ylab = "probability of\nresponding (%)",
frame.plot = FALSE, ef.size = FALSE, violin = FALSE, points = FALSE,
group.dx = c(0.6, 0.2, -0.2, -0.6),
central.tendency = cols, error.bars = cols), NA)
# Force axis lines to cover the plot extents
axis(1, at = par("usr")[1:2], labels = c("", ""), lwd.ticks = 0)
axis(2, at = par("usr")[3:4], labels = c("", ""), lwd.ticks = 0)
# Calculate centre of each group
at <- colMeans(matrix(ps$extents[,1], nrow = 4))
axis(1, at = at, labels = names(meansA))
title(xlab = "solution")
legend(par("usr")[2] + 0.2, mean(par("usr")[3:4]), yjust = 0.5, xpd = NA,
c("1, no exposure", "2, short exposure", "3, exposure withheld", "4, constant exposure"),
col = cols, lwd = 3, pch = 19, bty = "n")
}
})
test_that("group labels etc", {
# Add in some fake sex data to the insulin data set
data <- cbind(insulin, Sex = sample(c("Male", "Female"), nrow(insulin), replace = TRUE))
# Thin it the data so individual symbols are visible
data <- data[data$id %in% 1:15, ]
d <- DurgaDiff(data, "sugar", "treatment", "id", groups = c("Before insulin" = "before", "After insulin" = "after"), na.rm = TRUE)
expect_error(DurgaPlot(d,
left.ylab = "Blood sugar level",
violin.shape = c("left", "right"), violin.dx = c(-0.055, 0.055), violin.width = 0.3,
points = "black",
points.params = list(bg = ifelse(data$Sex == "Female", "red", "blue"), pch = ifelse(data$Sex == "Female", 21, 24)),
ef.size.pch = 19,
ef.size.violin = "blue",
ef.size.violin.shape = "full",
central.tendency = FALSE,
main = "Customised plot"),
NA)
d <- DurgaDiff(iris, data.col = "Sepal.Length", group.col = "Species")
expect_error(DurgaPlot(d, bar = TRUE, error.bars.type = "SD", points = FALSE, main = "Bar chart with std. deviation"), NA)
expect_error(DurgaPlot(d, box = TRUE, error.bars = TRUE, central.tendency.type = "median", error.bars.type = "CI", points = FALSE, main = "Box plot with 95% CI"), NA)
expect_error(DurgaPlot(d, bar = TRUE, central.tendency.symbol = "segment", error.bars.type = "SE", points = FALSE, main = "Bar chart with SE"), NA)
})
test_that("plot miscellanea", {
d <- DurgaDiff(damselfly, "length", "maturity",
groups = c("Immature" = "juvenile", "Mature" = "adult"))
# Axis text is smaller when there are multiple columns
op <- par(mfrow = c(1, 3))
on.exit(par(op))
DurgaPlot(d, ef.size.position = "below", main = "Text size consistent")
par(mar = c(5, 4, 4, 6) + 0.1)
DurgaPlot(d, bar = T)
DurgaPlot(d, box = T, xlim = c(0, 5), ylim = c(28, 40), main = "Explicit limits")
expect_equal(1, 1)
expect_error(DurgaDiff(petunia, 1, 2,
groups = c("self-fertilised" = "self_fertilised",
"intercrossed" = "inter_cross",
"Westerham-crossed" = "westerham_cross"),
contrasts = c("Westerham-crossed - self-fertilised",
"Westerham-crossed - intercrossed",
"intercrossed - self-fertilised")), NA)
})
test_that("CI", {
x <- rnorm(200)
CI90 <- meanCI(x, .9)
CI95 <- meanCI(x, .95)
expect_lt(CI95[1], mean(x))
expect_lt(CI95[1], CI90[1])
expect_gt(CI95[2], mean(x))
expect_gt(CI95[2], CI90[2])
set.seed(1)
d90 <- DurgaDiff(petunia, "height", "group", ci.conf = .9)
d95 <- DurgaDiff(petunia, "height", "group", ci.conf = .95)
d99 <- DurgaDiff(petunia, "height", "group", ci.conf = .99)
# CI should be smaller for lower levels
for (g in seq_along(d90$groups)) {
# Ensure we are comparing the same things
expect_equal(d90$group.differences[[g]]$groupLabels, d95$group.differences[[g]]$groupLabels)
expect_equal(d90$group.differences[[g]]$groupLabels, d99$group.differences[[g]]$groupLabels)
# Check CI of mean differences
# Lower limits
expect_gt(d90$group.differences[[g]]$bca[4], d95$group.differences[[g]]$bca[4])
expect_gt(d95$group.differences[[g]]$bca[4], d99$group.differences[[g]]$bca[4])
# Upper limits
expect_lt(d90$group.differences[[g]]$bca[5], d95$group.differences[[g]]$bca[5])
expect_lt(d95$group.differences[[g]]$bca[5], d99$group.differences[[g]]$bca[5])
# Check CI of group means
expect_gt(d90$group.statistics[g, "CI.lower"], d95$group.statistics[g, "CI.lower"])
expect_gt(d90$group.statistics[g, "CI.lower"], d95$group.statistics[g, "CI.lower"])
expect_lt(d95$group.statistics[g, "CI.upper"], d99$group.statistics[g, "CI.upper"])
expect_lt(d95$group.statistics[g, "CI.upper"], d99$group.statistics[g, "CI.upper"])
}
})
test_that("Diff error detection", {
n <- 40
set.seed(1)
realDiff <- 1
df <- data.frame(val = c(rnorm(n, mean = 10), rnorm(n, mean = 10 + realDiff)),
group = c(rep("Control", n), rep("Group", n)),
id = c(1:n, 1:n))
# Shuffle
df <- df[sample(nrow(df)), ]
# Missing group
expect_error(DurgaDiff(df, data.col = 1, group.col = 2, groups = c("Control", "Group", "Nonexistent")), "Nonexistent")
# Non factor ID
d1 <- DurgaDiff(df, data.col = 1, group.col = 2, id.col = 3)
expect_true(d1$paired.data)
# Factor ID
df$id <- factor(df$id)
d2 <- DurgaDiff(df, data.col = 1, group.col = 2, id.col = 3)
expect_true(d2$paired.data)
compareDiffs(d2, d1)
# Missing IDs - remove some of the Group values
removeIdxs <- sample(which(df$group == "Group"), 10)
df <- df[-removeIdxs, ]
expect_error(DurgaDiff(df, data.col = 1, group.col = 2, id.col = 3), "id")
# Non-numeric value
expect_error(DurgaDiff(df, data.col = 3, group.col = 2, id.col = 3), "numeric")
# Empty data frame
expect_error(DurgaDiff(df[numeric(0), ], data.col = 1, group.col = 2, id.col = 3), "No data")
})
test_that("single group", {
op <- par(mfrow = c(1, 2))
on.exit(par(op))
n <- 40
df <- data.frame(val = rnorm(n, 10),
group = rep("G1", each = n))
d <- DurgaDiff(df, data.col = 1, group.col = 2)
p <- expect_error(DurgaPlot(d, main = "1 group in data"), NA)
df <- data.frame(val = c(rnorm(n, 10), rnorm(n, 11)),
group = rep(c("G1", "G2"), each = n))
d <- DurgaDiff(df, data.col = 1, group.col = 2, groups = "G1")
expect_error(DurgaPlot(d, main = "1 group in diff"), NA)
})
test_that("group colours", {
op <- par(mfrow = c(2, 2))
on.exit(par(op))
d <- DurgaDiff(petunia, 1, 2)
DurgaPlot(d, ef.size = FALSE, group.colour = "Set1", main = "Group colours Set1")
DurgaPlot(d, ef.size = FALSE, group.colour = "blue", main = "group.colours blue")
DurgaPlot(d, ef.size = FALSE, group.colour = c("red", "Green", "blue"), main = "group.colours RGB, points fill coloured",
points = "black", points.params = list(pch = 21))
DurgaPlot(d, ef.size = FALSE, group.colour = c("red", "Green", "#0000ff"), main = "group.colours RGB, points red fill",
points.params = list(pch = 21, bg = "red"))
# Invalid colour/palette
expect_error(DurgaPlot(d, group.colour = "Fred"))
expect_error(DurgaPlot(d, group.colour = c("Set1", "Dark1")))
})
test_that("minor formatting", {
d <- DurgaDiff(damselfly, 1, 3)
expect_error(DurgaPlot(d, main = "Offset lines, styled error bars, ef size lines",
error.bars = "red", error.bars.lwd = 5, error.bars.lty = 4,
ef.size.mean.line.dx = 0.2, ef.size.line.col = "blue",
ef.size.line.lwd = 3, ef.size.line.lty = 3,
ef.size.violin = "blue", ef.size.violin.fill = "pink"), NA)
expect_error(DurgaPlot(d, main = "Offset lines, styled error bars, ef size line",
ef.size.position = "below",
error.bars = "red", error.bars.lwd = 5, error.bars.lty = 4,
ef.size.mean.line.dx = 0.2, ef.size.line.col = "blue",
ef.size.line.lwd = 3, ef.size.line.lty = 1,
ef.size.violin = "blue", ef.size.violin.fill = "pink"), NA)
})
test_that("Spaces in column names", {
n <- 40
df <- data.frame(`Genital length` = c(rnorm(n, mean = 10)),
`Cannibalism y/n` = sample(c("Yes", "No"), n, replace = TRUE),
check.names = FALSE)
d <- DurgaDiff(df, "Genital length", "Cannibalism y/n")
expect_error(DurgaPlot(d, xlab = "Cannibalism?", main = "Spaces in names, xlab"), NA)
})
test_that("Formula", {
n <- 40
set.seed(1)
valVar <- c(rnorm(n, mean = 10), rnorm(n, mean = 11))
df <- data.frame(`Scapus length` = valVar,
val = valVar,
group = c(rep("Control", n), rep("Group", n)),
id = c(1:n, 1:n),
check.names = FALSE)
`Group cat` <- df$group
op <- par(mfrow = c(1, 2))
on.exit(par(op))
DurgaPlot(DurgaDiff(valVar ~ group, df, id.col = "id", groups = c("Control", "Group")), main = "Formula interface, paired")
DurgaPlot(DurgaDiff(df, "val", "group", "id", groups = c("Control", "Group")), main = "Standard interface, paired")
# More complicated formulae
DurgaPlot(DurgaDiff(log(valVar) ~ group, df), main = "Formula interface")
DurgaPlot(DurgaDiff(`Scapus length` ~ group, data = df), main = "Formula interface")
DurgaPlot(DurgaDiff(log(`Scapus length`) ~ group, data = df), main = "Formula interface")
DurgaPlot(DurgaDiff(log(`Scapus length`) ~ `Group cat`, data = df), main = "Formula interface")
expect_error(DurgaDiff(`Scapus lengh` ~ group, data = df))
})
test_that("custom stat", {
# Example from http://www.estimationstats.com/#/analyze/shared-control
ds <- "A1 A2 B1 B2 C1 C2 D1 D2
8.885 10.135 8 -35 3.375 6.625 0.54 -0.54
14.38 11.94 7 -30 -0.3 2.3 1.98 0.02
8.015 6.025 17 -25 10.025 11.975 1.1 0.9
5.835 3.045 15 -20 2.35 3.65 3.42 0.58
5.47 1.87 12 -15 7.675 8.325 2.54 1.46
12.06 12.64 5 -10 9 9 1.655 2.345
11.72 9.66 6 -5 7.325 6.675 4.865 1.135
10.315 9.265 19 0 6.65 5.35 3.98 2.02
5.065 6.155 16 5 4.975 3.025 3.1 2.9
8.235 10.785 11 10 3.3 0.7 2.215 3.785
15.08 12.36 18 15 11.625 8.375 6.305 1.695
13.485 10.175 9 20 17.765 8.235 5.42 2.58
11.3 12.38 14 25 17.09 6.91 4.54 3.46
9.82 9.66 13 30 19.41 8.59 3.655 4.345
9.565 6.955 10 35 20.735 9.265 2.775 5.225"
dw <- read.delim(text = ds)
# Convert to long format
l <- lapply(colnames(dw), function(c) data.frame(value = as.numeric(dw[[c]]), group = c, id = seq_along(c)))
df <- do.call(rbind, l)
# Single difference
dd1 <- DurgaDiff(df, 1, 2, groups = c("A1", "A2"))
dc1 <- DurgaDiff(df, 1, 2, groups = c("A1", "A2"), effect.type = function(x1, x2) { median(x2) - median(x1) })
# Many groups
set.seed(1)
dd <- DurgaDiff(df, 1, 2, contrasts = ". - A1")
set.seed(1)
dc <- DurgaDiff(df, 1, 2, contrasts = ". - A1", effect.type = function(x1, x2) { median(x2) - median(x1) })
# Check that group details are the same, pairwise differences are different
od <- capture.output(print(dd))
oc <- capture.output(print(dc))
expect_equal(which(od == oc), 1:12)
# Check it can be plotted
# One contrast
op <- par(mfrow = c(1, 2))
expect_error(DurgaPlot(dd1, main = "Defaults"), NA)
expect_error(DurgaPlot(dc1, main = "Custom median differences"), NA)
par(op)
# Many contrasts
op <- par(mfrow = c(2, 1))
expect_error(DurgaPlot(dd, main = "Defaults"), NA)
expect_error(DurgaPlot(dc, main = "Custom median differences"), NA)
par(op)
})
test_that("custom labels", {
data <- makeData()
d <- DurgaDiff(data, 1, 2, groups = c("ZControl1", "Group1", "Group2"))
# Override effect size label
d$group.differences[[2]]$label.plot <- expression(italic("Sp. 1") ~ "-" ~ italic("Sp. 2"))
# Override effect name label
expect_error(DurgaPlot(d, ef.size.label = expression(bold("Bold name")), x.axis = F), NA)
# Override print label
d$group.differences[[2]]$label.print <- "Sp. 1 : Sp. 2"
s <- capture.output(print(d))
expect_match(s[10], "^ *Sp. 1 : Sp. 2:")
})
test_that("ef range plot bug", {
n <- c(20, 30, 50, 30)
seasons <- c("Spring", "Summer", "Autumn", "Winter")
df <- data.frame(proportion = c(
rnorm(n[1], mean = 0.1, sd = 0.01),
rnorm(n[2], mean = 0.15, sd = 0.015),
rnorm(n[3], mean = 0.25, sd = 0.02),
rnorm(n[4], mean = 0.6, sd = 0.03)
), season = rep(seasons, n)
)
d <- DurgaDiff(df, 1, 2, contrasts = ". - Winter", groups = seasons)
expect_error(DurgaPlot(d, main = "Effect size ylim correct"), NA)
})
test_that("ef below layout", {
data <- makeData()
d <- DurgaDiff(data, 1, 2, groups = c("ZControl1", "Group1", "Group2"))
op <- par(mfrow = c(1, 2), cex = 0.7)
on.exit(par(op))
expect_error(DurgaPlot(d, main = "Default EF layout"), NA)
expect_error(DurgaPlot(d, ef.size.top.pad = 1.5, ef.size.height = 0.6, main = "Smaller gap, larger height"), NA)
})
test_that("ef size ticks", {
data <- makeData()
op <- par(mfrow = c(2, 2), mar = c(5, 4, 4, 1) + 0.1)
on.exit(par(op))
d <- DurgaDiff(data, 1, 2, groups = c("ZControl1", "Group1", "Group2"))
DurgaPlot(d, main = "Custom ef ticks", ef.size.ticks = c(30, 0, -50))
DurgaPlot(d, contrasts = "Group2 - ZControl1", main = "Custom ef ticks", ef.size.ticks = c(30, 0, -50))
d <- DurgaDiff(data, 1, 2, groups = c("ZControl1", "Group1", "Group2"), effect.type = "cohens d")
DurgaPlot(d, main = "Custom ef ticks", ef.size.ticks = c(-2, 0, 1))
expect_error(DurgaPlot(d, contrasts = "Group2 - ZControl1", main = "Custom ef ticks", ef.size.ticks = c(-2, 0, 1)), NA)
})
test_that("ef size labels", {
data <- makeData()
op <- par(mfrow = c(2, 2))
on.exit(par(op))
d <- DurgaDiff(data, 1, 2, groups = c("ZControl1", "Group1", "Group2"))
DurgaPlot(d, main = "Custom ef labels", ef.size.ticks = c("Big" = 30, "None" = 0, "Huge" = -50), ef.size.params = list(las = 1))
DurgaPlot(d, contrasts = "Group2 - ZControl1", main = "Custom ef labels", ef.size.ticks = c("Big" = 30, "None" = 0, "Huge" = -50), ef.size.params = list(las = 1))
d <- DurgaDiff(data, 1, 2, groups = c("ZControl1", "Group1", "Group2"), effect.type = "cohens d")
DurgaPlot(d, main = "Custom ef labels", ef.size.ticks = c("Huge" = -2, "None" = 0, "Big" = 1), ef.size.params = list(las = 1))
expect_error(DurgaPlot(d, contrasts = "Group2 - ZControl1", main = "Custom ef labels", ef.size.ticks = c("Huge" = -2, "None" = 0, "Big" = 1), ef.size.params = list(las = 1)), NA)
})
test_that("ef size symbology", {
data <- makeData()
op <- par(mfrow = c(1, 2))
on.exit(par(op))
d <- DurgaDiff(data, 1, 2, groups = c(Control = "ZControl1", "Group1", "Group2"))
expect_error(DurgaPlot(d, main = "Custom ef symbology", ef.size = 2:3, ef.size.lty = 3:2, ef.size.lwd = c(4, 2)), NA)
d <- DurgaDiff(data, 1, 2, groups = c(Control = "ZControl1", "Group1"), effect.type = "cohens d")
expect_error(DurgaPlot(d, main = "Custom ef symbology", ef.size.lty = 2, ef.size.lwd = 4), NA)
})
test_that("pathological data", {
# There is a weird case when the density does not extend past the data
n <- 10000
df <- data.frame(Value = c(rnorm(n), 500, rnorm(n), -500),
group = rep(c("G1", "G2"), each = n + 1))
d <- DurgaDiff(df, 1, 2, contrasts = NULL, R = NA) # Don't bootstrap anything
expect_error(DurgaPlot(d, main = "Pathological case - don't crash!"), NA)
})
test_that("points layout", {
# Make some bimodal data
n1 <- 300
n2 <- 100
n3 <- 50
n <- n1 + n2 + n3
data <- data.frame(Measurement = c(rnorm(n1, mean = 1), rnorm(n2, mean = 4), rnorm(n3, mean = 7, sd = 0.2),
rnorm(n1, mean = 4), rnorm(n2, mean = 0.5), rnorm(n3, mean = -1, sd = 0.5)),
Group = rep(c("Group 1", "Group 2"), each = n))
op <- par(mfrow = c(2, 2))
on.exit(par(op))
d <- DurgaDiff(data, 1, 2, contrasts = "")
expect_error(DurgaPlot(d, main = "Default point layout", ef.size = FALSE), NA)
expect_error(DurgaPlot(d, main = "Adjust = 0.7", ef.size = FALSE, points.adjust = 0.7, violin.adj = 0.7), NA)
expect_error(DurgaPlot(d, main = "Method = tukey", ef.size = FALSE, points.method = "tukey"), NA)
expect_error(DurgaPlot(d, main = "Method = overplot", ef.size = FALSE, points.method = "overplot"), NA)
})
test_that("missing right axis", {
# Bug: Can fail with very small group sizes, because bootstrap wasn't stratified
stats <- structure(list(cat = c("RelearningwalksOld", "RelearningwalksOld",
"RelearningwalksOld", "RelearningwalksOld", "RelearningwalksOld",
"RelearningwalksOld", "RelearningNew", "RelearningNew", "RelearningNew",
"RelearningNew", "RelearningNew"),
`Convex hull area` = c(5749.50993182344,
12052.2167954142, 11692.8373439029, 5327.12611957551, 434.590489399867,
19118.6301846389, 7934.00774651262, 28646.8325343417, 25339.7006681887,
11880.8673679235, 26535.4117772832),
`Max displacement` = c(8.41844123108767,
6.34767201343218, 25.188225965698, 6.20186762835405, 2.10714057756224,
5.98568895263556, 11.3602307617808, 15.453027281305, 11.3599509921636,
18.5884235814962, 21.898981986908),
Duration = c(25.02, 43.14, 25.6, 44.76, 13.1, 55.48, 8.28, 9.52, 22, 9.28, 11.96)),
row.names = c(NA, -11L), class = "data.frame")
learningSheets <- c(`Old nest relearning walks` = "RelearningwalksOld", `New nest relearning walks` = "RelearningNew")
set.seed(1)
d <- DurgaDiff(stats, "Convex hull area", "cat", groups = learningSheets)
expect_error(DurgaPlot(d, main = "Effect size axis present?"), NA)
data <- data.frame(Val = rnorm(10), Group = c(1, 1, rep(2, 8)))
expect_error(DurgaDiff(data, 1, 2), NA)
})
test_that("Wide format data", {
n <- 10
wide <- data.frame(Control = rnorm(n, 10), Treatment = rnorm(n, 11), Mass = rnorm(n, 2, .4))
l <- stats::reshape(wide, direction = "long",
varying = list(c("Control", "Treatment")),
idvar = "Specimen",
v.names = "Measurement", # Name of the value column
timevar = "Condition", # Name of the group column
times = c("Control", "Treatment"))
d1 <- DurgaDiff(l, "Measurement", "Condition")
d2 <- DurgaDiff(wide, id.col = "Specimen", groups = c("Control", "Treatment"))
par(mfrow = c(2, 2))
DurgaPlot(d1, main = "Manual wide to long")
expect_error(DurgaPlot(d2, main = "Auto wide to long"), NA)
# 3 groups
n <- 20
df3 <- data.frame(Control = rnorm(n, 10),
Treatment1 = rnorm(n, 11),
Treatment2 = rnorm(n, 11.1, .4),
Treatment3 = rnorm(n, 9, 2))
d <- DurgaDiff(df3, id.col = "Id", groups = c("Control", "Treatment1", "Treatment2", "Treatment3"))
DurgaPlot(d, main = "Paired - multiple groups", left.ylab = "Mass (g)")
DurgaPlot(d, main = "Paired - multiple groups, contrasts", left.ylab = "Mass (g)",
contrasts = "Treatment1 - Control, Treatment2 - Treatment1, Treatment3 - Treatment2")
# Id column that isn't unique
df <- data.frame(id = rep(1:5, each = 2), Control = rnorm(10, 10), Treatment = rnorm(10, 11))
expect_error(DurgaDiff(df, id.col = "id", groups = c("Control", "Treatment")))
# Id column not specified
df <- data.frame(Control = rnorm(10, 10), Treatment = rnorm(10, 11))
d <- DurgaDiff(df, groups = c("Control", "Treatment"))
expect_true(d$paired.data)
# Existing id column not specified
df <- data.frame(id = sample(10), Control = rnorm(10, 10), Treatment = rnorm(10, 11))
d <- DurgaDiff(df, groups = c("Control", "Treatment"))
expect_true(d$paired.data)
})
test_that("mapY fn", {
my <- buildMapYFn(c(0, 1), c(0, 1))
expect_equal(my(0), 0)
expect_equal(my(1), 1)
expect_equal(my(2), 2)
expect_equal(my(-2), -2)
my <- buildMapYFn(c(1, 2), c(2, 1))
expect_equal(my(1), 2)
expect_equal(my(2), 1)
expect_equal(my(3), 0)
my <- buildMapYFn(c(1, 0), c(1, 0))
expect_equal(my(0), 0)
expect_equal(my(1), 1)
expect_equal(my(2), 2)
expect_equal(my(-2), -2)
})
test_that("group means", {
# Should a 2-sample group generate an error because the group mean CI can't be estimated?
# No, because sometimes people have 2 sample groups and can't get more data
df <- data.frame(val = c(rnorm(2), rnorm(4, 1)),
group = c("A", "A", "B", "B", "B", "B"))
d <- expect_error(DurgaDiff(df, "val", "group"), NA)
expect_true(is.na(d$group.statistics[1, "CI.lower"]))
expect_true(is.na(d$group.statistics[1, "CI.upper"]))
expect_true(!is.na(d$group.statistics[2, "CI.lower"]))
expect_true(!is.na(d$group.statistics[2, "CI.upper"]))
})
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.