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, <wdun...@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-boun...@r-project.org [mailto:r-help-boun...@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@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

______________________________________________
R-help@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.

Reply via email to