Title: | Analysis of Two-Way Tables |
---|---|
Description: | Carries out analyses of two-way tables with one observation per cell, together with graphical displays for an additive fit and a diagnostic plot for removable 'non-additivity' via a power transformation of the response. It implements Tukey's Exploratory Data Analysis (1973) <ISBN: 978-0201076165> methods, including a 1-degree-of-freedom test for row*column 'non-additivity', linear in the row and column effects. |
Authors: | Michael Friendly [aut, cre] , Richard M. Heiberger [aut], John Fox [ctb] |
Maintainer: | Michael Friendly <[email protected]> |
License: | GPL-3 |
Version: | 0.6.4 |
Built: | 2024-11-01 02:32:07 UTC |
Source: | https://github.com/friendly/twoway |
Test for a 1-df interaction in two-way ANOVA table by the Tukey test.
## S3 method for class 'twoway' anova(object, ...)
## S3 method for class 'twoway' anova(object, ...)
object |
a |
... |
other arguments passed down, but not used here |
At present, this function simply gives the results of the ANOVAs for the additive model, the model including the 1 df
term for non-additivity, and an anova()
comparison of the two.
The analysis is based on row and column means.
Michael Friendly
data(sentRT) sent.2way <- twoway(sentRT) anova(sent.2way)
data(sentRT) sent.2way <- twoway(sentRT) anova(sent.2way)
This is the data set used by Tukey (1977) for the initial examples of twoway tables
a matrix of 7 rows (Month) and 3 columns (City) where the value is mean
monthly temperature in degrees F. The matrix has a responseName
attribute, "Temperature"
Tukey, J. W. (1977). Exploratory Data Analysis, Reading MA: Addison-Wesley. Exhibit 1 of chapter 10, p. 333
data(Arizona) (AR.2way <-twoway(Arizona, method="median")) ## plot(AR.2way)
data(Arizona) (AR.2way <-twoway(Arizona, method="median")) ## plot(AR.2way)
"twoway"
object to a data.frame
The rows and columns of the data table are strung out in standard R order in a vector, joined with row and column labels. Additional columns are added, representing the calculated values used in the two-way display.
## S3 method for class 'twoway' as.data.frame(x, ...)
## S3 method for class 'twoway' as.data.frame(x, ...)
x |
a |
... |
other arguments, presently ignored |
a data.frame with rows corresponding to the input data table, and the following columns
row labels
column labels
the data value in the cell
the fitted value,
the row effect
the column effect
the 1 df for non-additivity value
data(sentRT) sent.2way <- twoway(sentRT) as.data.frame(sent.2way)
data(sentRT) sent.2way <- twoway(sentRT) as.data.frame(sent.2way)
Create an initial twoway object representing the data before fitting
Method for matrix input
as.twoway(x, ...) ## S3 method for class 'matrix' as.twoway( x, ..., name = deparse(substitute(x)), responseName = name, varNames = names(dimnames(x)) )
as.twoway(x, ...) ## S3 method for class 'matrix' as.twoway( x, ..., name = deparse(substitute(x)), responseName = name, varNames = names(dimnames(x)) )
x |
a numeric matrix or numeric data frame with rownames |
... |
other arguments, unused here |
name |
Name of the data matrix |
responseName |
Name of the response variable |
varNames |
Names of the row and column variables |
An object of class c("twoway")
with all effects(roweff, coleff, overall) set to zero, and method="Initial"
Richard M. Heiberger
Richard M. Heiberger
data(taskRT) as.twoway(taskRT)
data(taskRT) as.twoway(taskRT)
The original source is Winer (1971), p. 268. This was used as an example in Friendly (1991).
Friendly, M. (1991). SAS System for Statistical Graphics Cary, NC: SAS Institute, Output 7.28
data(drugs) twoway(drugs)
data(drugs) twoway(drugs)
Number of U.S. housing starts by month for the years 1965 – 1973
a 9 x 12 matrix, where the entries are the number of housing starts, in thousands
Becker, Chambers & Wilks (1988), The New S Language, Brooks Cole. Friendly, M. (1991). SAS System for Statistical Graphics Cary, NC: SAS Institute, p.380
hstart.2way <- twoway(hstart, method="mean") plot(hstart.2way)
hstart.2way <- twoway(hstart, method="mean") plot(hstart.2way)
Counts of numbers of an insect, Leptinotarsa decemlineata (the Colorado potato beetle), each of which is the sum for two plots treated alike, for all combinations of 4 treatments and 6 areas of the field chosen to be relatively homogeneous.
a 4 x 6 matrix, where the rows are treatments and the columns are areas of a field.
These data are used in Tukey (1977) Exhibit 1 of Ch 11 and throughout the chapter as examples of median polish. Because the data are counts, either a sqrt or log transformation would be reasonable.
Tukey, J. W. (1977). Exploratory Data Analysis, Reading MA: Addison-Wesley. Exhibit 1 of chapter 111
insect.2way <- twoway(insectCounts, method="median") print(insect.2way, digits=2) plot(insect.2way) plot(insect.2way, which="diagnose") # try sqrt transformation insect.sqrt <- twoway(sqrt(insectCounts), method="median") print(insect.sqrt, digits=2) plot(insect.sqrt) plot(insect.sqrt, which="diagnose")
insect.2way <- twoway(insectCounts, method="median") print(insect.2way, digits=2) plot(insect.2way) plot(insect.2way, which="diagnose") # try sqrt transformation insect.sqrt <- twoway(sqrt(insectCounts), method="median") print(insect.sqrt, digits=2) plot(insect.sqrt) plot(insect.sqrt, which="diagnose")
The input power value is rounded to the nearest integer or fractional powers, .
The function is presently designed just for display purposes.
ladder_power(p)
ladder_power(p)
p |
A numeric power, for use as a transformation of a response, y, of the form |
In use, the transformation via the ladder of powers usually attaches a minus sign to
the transformation when the power < 0
, so that the order of the response values
are preserved under the transformation. Thus, a result of power = -0.5
is interpreted
to mean .
a named list of two elements: power
, the ladder-of-power value, and
name
, the name for the transformation
Tukey, J. W. (1977). Exploratory Data Analysis, Reading MA: Addison-Wesley.
ladder_power(0.6) ladder_power(-0.6)
ladder_power(0.6) ladder_power(-0.6)
Fit a two-way table using row and column means
meanfit(x, ..., na.rm = FALSE)
meanfit(x, ..., na.rm = FALSE)
x |
a numeric matrix or data frame |
... |
other arguments passed down |
na.rm |
logical. Should missing values be removed? |
An object of class c("twoway")
with the following named components:
the fitted constant term.
the fitted row effects.
the fitted column effects.
the residuals.
the name of the dataset.
the names for the rows
the names for the columns
"median"
Fit a two-way table using median polish
medianfit(x, trace.iter = FALSE, ...)
medianfit(x, trace.iter = FALSE, ...)
x |
a numeric matrix or data frame |
trace.iter |
whether to give verbose output of iteration history in median polish. |
... |
other arguments passed down |
An object of class c("twoway", "medpolish")
with the following named components:
the fitted constant term.
the fitted row effects.
the fitted column effects.
the residuals.
the name of the dataset.
the names for the rows
the names for the columns
"median"
Plots either the fitted values and residuals under additivity or a diagnostic plot for removable non-additivity by a power transformation
## S3 method for class 'twoway' plot(x, which = c("fit", "diagnose"), ..., na.rm = any(is.na(x$residuals))) ## S3 method for class 'twoway.fit' plot( x, main = paste0("Tukey two-way fit plot for ", x$name, " (method: ", x$method, ")"), xlab = expression(hat(mu) * " + Column Effect - Row Effect"), ylab = expression("Fit = " * hat(mu) * " + Column Effect + Row Effect"), rfactor = 1, rcolor = c("blue", "red"), lwd = 3, ylim = NULL, ..., na.rm = any(is.na(x$residuals)) ) ## S3 method for class 'twoway.diagnose' plot(x, annotate = TRUE, jitter = FALSE, smooth = FALSE, pch = 16, ...)
## S3 method for class 'twoway' plot(x, which = c("fit", "diagnose"), ..., na.rm = any(is.na(x$residuals))) ## S3 method for class 'twoway.fit' plot( x, main = paste0("Tukey two-way fit plot for ", x$name, " (method: ", x$method, ")"), xlab = expression(hat(mu) * " + Column Effect - Row Effect"), ylab = expression("Fit = " * hat(mu) * " + Column Effect + Row Effect"), rfactor = 1, rcolor = c("blue", "red"), lwd = 3, ylim = NULL, ..., na.rm = any(is.na(x$residuals)) ) ## S3 method for class 'twoway.diagnose' plot(x, annotate = TRUE, jitter = FALSE, smooth = FALSE, pch = 16, ...)
x |
a |
which |
one of |
... |
other arguments, passed to |
na.rm |
logical. Should missing values be removed? |
main |
plot title |
xlab |
X axis label |
ylab |
Y axis label |
rfactor |
draw lines for |
rcolor |
a vector of length 2 giving the color of lines for positive and negative residuals |
lwd |
line width for residual lines in the fit plot |
ylim |
Y axis limits |
annotate |
A logical value; if |
jitter |
A logical value; if |
smooth |
A logical value; if |
pch |
Plot character for point symbols in the diagnostic plot |
For the which="fit"
plot, the basic result comes from a plot of the row effects against the column fitted
values, which appears as a rectangular grid in these coordinates. Rotating this 45 degrees counterclockwise give a plot
in which the vertical coordinate is the fitted value for the two-way table, and the horizontal coordinate is the column fit
minus the row effect. The spacing of the grid lines for the rows and columns of the table show the relative magnitudes of the
row/column means or medians.
For the which="diagnose"
plot, the interaction residuals from an additive model, ,
are plotted against the estimated components
. If this plot shows a substantially non-zero
slope,
, this analysis suggests that a power transformation,
might reduce the
apparent interaction effects.
For both plots, if you want to directly compare the result of method="mean"
and method="median"
, it is
essential to set the same xlim
and ylim
axes in the call.
The diagnostic plot invisibly returns a list with elements c("slope", "power")
data(taskRT) tw <- twoway(taskRT) tw twmed <- twoway(taskRT, method="median") twmed plot(tw, xlim=c(2,7), ylim=c(2,7)) ## use the same xlim and ylim, for comparison plot(twmed, xlim=c(2,7), ylim=c(2,7)) plot(tw, which="diagnose", xlim=c(-.19, .19), ylim=c(-.5, .55)) plot(twmed, which="diagnose", xlim=c(-.19, .19), ylim=c(-.5, .55)) data(insectCounts) twi <- twoway(insectCounts) twimed <- twoway(insectCounts, method="median") plot(twi, xlim=c(-250, 700), ylim=c(-180, 900)) plot(twimed, xlim=c(-250, 700), ylim=c(-180, 900)) plot(twi, which="diagnose", xlim=c(-160, 170), ylim=c(-200, 400)) ## power = .1 plot(twimed, which="diagnose", xlim=c(-160, 170), ylim=c(-200, 400)) ## power = .3
data(taskRT) tw <- twoway(taskRT) tw twmed <- twoway(taskRT, method="median") twmed plot(tw, xlim=c(2,7), ylim=c(2,7)) ## use the same xlim and ylim, for comparison plot(twmed, xlim=c(2,7), ylim=c(2,7)) plot(tw, which="diagnose", xlim=c(-.19, .19), ylim=c(-.5, .55)) plot(twmed, which="diagnose", xlim=c(-.19, .19), ylim=c(-.5, .55)) data(insectCounts) twi <- twoway(insectCounts) twimed <- twoway(insectCounts, method="median") plot(twi, xlim=c(-250, 700), ylim=c(-180, 900)) plot(twimed, xlim=c(-250, 700), ylim=c(-180, 900)) plot(twi, which="diagnose", xlim=c(-160, 170), ylim=c(-200, 400)) ## power = .1 plot(twimed, which="diagnose", xlim=c(-160, 170), ylim=c(-200, 400)) ## power = .3
Print method for two-way tables
## S3 method for class 'twoway' print(x, digits = getOption("digits"), border = 2, zapsmall = TRUE, ...)
## S3 method for class 'twoway' print(x, digits = getOption("digits"), border = 2, zapsmall = TRUE, ...)
x |
a numeric matrix |
digits |
number of digits to print |
border |
if 0, the components |
zapsmall |
a logical value; if |
... |
other arguments passed down |
Michael Friendly, Richard Heiberger
data(taskRT) task.2way <- twoway(taskRT) print(task.2way) print(task.2way, border=0) data(sentRT) sent.2way <- twoway(sentRT) print(sent.2way) print(sent.2way, border=1)
data(taskRT) task.2way <- twoway(taskRT) print(task.2way) print(task.2way, border=0) data(sentRT) sent.2way <- twoway(sentRT) print(sent.2way) print(sent.2way, border=1)
Extract residuals from a twoway object
Extract fitted values from a twoway object
## S3 method for class 'twoway' residuals(object, nonadd = FALSE, ...) ## S3 method for class 'twoway' fitted(object, nonadd = FALSE, ...)
## S3 method for class 'twoway' residuals(object, nonadd = FALSE, ...) ## S3 method for class 'twoway' fitted(object, nonadd = FALSE, ...)
object |
A |
nonadd |
If |
... |
other arguments (unused) |
A numeric matrix of residuals corresponding to the data supplied to twoway
A numeric matrix of fitted values corresponding to the data supplied to twoway
data(taskRT) task.2way <- twoway(taskRT) residuals(task.2way) residuals(task.2way, nonadd=TRUE) sum(residuals(task.2way)^2) # SSE for additive model sum(residuals(task.2way, nonadd=TRUE)^2) # SSPE, non-additive model data(taskRT) task.2way <- twoway(taskRT) fitted(task.2way) fitted(task.2way, nonadd=TRUE)
data(taskRT) task.2way <- twoway(taskRT) residuals(task.2way) residuals(task.2way, nonadd=TRUE) sum(residuals(task.2way)^2) # SSE for additive model sum(residuals(task.2way, nonadd=TRUE)^2) # SSPE, non-additive model data(taskRT) task.2way <- twoway(taskRT) fitted(task.2way) fitted(task.2way, nonadd=TRUE)
The specific volume of natural rubber was measured at four values of temperature and six values of pressure. Is there any evidence that volume is not an additive relation with temperature and pressure?
Rubber
Rubber
a 4 x 6 matrix, where the cell values are the specific volume (in cubic centimeters per gram) of peroxide-cured rubber. The row and column variables are:
Temperature, in degrees Celcuis
Pressure, in kg / cm^2 above atmospheric pressure.
Wood, L. A. & Martin, G. M. (1964). "Compressibility of natural rubber at pressures below 500kg/cm^2", Journal of Research of the National Standards Bureau–A. Physics & Chemistry, **68A**, 259–268.
Emerson, J. D. & Wong, G. Y. (1985). "Resistant Nonadditve Fits for Two-Way Tables". In Hoaglin, D. C., Mosteller, F., & Tukey, J. W. (Eds.). Exploring data tables, trends and shapes. John Wiley Sons. Ch. 3, Table 3.1.
Rubber # scale the response to avoid small decimals rub <- 10000*Rubber rubfit <- twoway(rub, "median") plot(rubfit)
Rubber # scale the response to avoid small decimals rub <- 10000*Rubber rubfit <- twoway(rub, "median") plot(rubfit)
A demonstration 3 x 3 two-way table composed of reaction times for three subjects making T/F judgments on three types of sentences
Friendly, M. (1991). SAS System for Statistical Graphics Cary, NC: SAS Institute, Table 7.2
data(sentRT) twoway(sentRT)
data(sentRT) twoway(sentRT)
A demonstration 3 x 4 two-way table composed of reaction times for tasks varying in difficulty, with content on different topics.
A matrix of 3 rows and 4 columns, where the rows are the task difficulty levels and the columns are the the topics.
The cell values are average reaction times (in sec.). The matrix has a responseName
attribute, "RT"
data(taskRT) twoway(taskRT) twoway(taskRT, method="median")
data(taskRT) twoway(taskRT) twoway(taskRT, method="median")
Reshape a data.frame or matrix to a long data.frame
Reshape a data.frame or matrix to a wide data.frame
to_long( wide, rowname = NULL, colname = NULL, responseName = deparse(substitute(wide)), varNames = c("Row", "Col") ) to_wide(long, row = 1, col = 2, response = 3)
to_long( wide, rowname = NULL, colname = NULL, responseName = deparse(substitute(wide)), varNames = c("Row", "Col") ) to_wide(long, row = 1, col = 2, response = 3)
wide |
A data.frame or matrix in wide form |
rowname |
Name for the row variable |
colname |
Name for the column variable |
responseName |
Name for the response variable. If |
varNames |
Default names for the row and column variables if not passed as |
long |
A data.frame in long form |
row |
Column index or quoted name of the row variable |
col |
Column index or quoted name of the column variable |
response |
Column index or quoted name of the response variable |
A data.frame in long format
Michael Friendly and Richard M. Heiberger
Michael Friendly and Richard M. Heiberger
Arizona.long <- to_long(Arizona, varNames=c("Month", "City")) Arizona.long Arizona.long <- to_long(Arizona, varNames=c("Month", "City")) # back the other way to_wide(Arizona.long)
Arizona.long <- to_long(Arizona, varNames=c("Month", "City")) Arizona.long Arizona.long <- to_long(Arizona, varNames=c("Month", "City")) # back the other way to_wide(Arizona.long)
Fits an additive model using either row and column means or Tukey's median polish procedure
twoway(x, ...) ## Default S3 method: twoway( x, method = c("mean", "median"), ..., name = deparse(substitute(x)), responseName = attr(x, "response"), varNames = names(dimnames(x)) )
twoway(x, ...) ## Default S3 method: twoway( x, method = c("mean", "median"), ..., name = deparse(substitute(x)), responseName = attr(x, "response"), varNames = names(dimnames(x)) )
x |
a numeric matrix or data frame. |
... |
other arguments passed down |
method |
one of |
name |
name for the input dataset |
responseName |
name for the response variable |
varNames |
names for the Row and Column variables |
The rownames(x)
are used as the levels of the row factor and the colnames(x
) are
the levels of the column factor.
For a numeric matrix, the function uses the names(dimnames(x))
as the names of these
variables, and, if present, a responseName
attribute as the name for the response variable.
An object of class c("twoway")
with the following named components:
the fitted constant term.
the fitted row effects.
the fitted column effects.
the residuals.
the name of the dataset.
the names for the rows
the names for the columns
the fitting method
the names of the row and column variables
the name of the response variable
the comparison values, for the diagnostic plot
the slope value, for the diagnostic plot
the suggested power transformation, 1-slope
An object of class "twoway"
, but supplemented by additional components used for labeling
Michael Friendly
Tukey, J. W. (1977). Exploratory Data Analysis, Reading MA: Addison-Wesley.
Friendly, M. (1991). SAS System for Statistical Graphics Cary, NC: SAS Institute
codetwoway.formula, codemedpolish
data(taskRT) twoway(taskRT)
data(taskRT) twoway(taskRT)
The formula method reshapes the data set from long to wide format and calls the default method.
## S3 method for class 'formula' twoway(formula, data, subset, na.action, ...)
## S3 method for class 'formula' twoway(formula, data, subset, na.action, ...)
formula |
A formula of the form |
data |
The name of the data set, containing a row vector, column factor and a numeric response |
subset |
An expression to subset the data (unused) |
na.action |
What to do with NAs? (unused) |
... |
other arguments, passed down |
Michael Friendly and Richard Heiberger
the conversion of long to wide in a formula method was suggested on https://stackoverflow.com/questions/50469320/how-to-write-a-formula-method-that-converts-long-to-wide
longRT <- to_long(taskRT) twoway(RT ~ Task + Topic, data=longRT)
longRT <- to_long(taskRT) twoway(RT ~ Task + Topic, data=longRT)
Vermont country populations from the US Census, 1900-1990
VermontPop
VermontPop
An object of class data.frame
with 14 rows and 10 columns.
Morgenthaler, Stephan, and John W. Tukey. “Multipolishing and Two-Way Plots.” Metrika 53.3 (2001): 245–267.
options(digits=4) VP <- twoway(VermontPop, method="median", responseName = "log Population") VP plot(VP)
options(digits=4) VP <- twoway(VermontPop, method="median", responseName = "log Population") VP plot(VP)