canvasSampvarPropDiff <- setRefClass("canvasSampvarPropDiffClass", contains = "canvasPlotClass",
methods = list(
calcStat = function(i = which.sample, ys = NULL, canvas = .self) {
props <- calcPropDiff(samples[[i]], level.samples[[i]], canvas)
# Sorting in ylevel order but reversing so we end up
# with correct differences
rev(props[canvas$ylevels])
},
calcAllStats = function(xs, ys = NULL, canvas = .self) {
props <- calcPropDiff(xs, ys, canvas)
# Sorting in ylevel order but reversing so we end up
# with correct differences
rev(props[canvas$ylevels])
},
animateStat = function(env, n.steps) {
dropBootPropDiffArrow(.self, env, n.steps)
},
plotSample = function(env, i = which.sample, alpha = 0.2, ...) {
plotKSampvarProportions(.self, env, i, alpha = alpha)
},
showLabels = function() {
sampvarDiffLabels(.self)
},
plotDataStat = function(env, ...) {
dataDiffArrowProp(.self, env)
},
plotStatDist = function(env, ...) {
plotBootDiffDist(.self, env)
},
animateSample = function(e, n.steps, n.slow, opts) {
dropSampvarPropDiffSample(.self, e, n.steps, n.slow)
},
handle1000 = function(env, ...) {
sampvarDiff1000(.self, env, ...)
},
displayResult = function(env, ...){
plotSampvarTwoSampPropTheoDist(.self, env, ...)
}))
load_sampvar_proportion_diff <- function(e) {
e$c1$stat.in.use <- svalue(e$stat)
e$sampvar.method <- svalue(e$sampvar.choices)
e$c1$stat.method <- e$sampvar.method
# There is something messy going on with viewports and
# gTrees, such that when attempting to import them, we
# end up with "uninitializedField"s. Assign to a temp
# var and reassign later.
tmp.vps <- e$c1$viewports
tmp.image <- e$c1$image
e$c1$viewports <- NULL
e$c1$image <- NULL
tmp.canvas <- canvasSampvarPropDiff$new()
tmp.canvas$import(e$c1)
e$c1 <- tmp.canvas
e$c1$viewports <- tmp.vps
e$c1$image <- tmp.image
e$difference <- TRUE
}
plotKSampvarProportions <- function(canvas, e, i, alpha = 0.2) {
index <- canvas$indexes[[i]]
x <- canvas$x[index]
x[x != canvas$loi] <- canvas$loi.alt
data.levels <- as.character(canvas$levels)
levels <- data.levels[index]
ylevels <- canvas$ylevels
n <- canvas$n
props <- rev(calcPropDiff(x, levels, canvas)[ylevels])
canvas$sampled.stats <- c(canvas$sampled.stats, i)
all.props <- canvas$stat.dist[canvas$sampled.stats, 2:1, drop = FALSE]
# Finding the max width to place the levels labels within
seekViewport(canvas$graphPath("sample", 1))
max.str.width <- stringWidth(ylevels)
max.str.width <- convertWidth(max(max.str.width), "native", valueOnly = TRUE)
upViewport(0)
for (j in 1:length(ylevels)) {
level.props <- all.props[, j]
yloc <- if (j == 1) 0.5 else -0.1
canvas$image <- addGrob(canvas$image,
rectGrob(x = unit(level.props, "npc"),
y = unit(yloc, "npc"), height = unit(0.1, "npc"),
width = unit(0, "npc"), just = c("left", "bottom"),
gp = gpar(alpha = alpha, col = "blue", lwd = 2),
vp = canvas$graphPath("sample", j),
name = paste("samplePlot.ghosts.", j, sep = "")))
# We add a blank white rect to obscure most of the ghosting lines
# so that they are not visible through the propbar.
canvas$image <- addGrob(canvas$image,
rectGrob(x = unit(0, "npc"), y = unit(0, "npc"),
width = unit(1, "npc"), height = unit(0.5, "npc"),
just = c("left", "bottom"),
gp = gpar(fill = "white", col = "white"),
vp = canvas$graphPath("sample", j),
name = paste("samplePlot.blank.", j, sep = "")))
canvas$image <- addGrob(canvas$image, kpropbarGrob
(x[levels == ylevels[j]],
ylab = ylevels[j],
ylab.pos = 1 - max.str.width,
ylab.col = getColour(j, length(ylevels)),
draw.points = FALSE,
lois = c(canvas$loi, canvas$loi.alt),
y = 0, height = 0.5, vpcex = 1 / length(ylevels),
name = paste("samplePlot.propbar", j, sep = "."),
vp = canvas$graphPath("sample", j)))
}
# Now we are creating the points which we light up if possible
dataProp1 <- getGrob(canvas$image, gPath("dataPlot.propbar.1"))
dataProp2 <- getGrob(canvas$image, gPath("dataPlot.propbar.2"))
show.points <- dataProp1$points.present & dataProp2$points.present
pointCols <- ifelse(levels == ylevels[1],
ifelse(x == canvas$loi,
getColour(1, 2, l = 85),
getColour(1, 2, l = 45)),
ifelse(x == canvas$loi,
getColour(2, 2, l = 85),
getColour(2, 2, l = 45)))
if (show.points) {
# Need to dive into each VP and grab the size of the units relative
# animation.field VP. Because we're dealing with two data VPs, each
# will be scaled by a half.
depth <- downViewport(canvas$graphPath("data", 1))
prop1.dpx <- convertX(dataProp1$x, "native", valueOnly = TRUE)
prop1.dpy <- convertY(dataProp1$y, "native", valueOnly = TRUE) / length(ylevels)
upViewport(depth)
depth <- downViewport(canvas$graphPath("data", 2))
prop2.dpx <- convertX(dataProp2$x, "native", valueOnly = TRUE)
prop2.dpy <- convertY(dataProp2$y, "native", valueOnly = TRUE) / length(ylevels)
upViewport(depth)
# Need to translate the coordinates so that they fit in the
# animation.field viewport
prop1.dpy <- prop1.dpy + 2
prop2.dpy <- prop2.dpy + 2.5
}
if (show.points) {
# Calculating index vectors so that the i'th
# value corresponds to the correct location within
# each of the data propbars.
first.level.ind <- 1
second.level.ind <- 1
data.index <- integer(length(data.levels))
for (i in 1:length(data.levels)) {
if (data.levels[i] == ylevels[1]) {
data.index[i] <- first.level.ind
first.level.ind <- first.level.ind + 1
} else {
data.index[i] <- second.level.ind
second.level.ind <- second.level.ind + 1
}
}
}
# Animation of slow points.
pxs <- numeric(n)
pys <- numeric(n)
if (show.points) {
# Light up point to drop
for (i in 1:n) {
pxs[i] <- if (levels[i] == ylevels[1])
prop1.dpx[data.index[index[i]]]
else
prop2.dpx[data.index[index[i]]]
pys[i] <- if (levels[i] == ylevels[1])
prop1.dpy[data.index[index[i]]]
else
prop2.dpy[data.index[index[i]]]
}
}
# Plot the points that have been sampled.
if (show.points) {
temp.point2 <- pointsGrob(pxs,
pys,
pch = 19, gp = gpar(col = pointCols),
vp = canvas$graphPath("animation.field"),
name = "samplePlot.datapoints")
canvas$image <- addGrob(canvas$image, temp.point2)
}
# If we're not doing ANOVA, show the difference
if (length(ylevels) == 2) {
canvas$image <- addGrob(canvas$image, linesGrob
(x = unit(props, "native"),
y = unit(0.75, "native"),
gp = gpar(lwd = 2, col = "red"),
arrow = arrow(length = unit(0.1, "inches")),
vp = canvas$graphPath("sample", 1),
name = "samplePlot.line.1"))
}
}
dropSampvarPropDiffSample <- function(canvas, e, drop.points = FALSE, n.steps = 10, n.slow = 5, max = 50) {
rmvec <- 1:length(canvas$ylevels)
canvas$rmGrobs(c(paste("samplePlot.blank", rmvec, sep = "."),
paste("samplePlot.propbar", rmvec, sep = "."),
"samplePlot.line.1", "samplePlot.datapoints"))
n <- canvas$n
index <- canvas$indexes[[canvas$which.sample]]
sample <- canvas$x
levels <- as.character(canvas$levels)
resample <- sample[index]
resample.levels <- levels[index]
ylevels <- canvas$ylevels
dataProp1 <- getGrob(canvas$image, gPath("dataPlot.propbar.1"))
dataProp2 <- getGrob(canvas$image, gPath("dataPlot.propbar.2"))
animate.points <- dataProp1$points.present & dataProp2$points.present
pointCols <- ifelse(resample.levels == ylevels[1],
ifelse(resample == canvas$loi,
getColour(1, 2, l = 85),
getColour(1, 2, l = 45)),
ifelse(resample == canvas$loi,
getColour(2, 2, l = 85),
getColour(2, 2, l = 45)))
# In the case that we're tracking, get rid of the sample plots
if (drop.points & animate.points)
canvas$rmGrobs(c("samplePlot.propbar.1", "samplePlot.propbar.2",
"samplePlot.ghosts.1", "samplePlot.ghosts.2",
"samplePlot.blank.1", "samplePlot.blank.2",
"samplePlot.line.1"))
if (n < 100 & length(canvas$x) < 100) {
if (animate.points) {
# Need to dive into each VP and grab the size of the units relative
# animation.field VP. Because we're dealing with two data VPs, each
# will be scaled by a half.
depth <- downViewport(canvas$graphPath("data", 1))
prop1.dpx <- convertX(dataProp1$x, "native", valueOnly = TRUE)
prop1.dpy <- convertY(dataProp1$y, "native", valueOnly = TRUE) / length(ylevels)
upViewport(depth)
depth <- downViewport(canvas$graphPath("data", 2))
prop2.dpx <- convertX(dataProp2$x, "native", valueOnly = TRUE)
prop2.dpy <- convertY(dataProp2$y, "native", valueOnly = TRUE) / length(ylevels)
upViewport(depth)
# Creating sample propbars and grabbing the point locations
# from each of the propbars.
sampleProp1 <- kpropbarGrob(resample[resample.levels == ylevels[1]],
ylab = ylevels[1],
draw.points = animate.points,
lois = c(canvas$loi, canvas$loi.alt),
y = 0.1, height = 0.5,
name = paste("samplePlot.propbar", 1, sep="."),
vp = canvas$graphPath("sample", 1))
sampleProp2 <- kpropbarGrob(resample[resample.levels == ylevels[2]],
ylab = ylevels[2],
draw.points = animate.points,
lois = c(canvas$loi, canvas$loi.alt),
y = 0, height = 0.5,
name = paste("samplePlot.propbar", 2, sep="."),
vp = canvas$graphPath("sample", 2))
depth <- downViewport(canvas$graphPath("sample", 1))
prop1.spx <- convertX(sampleProp1$x, "native", valueOnly = TRUE)
prop1.spy <- convertY(sampleProp1$y, "native", valueOnly = TRUE) / length(ylevels)
upViewport(depth)
depth <- downViewport(canvas$graphPath("sample", 2))
prop2.spx <- convertX(sampleProp2$x, "native", valueOnly = TRUE)
prop2.spy <- convertY(sampleProp2$y, "native", valueOnly = TRUE) / length(ylevels)
upViewport(depth)
# Need to translate the coordinates so that they fit in the
# animation.field viewport
prop1.dpy <- prop1.dpy + 2
prop2.dpy <- prop2.dpy + 2.5
prop1.spy <- prop1.spy + 1
prop2.spy <- prop2.spy + 1.5
}
first.group <- levels == ylevels[1]
max.width.x <- max(convertX(stringWidth(sample),
"cm", valueOnly = TRUE))
max.width.y <- max(convertX(stringWidth(ylevels),
"cm", valueOnly = TRUE))
max.width.x <- unit(max.width.x, "cm")
max.width.y <- unit(max.width.y, "cm")
if (drop.points & animate.points) {
# Drawing labels to more easily identify which level each point belongs to.
depth <- downViewport(canvas$graphPath("sample", 1))
ylab.height <- convertHeight(max(stringHeight(ylevels)), "native", valueOnly = TRUE)
upViewport(depth)
for (i in 1:length(ylevels)) {
canvas$image <- addGrob(canvas$image, textGrob
(ylevels[i],
x = unit(1, "npc"),
y = unit(0.7, "native"),
just = c("right", "bottom"),
gp = gpar(col = getColour(i, length(ylevels))),
name = paste("samplePlot.yLab", i, sep = "."),
vp = canvas$graphPath("sample", i)))
}
}
if (animate.points) {
# Calculating index vectors so that the i'th
# value corresponds to the correct location within
# each of the data propbars.
first.level.ind <- 1
second.level.ind <- 1
data.index <- integer(length(levels))
for (i in 1:length(levels)) {
if (levels[i] == ylevels[1]) {
data.index[i] <- first.level.ind
first.level.ind <- first.level.ind + 1
} else {
data.index[i] <- second.level.ind
second.level.ind <- second.level.ind + 1
}
}
first.level.ind <- 1
second.level.ind <- 1
sample.index <- integer(length(levels))
for (i in 1:length(resample)) {
if (resample.levels[i] == ylevels[1]) {
sample.index[i] <- first.level.ind
first.level.ind <- first.level.ind + 1
} else {
sample.index[i] <- second.level.ind
second.level.ind <- second.level.ind + 1
}
}
# Initialising vectors for points so that we can draw them more easily later
points.xs <- numeric(n)
points.ys <- numeric(n)
xs.step <- numeric(n)
ys.step <- numeric(n)
points.cols <- character(n)
# Because the position of the point is dependent on both the ylevel and the level
# we need to work out the appropriate stepping from the data to the sample.
for (i in 1:length(resample)) {
if (resample.levels[i] == ylevels[1]) {
if (levels[index[i]] == ylevels[1]) {
xs.step[i] <- (prop1.dpx[data.index[index[i]]] - prop1.spx[sample.index[i]]) / n.steps
ys.step[i] <- (prop1.dpy[data.index[index[i]]] - prop1.spy[sample.index[i]]) / n.steps
} else {
xs.step[i] <- (prop2.dpx[data.index[index[i]]] - prop1.spx[sample.index[i]]) / n.steps
ys.step[i] <- (prop2.dpy[data.index[index[i]]] - prop1.spy[sample.index[i]]) / n.steps
}
points.xs[i] <- prop1.spx[sample.index[i]]
points.ys[i] <- prop1.spy[sample.index[i]]
points.cols[i] <- if (resample[i] == canvas$loi) "blue" else "red"
} else {
if (levels[index[i]] == ylevels[1]) {
xs.step[i] <- (prop1.dpx[data.index[index[i]]] - prop2.spx[sample.index[i]]) / n.steps
ys.step[i] <- (prop1.dpy[data.index[index[i]]] - prop2.spy[sample.index[i]]) / n.steps
} else {
xs.step[i] <- (prop2.dpx[data.index[index[i]]] - prop2.spx[sample.index[i]]) / n.steps
ys.step[i] <- (prop2.dpy[data.index[index[i]]] - prop2.spy[sample.index[i]]) / n.steps
}
points.xs[i] <- prop2.spx[sample.index[i]]
points.ys[i] <- prop2.spy[sample.index[i]]
points.cols[i] <- if (resample[i] == canvas$loi) "blue" else "red"
}
}
}
n.slow <- min(n.slow, n)
if (drop.points & animate.points) {
for (j in 1:length(ylevels)) {
canvas$image <- addGrob(canvas$image, rectGrob
(x = unit(0, "native"), y = unit(if (j == 1) 0.1 else 0, "native"),
width = unit(1, "native"), height = unit(0.5, "native"),
just = c("left", "bottom"),
gp = gpar(col = getColour(j, length(ylevels)),
fill = "transparent", lwd = 3),
name = paste("samplePlot.boundRect", j, sep = "."),
vp = canvas$graphPath("sample", j)))
canvas$image <- addGrob(canvas$image, rectGrob
(x = unit(0, "native"), y = unit(0.1, "native"),
width = unit(1, "native"), height = unit(0.6, "native"),
just = c("left", "bottom"),
gp = gpar(col = getColour(j, length(ylevels)),
fill = "transparent", lwd = 3),
name = paste("samplePlot.databoundRect", j, sep = "."),
vp = canvas$graphPath("data", j)))
}
}
# Ensure labels are drawn on top of new shell rects
canvas$showLabels()
# Animation of slow points.
pxs <- numeric(n)
pys <- numeric(n)
for (i in seq(from = 1, by = 1, length.out = n.slow)) {
# Light up point to drop
if (drop.points & animate.points) {
pxs[i] <- if (resample.levels[i] == ylevels[1])
prop1.dpx[data.index[index[i]]]
else
prop2.dpx[data.index[index[i]]]
pys[i] <- if (resample.levels[i] == ylevels[1])
prop1.dpy[data.index[index[i]]]
else
prop2.dpy[data.index[index[i]]]
temp.point <- pointsGrob(x = pxs[1:i],
y = pys[1:i],
pch = 19, gp = gpar(col = pointCols[1:i]),
vp = canvas$graphPath("animation.field"),
name = "samplePlot.temp.point")
canvas$image <- addGrob(canvas$image, temp.point)
}
if (canvas$stopAnimation)
return()
canvas$pauseImage(5)
}
# Animation of fast points.
length.out <- max(0, n - n.slow)
for (i in seq(from = n.slow + 1, by = 1, length.out = length.out)) {
# Light up point to drop
if (drop.points & animate.points) {
pxs[i] <- if (resample.levels[i] == ylevels[1])
prop1.dpx[data.index[index[i]]]
else
prop2.dpx[data.index[index[i]]]
pys[i] <- if (resample.levels[i] == ylevels[1])
prop1.dpy[data.index[index[i]]]
else
prop2.dpy[data.index[index[i]]]
temp.point <- pointsGrob(pxs[1:i],
pys[1:i],
pch = 19, gp = gpar(col = pointCols[1:i]),
vp = canvas$graphPath("animation.field"),
name = "samplePlot.temp.point")
canvas$image <- addGrob(canvas$image, temp.point)
}
if (canvas$stopAnimation)
return()
canvas$drawImage()
}
# Plot the points that have been sampled.
if (drop.points & animate.points) {
for (j in 1:n.steps) {
temp.point2 <- pointsGrob(pxs - j*xs.step,
pys - j*ys.step,
pch = 19, gp = gpar(col = pointCols),
vp = canvas$graphPath("animation.field"),
name = "samplePlot.temp.point2")
canvas$image <- addGrob(canvas$image, temp.point2)
canvas$drawImage()
}
}
canvas$pauseImage(10)
}
# Removing animation grobs before plotting the sample
# Because we're plotting within the animation.field VP, there is no vpNumber()
# associated with our samplePlot.points, thus, we omit the numeric index
canvas$rmGrobs(c("samplePlot.temp.point", "samplePlot.temp.point2", "samplePlot.points.",
paste("samplePlot.yLab", 1:length(ylevels), sep="."),
paste("samplePlot.boundRect", 1:length(ylevels), sep="."),
paste("samplePlot.databoundRect", 1:length(ylevels), sep=".")))
# Now that animation grobs have been removed, draw the sample
canvas$plotSample(e, canvas$which.sample)
canvas$showLabels()
canvas$pauseImage(5)
}
plotSampvarTwoSampPropTheoDist <- function(canvas, e) {
## Replotting statistic distribution
x <- apply(canvas$stat.dist, 1, diff)
y <- canvas$stat.ypos
plotPoints(canvas, x, y, canvas$graphPath("stat"),
"statPlot", black = FALSE, alpha = 0.7)
stat.mean <- mean(x)
stat.sd <- sd(x)
pop1 <- canvas$x[canvas$levels == canvas$ylevels[1]]
pop2 <- canvas$x[canvas$levels == canvas$ylevels[2]]
n1 <- length(pop1)
n2 <- length(pop2)
N <- n1 + n2
p1 <- mean(pop1 == canvas$loi)
p2 <- mean(pop2 == canvas$loi)
mean <- p1 - p2
var1 <- p1*(1 - p1)/(canvas$n*n1/N)
var2 <- p2*(1 - p2)/(canvas$n*n2/N)
sd <- sqrt(var1 + var2)
## Getting statistic panel x-scale.
top.level <- downViewport(canvas$graphPath("stat"))
stat.scale <- current.viewport()$xscale
upViewport(top.level)
## Calculating normal density under the CLT.
xs <- seq(stat.scale[1], stat.scale[2], length.out = 300)
ys <- dnorm(xs, mean, sd)
## We need a sense of "density scale" for the y-axis. Fitting a
## kernel density estimator can provide this. We calculate the
## KDE, find the maximum point, map this to meet up with the top
## of the topmost point in the statistic panel, and scale the
## normal density curve accordingly. This ensures that the normal
## density curve has about the same area below it as the area
## taken up by the points; the normal density will have the same
## area as the KDE, which, in turn, will have a similar area to
## the points.
dens <- density(x, from = stat.scale[1], to = stat.scale[2])
ys <- ys/max(dens$y)
y.max <- unit(1, "npc") - unit(2, "lines") - unit(0.5, "char")
canvas$image <- addGrob(canvas$image, linesGrob
(x = unit(xs, "native"), y = (y.max*ys) + ys*unit(0.5, "char"),
gp = gpar(lwd = 2, col = "red"),
name = "statPlot.theodist.1",
vp = canvas$graphPath("stat")))
canvas$showLabels()
canvas$drawImage()
canvas$rmGrobs(c("samplePlot.points.1", "samplePlot.lines.1",
"samplePlot.datapoints.points.1", "samplePlot.databox.text.2",
"samplePlot.stat.1", "samplePlot.hist.1"))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.