Here is a possible solution using sweep instead of ave:
df <- data.frame(site = c("a", "a", "a", "b", "b", "b"),
gr = c("total", "x1", "x2", "x1", "total","x2"),
value1 = c(212, 56, 87, 33, 456, 213),
value2 = c(1546, 560, 543, 234, 654, 312) )
sdf <- split(df, df$site)
out <- lapply( sdf, function(mat){
small.mat <- mat[ , -c(1,2)]
totals <- mat[ which( mat[ , "gr"] == "total" ), -c(1,2) ]
totals <- as.numeric(totals)
percent=sweep( small.mat, MARGIN=2, STATS=totals, FUN="/" )
colnames(percent) <- paste("percent_", colnames(percent), sep="")
return( cbind(mat, percent) )
} )
do.call("rbind", out)
site gr value1 value2 percent_value1 percent_value2
a.1 a total 212 1546 1.00000000 1.0000000
a.2 a x1 56 560 0.26415094 0.3622251
a.3 a x2 87 543 0.41037736 0.3512290
b.4 b x1 33 234 0.07236842 0.3577982
b.5 b total 456 654 1.00000000 1.0000000
b.6 b x2 213 312 0.46710526 0.4770642
Also I think it might be more efficient to replace your "gr" variable
with a binary 0,1 where 1 indicates the total. That way you don't have
to generate x1, x2, x3, ....
Regards, Adai
On 30/11/2010 14:42, Patrick Hausmann wrote:
Hi all,
I would like to calculate the percent of the total per group for this
data.frame:
df<- data.frame(site = c("a", "a", "a", "b", "b", "b"),
gr = c("total", "x1", "x2", "x1", "total","x2"),
value1 = c(212, 56, 87, 33, 456, 213))
df
calcPercent<- function(df) {
df<- transform(df, pct_val1 = ave(df[, -c(1:2)], df$gr,
FUN = function(x)
x/df[df$gr == "total", "value1"]) )
}
# This works as intended...
w<- lapply(split(df, df$site), calcPercent)
w<- do.call(rbind, w)
w
# ... but when I add a new column
df$value2<- c(1546, 560, 543, 234, 654, 312)
# the result is not what I want...
w<- lapply(split(df, df$site), calcPercent)
w<- do.call(rbind, w)
w
Clearly I have to change the function, (particularly "value1") - but
how... I've also played around with "apply" but without any success.
Thanks for any help!
Patrick
______________________________________________
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.
______________________________________________
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.