[S] "list" format for table()

Don MacQueen (macqueen1@llnl.gov)
Thu, 21 May 1998 16:10:35 -0800


Back when I was a heavy SAS user, I almost always used the /list option in
proc freq. Here, in case anyone finds it useful, is a function named
table.list() that takes the result of the table() function and rearranges
it like a frequency tablulation using the /list option in SAS.

This was an interesting programming problem for me, and I'm wondering if
there's a better way. A one-liner? A built-in function that I haven't
noticed? A way to do it without looping? It would be nice to pick up the
names of the objects originally passed to table()--a problem I'd like to go
back and solve myself someday.

> args(table.list)
function(tbl, colnames = c(paste("arg", (1:ndim), sep = "."), "value"),
zero.rm = T, reorder = T)

-Don

Examples first:

> a1 <- rep( c('a','b','c'),4)
> a2 <- rep(c('x','y'),6)
> a3 <- c(rep('z3',8),rep('m3',3),'z3')

> tbl <- table(a1,a2,a3)
> tbl

, , m3
x y
a 0 1
b 1 0
c 1 0

, , z3
x y
a 2 1
b 1 2
c 1 2

> table.list(tbl,zero.rm=F,reorder=F)
arg.1 arg.2 arg.3 value
1 a x m3 0
2 b x m3 1
3 c x m3 1
4 a y m3 1
5 b y m3 0
6 c y m3 0
7 a x z3 2
8 b x z3 1
9 c x z3 1
10 a y z3 1
11 b y z3 2
12 c y z3 2

> table.list(tbl,colnames=c('a1','a2','a3','n'))
a1 a2 a3 n
4 a x z3 2
3 a y m3 1
7 a y z3 1
1 b x m3 1
5 b x z3 1
8 b y z3 2
2 c x m3 1
6 c x z3 1
9 c y z3 2

table.list <- function(tbl,colnames=c( paste('arg',(1:ndim),sep='.'), 'value'),
zero.rm=T,reorder=T) {

dims <- dim(tbl)
ndim <- length(dim(tbl))
vals <- as.vector(tbl)
nvals <- length(vals)
dimns <- dimnames(tbl)

nm <- rep(dimns[[1]],length=nvals)
for (i in 2:ndim) {
nm.i <- rep(dimns[[i]],rep(prod(dims[1:(i-1)]),dims[i]))
nm.i <- rep(nm.i,length=nvals)
nm <- cbind(nm,nm.i)
}

if (zero.rm) drop <- vals==0
else drop <- rep(F,length(vals))

out <- data.frame(nm[!drop,],vals[!drop])
names(out) <- colnames

if (reorder) {
ord <- order.list( as.list(out[, 1:ndim]) )
out <- out[ord,]
}

out
}

-----------------------------------------------------------------------
This message was distributed by s-news@wubios.wustl.edu. To unsubscribe
send e-mail to s-news-request@wubios.wustl.edu with the BODY of the
message: unsubscribe s-news