Re: [R] a more elegant way to get percentages?

From: Monica Pisica <pisicandru_at_hotmail.com>
Date: Thu, 13 Mar 2008 14:05:05 +0000

Hi everybody,

I am amazed how quick i got my answer ;-) I have to recognize that Gabor's code really puts to shame my skills in doing any programming in R. Is there any book or documentation which really explains in details all these neat tricks from {stats} like ave (i even didn't know this function existed), apply and all its friends (sapply, tapply, etc) ? To be honest it took me quite a while to come up with the "fancy" subscripting to get my persantages ;-))

thank you so much, i really appreciate your help,

Monica

> Date: Thu, 13 Mar 2008 09:45:05 -0400
> From: ggrothendieck_at_gmail.com
> To: pisicandru_at_hotmail.com
> Subject: Re: [R] a more elegant way to get percentages?
> CC: r-help_at_r-project.org
>
> Assuming your x is as follows:
>
> x <- data.frame(locat = c("a", "b", "b", "c", "c", "c", "c", "d", "d", "d"),
> val = c(5, 5, 15, 5, 20, 5, 10, 5, 15, 10))
>
> Try this:
>
> x\$percent1 <- ave(x\$val, x\$locat, FUN = function(x) 100*x/sum(x))
>
> On Thu, Mar 13, 2008 at 9:36 AM, Monica Pisica wrote:
>>
>> Hi,
>>
>> I am trying to get percentages in a more elegant way. I have a data.frame with locations and values (counts) of species at that location. Each location is repeated for each species i have values for and i would like to get percentages of each species at that location. I am not sure if i am clear in my explanations so i will paste my code below:
>>
>> #####################
>>
>>> x
>> locat val
>> 1 a 5
>> 2 b 5
>> 3 b 15
>> 4 c 5
>> 5 c 20
>> 6 c 5
>> 7 c 10
>> 8 d 5
>> 9 d 15
>> 10 d 10
>>> loc1 <- x\$locat
>>> n <- length(loc1)
>>> locuniq1 <- unique(loc1)
>>> m <- length(locuniq1)
>>> counts <- seq(1:m)
>>>
>>> for (i in 1:m) {
>> + count <- 0
>> + for (j in 1:n) {
>> + if (loc1[j]==locuniq1[i]) count <- count+1
>> + counts[i] <- count
>> + }
>> + }
>>>
>>> percent1 <- rep(0,n)
>>> j <- 0
>>> for (i in 1:m) {
>> +
>> + b <- x[(j+1):(j+counts[i]),]
>> + total <- sum(b\$val)
>> + percent1[(j+1):(j+counts[i])] <- round(apply(as.matrix(b\$val), 1, function(x) {x*100/total}),2)
>> + j = j+counts[i]
>> + }
>>> x1 <- cbind(x, percent1) # this is the result i want
>>> x1
>> locat val percent1
>> 1 a 5 100.00
>> 2 b 5 25.00
>> 3 b 15 75.00
>> 4 c 5 12.50
>> 5 c 20 50.00
>> 6 c 5 12.50
>> 7 c 10 25.00
>> 8 d 5 16.67
>> 9 d 15 50.00
>> 10 d 10 33.33
>>>
>> ################
>>
>> I am wondering if there is any way to do it more efficiently, much more that the first loop which gives how many times each location is present in the data.frame is slow if you have a larger data.frame and not only 10 rows.
>>
>> Thanks for any input and sorry if the email is on the long side,
>>
>> Monica
>>
>>
>> _________________________________________________________________
>> [[elided Hotmail spam]]
>>
>> ______________________________________________
>> R-help_at_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.
>>

08

R-help_at_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. Received on Fri 14 Mar 2008 - 03:17:42 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Fri 14 Mar 2008 - 04:30:21 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-help. Please read the posting guide before posting to the list.