[R] recoding table dimensions interactively
Michael Friendly
friendly at yorku.ca
Thu Jan 9 20:29:34 CET 2014
Thanks for this, Bill
Your solution does just what I want. In fact, it qualifies as the
missing as.matrix() method
for n-way tables arranged with ftable(), or vcd::structable(), which
does provide an
as.matrix() method, but omits the names and dimnames.
Here it is, renamed and
using "_" as the default separator for names joined together, which is
probably a better
default. I'll propose this as an addition to the stats package on R-devel.
# modified from Willaim Dunlop, <wdunlap at tibco.com>, R-Help, 01-09-2014
as.matrix.ftable <- function(x, sep="_") {
makeDimNames <- function(vars) {
structure(
list(do.call(paste, c(rev(expand.grid(rev(vars))),
list(sep=sep)))),
names = paste(collapse=sep, names(vars))
)
}
structure(
unclass(x),
dimnames=c(makeDimNames(attr(x, "row.vars")),
makeDimNames(attr(x, "col.vars"))),
row.vars=NULL,
col.vars=NULL)
}
Tests:
> UCB <- UCBAdmissions
> as.matrix(ftable(Dept ~ Admit + Gender, data=UCB))
Dept
Admit_Gender A B C D E F
Admitted_Male 512 353 120 138 53 22
Admitted_Female 89 17 202 131 94 24
Rejected_Male 313 207 205 279 138 351
Rejected_Female 19 8 391 244 299 317
> as.matrix(ftable(Dept ~ ., data=UCB))
Dept
Admit_Gender A B C D E F
Admitted_Male 512 353 120 138 53 22
Admitted_Female 89 17 202 131 94 24
Rejected_Male 313 207 205 279 138 351
Rejected_Female 19 8 391 244 299 317
> as.matrix(ftable(Admit + Gender ~ Dept, data=UCB))
Admit_Gender
Dept Admitted_Male Admitted_Female Rejected_Male Rejected_Female
A 512 89 313 19
B 353 17 207 8
C 120 202 205 391
D 138 131 279 244
E 53 94 138 299
F 22 24 351 317
> as.matrix(ftable(Admit ~ ., data=UCB))
Admit
Gender_Dept Admitted Rejected
Male_A 512 313
Male_B 353 207
Male_C 120 205
Male_D 138 279
Male_E 53 138
Male_F 22 351
Female_A 89 19
Female_B 17 8
Female_C 202 391
Female_D 131 244
Female_E 94 299
Female_F 24 317
>
> str(as.matrix(ftable(Admit + Gender ~ Dept, data=UCB)))
num [1:6, 1:4] 512 353 120 138 53 22 89 17 202 131 ...
- attr(*, "dimnames")=List of 2
..$ Dept : chr [1:6] "A" "B" "C" "D" ...
..$ Admit_Gender: chr [1:4] "Admitted_Male" "Admitted_Female"
"Rejected_Male" "Rejected_Female"
>
On 1/9/2014 11:32 AM, William Dunlap wrote:
> Do you just want to change how the rows and columns of ftable's output are
> labelled? If so, the following may do what you want: it produces a matrix
> with dimnames based on the row.vars and col.vars attributes of ftable's
> output.
>
> f <- function(ftable) {
> makeDimNamesEl <- function(x) {
> structure(
> list(do.call(paste, c(rev(expand.grid(rev(x))), list(sep=":")))),
> names = paste(collapse=":", names(x))
> )
> }
> structure(
> unclass(ftable),
> dimnames=c(makeDimNamesEl(attr(ftable, "row.vars")),
> makeDimNamesEl(attr(ftable, "col.vars"))),
> row.vars=NULL,
> col.vars=NULL)
> }
>
> E.g.,
>> f(ftable(UCBAdmissions))
> Dept
> Admit:Gender A B C D E F
> Admitted:Male 512 353 120 138 53 22
> Admitted:Female 89 17 202 131 94 24
> Rejected:Male 313 207 205 279 138 351
> Rejected:Female 19 8 391 244 299 317
>> f(ftable(data=mtcars, am + gear ~ vs + carb))
> am:gear
> vs:carb 0:3 0:4 0:5 1:3 1:4 1:5
> 0:1 0 0 0 0 0 0
> 0:2 4 0 0 0 0 1
> 0:3 3 0 0 0 0 0
> 0:4 5 0 0 0 2 1
> 0:6 0 0 0 0 0 1
> 0:8 0 0 0 0 0 1
> 1:1 3 0 0 0 4 0
> 1:2 0 2 0 0 2 1
> 1:3 0 0 0 0 0 0
> 1:4 0 2 0 0 0 0
> 1:6 0 0 0 0 0 0
> 1:8 0 0 0 0 0 0
>
> Bill Dunlap
> Spotfire, TIBCO Software
> wdunlap tibco.com
>
>
>> -----Original Message-----
>> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf
>> Of Michael Friendly
>> Sent: Thursday, January 09, 2014 7:14 AM
>> To: R-help
>> Subject: [R] recoding table dimensions interactively
>>
>> Given a 3+ way table, I'd like a simple, elegant way to flatten the
>> table to a two-way
>> table, with some variables joined interactively to form the rows and
>> others forming
>> the columns. For example, starting with
>>
>> > str(UCBAdmissions)
>> table [1:2, 1:2, 1:6] 512 313 89 19 353 207 17 8 120 205 ...
>> - attr(*, "dimnames")=List of 3
>> ..$ Admit : chr [1:2] "Admitted" "Rejected"
>> ..$ Gender: chr [1:2] "Male" "Female"
>> ..$ Dept : chr [1:6] "A" "B" "C" "D" ...
>> >
>>
>> What I want is something similar to the result of ftable:
>>
>> > ftable(UCBAdmissions)
>> Dept A B C D E F
>> Admit Gender
>> Admitted Male 512 353 120 138 53 22
>> Female 89 17 202 131 94 24
>> Rejected Male 313 207 205 279 138 351
>> Female 19 8 391 244 299 317
>>
>> One way to do this is to convert to a data.frame, paste the factors
>> together and then convert back to a table:
>>
>> UCB.df <- as.data.frame(UCBAdmissions)
>> UCB.df$`Admit:Gender` <- paste(UCB.df$Admit, UCB.df$Gender, sep=':')
>> UCB.tab2 <- xtabs(Freq ~ `Admit:Gender` + Dept, data=UCB.df)
>> UCB.tab2
>>
>> > UCB.tab2
>> Dept
>> Admit:Gender A B C D E F
>> Admitted:Female 89 17 202 131 94 24
>> Admitted:Male 512 353 120 138 53 22
>> Rejected:Female 19 8 391 244 299 317
>> Rejected:Male 313 207 205 279 138 351
>> >
>>
>> But maybe there is a simpler, more elegant and general way to do this.
>>
>> --
>> Michael Friendly Email: friendly AT yorku DOT ca
>> Professor, Psychology Dept. & Chair, Quantitative Methods
>> York University Voice: 416 736-2100 x66249 Fax: 416 736-5814
>> 4700 Keele Street Web:http://www.datavis.ca
>> Toronto, ONT M3J 1P3 CANADA
>>
>> ______________________________________________
>> R-help at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
--
Michael Friendly Email: friendly AT yorku DOT ca
Professor, Psychology Dept. & Chair, Quantitative Methods
York University Voice: 416 736-2100 x66249 Fax: 416 736-5814
4700 Keele Street Web: http://www.datavis.ca
Toronto, ONT M3J 1P3 CANADA
More information about the R-help
mailing list