В пакете twoway у меня есть метод twoway.default()
, который берет матрицу или фрейм данных и применяет методы Тьюки для анализа таблиц twoway.
Пример:
> data(taskRT)
> taskRT
topic1 topic2 topic3 topic4
Easy 2.43 3.12 3.68 4.04
Medium 3.41 3.91 4.07 5.10
Hard 4.21 4.65 5.87 5.69
> twoway(taskRT)
Mean decomposition (Dataset: "taskRT")
Residuals bordered by row effects, column effects, and overall
topic1 topic2 topic3 topic4 roweff
+ --------- --------- --------- --------- + ---------
Easy | -0.055833 0.090833 0.004167 -0.039167 : -0.864167
Medium | 0.119167 0.075833 -0.410833 0.215833 : -0.059167
Hard | -0.063333 -0.166667 0.406667 -0.176667 : 0.923333
+ ......... ......... ......... ......... + .........
coleff | -0.831667 -0.288333 0.358333 0.761667 : 4.181667
Я хочу расширить это с помощью метода формулы, который принимает фрейм данных и формулу вида response ~ row + column
, изменяет его с длинного на широкий и затем вызываетметод по умолчанию.Я знаю несколько способов сделать это непосредственно в консоли, но я не могу заставить какой-либо из них работать в функции метода формул.
Таким образом, для этих данных в длинном формате со значением ячейкис именем RT
и переменными строки и столбца как task
и topic
, я хотел бы получить те же результаты с вызовом
twoway(RT ~ task + topic, data=long)
На верхнем уровне, в консоли IЭто можно сделать разными способами, начиная с версии long
тех же данных.
library(reshape2)
long <- melt(as.matrix(taskRT))
colnames(long) <- c("task", "topic", "RT")
Преобразовать обратно в широкоформатный формат и вызвать twoway()
для этого:
# convert wide to long: dcast
(wide <- dcast(long, task ~ topic, value.var="RT"))
twoway(wide[,-1])
# tidyr::spread
library(tidyr)
(wide <- spread(long, key=topic, value=RT))
twoway(wide[,-1])
# base, unstack
wide <- unstack(long, form = RT ~ topic)
rownames(wide) <- unique(long$task)
twoway(wide)
Ниже приведен начальный эскиз метода twoway.formula
.У меня проблема в том, что я не могу понять, как использовать результаты синтаксического анализа объекта формулы и соответствующего фрейма данных в функции для создания вызова функции, который привел бы к подходящей широкой матрице или фрейму данных.для перехода к методу по умолчанию.До сих пор я пробовал различные формы dcast
внутри функции, показанные в виде комментариев, ни одна из которых не доставляет мне радости.
#' Initial sketch for a twoway formula method
#'
#' Doesn't do anything useful yet, but the idea is to be able to use a
#' formula for a twoway table in long form, e.g.,
#' twoway(response ~ row + col, data=mydata)
#'
#' @param formula A formula of the form \code{response ~ rowvar + colVAR}
#' @param data The name of the data set
#' @param subset An expression to subset the data (unused)
#' @param na.action What to do with NAs? (unused)
#' @param ... other arguments, passed down
#' @importFrom stats terms
#'
twoway.formula <- function(formula, data, subset, na.action, ...) {
if (missing(formula) || !inherits(formula, "formula"))
stop("'formula' missing or incorrect")
if (length(formula) != 3L)
stop("'formula' must have both left and right hand sides")
tt <- if (is.data.frame(data))
terms(formula, data = data)
else terms(formula)
if (any(attr(tt, "order") > 1))
stop("interactions are not allowed")
rvar <- attr(terms(formula[-2L]), "term.labels")
lvar <- attr(terms(formula[-3L]), "term.labels")
rhs.has.dot <- any(rvar == ".")
lhs.has.dot <- any(lvar == ".")
if (lhs.has.dot || rhs.has.dot)
stop("'formula' has '.' in left or right hand sides")
m <- match.call(expand.dots = FALSE)
edata <- eval(m$data, parent.frame())
lhs <- formula[[2]]
rhs <- formula[[3]]
# wide <- dcast(data=edata, formula=as.formula(rhs), value.var=lhs )
# wide <- dcast(data=edata, value.var=lhs)
# wide <- dcast(data=edata, rvar[1] ~ rvar[2], value.var=cvar)
# wide <- dcast(data=edata, list(.(rvar[1], .(rvar[2], .(cvar)))))
#browser()
stop("The formula method is not yet implemented.")
# call the default method on the wide data set
twoway(wide)
}
Кто-нибудь может помочь?