[19007] in s-news-athena
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