[19007] in s-news-athena

home help back first fref pref prev next nref lref last post

Re: [S] transpose and expand dataframe

daemon@ATHENA.MIT.EDU (John P McKinlay)
Mon Aug 23 07:29:34 1999

Message-Id: <3.0.1.32.19990823192614.0092c100@mail.bigpond.com>
Date: Mon, 23 Aug 1999 19:26:14
To: S-news@wubios.wustl.edu
From: John P McKinlay <john.mckinlay@bigpond.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"


Original question:

>I'm looking an efficient way of turning
>
>> adf<-data.frame(A=c(4,4,4,7,7,7,7,9,9),
>                  B=c(2,3,4,3,7,8,6,4,8),
>        count=c(23,12,34,7,56,32,10,16,3))
>> adf
>  A B count 
>1 4 2    23
>2 4 3    12
>3 4 4    34
>4 7 3     7
>5 7 7    56
>6 7 8    32
>7 7 6    10
>8 9 4    16
>9 9 8     3
>
>into a dataframe which looks like:
>
>   A   2   3   4   6   7   8 
>1  4  23  12  34   0   0   0
>2  7   0   7   0  10  56  32
>3  9   0   0  16   0   0   3 
>
Thanks to Fang Chen <fangc@stat.cmu.edu> and Christian Keller
<ckeller@aicos.com> for solutions. Minor modifications are mine; I don't
think they will have slowed things down appreciably. Timings are for a 916
x 40 output dataframe with 2550 non-zero entries (PII-350, 128mb, S+V4.5).

> dos.time(chen(zdf, row = 1, col = 2, count = 3))
[1] 0.4921875

> dos.time(keller(zdf,row = 1, col = 2, count = 3))
[1] 7.078125

> chen
function(adf, row = 1, col = 2, count = 3)
{
	tmp <- matrix(0, nrow = length(unique(adf[, row])), length(unique(adf[,
col])) + 1)
	tmp[, 1] <- unique(adf[, row])
	index <- rep(1:dim(tmp)[1], c(as.vector(table(adf[, row]))))
	tmp[cbind(index, match(adf[, col], sort(unique(adf[, col]))) + 1)] <-
adf[, count]
	ans <- as.data.frame(tmp)
	names(ans) <- c(names(adf)[row], sort(unique(adf[, col])))
	return(ans)
}
 
> keller
function(adf, row = 1, col = 2, count = 3)
{
	x <- tapply(adf[, count], list(adf[, row], adf[, col]), sum)
	x[is.na(x)] <- 0
	a <- sort(unique(adf[, row]))
	b <- sort(unique(adf[, col]))
	y <- data.frame(a, x)
	dimnames(y) <- list(seq(along = a), c(names(adf)[row], b))
	return(y)
}













-- 
John McKinlay

Phone: 08 92468440 -w 
       08 92465812 -h
email: john.mckinlay@bigpond.com   or  john.mckinlay@fish.wa.gov.au
-----------------------------------------------------------------------
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

home help back first fref pref prev next nref lref last post