Re: [R] For loop by factor.

2011-06-20 Thread Sarah Goslee
Chris,

This doesn't cover all possible cases, but does work for your example.
It should be enough for you to tweak for your actual data.

diffsum <- function(x) {
# first identify the decreasing values
# and the difference between increasing values
xdif <- x[2:length(x)] - x[1:(length(x)-1)]
xdif <- c(xdif, 0) # last element has nothing to compare to
xdif[xdif <= 0] <- 0
# then figure out what to add
# NOTE: your example is not clear on what to do if
# there's a gap followed by more increasing number
xsum <- rev(cumsum(rev(xdif)))
xsum[xdif == 0] <- 0
x + xsum
}


diffsum(c(2,3,5,2,1))


test <- data.frame(A=c("a", "a", "a", "b", "b", "c", "c", "c", "c"),
B=c(3,2,1,3,2,2,3,1,1))
test2 <- lapply(split(test$B, test$A), diffsum)
test3 <- data.frame(A=rep(names(test2), times=lapply(test2, length)),
B=unlist(test2))

Sarah

On Mon, Jun 20, 2011 at 9:51 AM, Christopher Peters  wrote:
> Sarah,  thank you this is very close.
> The difference is that I'm not trying to sort to make it monotonic, but
> rather take the difference between any increasing value in the series and
> the previous value and add that difference back into each previous value.
> For example.
> column   var1    diff (0 where decreasing)    var2 (<--correct)
> a             2        1                                      5 <- (2 +
> (1+2))
> a             3        2                                      5 <- (3 + (2))
> a             5        0                                      5
> a             2        0                                      2
> a             1        0                                      1
> Chris
> __
>
>
> On Sun, Jun 19, 2011 at 6:02 PM, Sarah Goslee 
> wrote:
>>
>> This works, but I'm still hunting for a more elegant final step:
>> > test <- data.frame(A=c("a", "a", "a", "b", "b", "c", "c", "c", "c"),
>> > B=c(3,2,1,3,2,2,3,1,1))
>> > test2 <- lapply(split(test$B, test$A), sort, dec=TRUE)
>> > test3 <- data.frame(A=rep(names(test2), times=lapply(test2, length)),
>> > B=unlist(test2))
>>
>> It will also group data by factor, which was already done in your example.
>>
>> Sarah
>>
>> On Sun, Jun 19, 2011 at 4:20 PM, Christopher Peters 
>> wrote:
>> > I have a data.frame as follows:
>> >
>> > a  3
>> > a  2
>> > a  1
>> > b  3
>> > b  2
>> > c  2
>> > c  3
>> > c  1
>> > c  1
>> >
>> > Each factor (a, b, c) should be monotonically decreasing, notice that
>> > factor
>> > 'c' is not.
>> >
>> > I could use some help to figure out how to form a logical structure
>> > (mostly
>> > just syntax), that will check each 'next value' for each factor to see
>> > if it
>> > is less than the previous value.  If it is less than the previous value,
>> > do
>> > nothing, else subtract 'next value' from 'current value', add that
>> > amount to
>> > the starting value and each previous value to the 'next value' is
>> > greater
>> > than 'previous value'.
>> >
>> > So basically the data.frame would look like:
>> >
>> > a 3
>> > a 2
>> > a 1
>> > b 3
>> > b 2
>> > c 3
>> > c 3
>> > c 1
>> > c 1
>> >
>> --


-- 
Sarah Goslee
http://www.functionaldiversity.org

__
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.


Re: [R] For loop by factor.

2011-06-19 Thread Bill.Venables
If I understand you correctly, you are trying to find the cumulative maximum 
from the end within each level of the factor.  If this is what you are trying 
to do, then here is one way you might like to do it.  First, define the 
function:

> cumMax <- function(x) Reduce(max, x, right = TRUE, accumulate = TRUE)

Here is how you might use it:

> test
  A B
1 a 3
2 a 2
3 a 1
4 b 3
5 b 2
6 c 2
7 c 3
8 c 1
9 c 1
> (test <- within(test, B <- ave(B, A, FUN = cumMax))
  A B
1 a 3
2 a 2
3 a 1
4 b 3
5 b 2
6 c 3
7 c 3
8 c 1
9 c 1 

-Original Message-
From: r-help-boun...@r-project.org [mailto:r-help-boun...@r-project.org] On 
Behalf Of Christopher Peters
Sent: Monday, 20 June 2011 6:21 AM
To: r-help@r-project.org
Subject: [R] For loop by factor.

I have a data.frame as follows:

a  3
a  2
a  1
b  3
b  2
c  2
c  3
c  1
c  1

Each factor (a, b, c) should be monotonically decreasing, notice that factor
'c' is not.

I could use some help to figure out how to form a logical structure (mostly
just syntax), that will check each 'next value' for each factor to see if it
is less than the previous value.  If it is less than the previous value, do
nothing, else subtract 'next value' from 'current value', add that amount to
the starting value and each previous value to the 'next value' is greater
than 'previous value'.

So basically the data.frame would look like:

a 3
a 2
a 1
b 3
b 2
c 3
c 3
c 1
c 1

Thanks for your help!
__
Christopher P. Peters
Research Associate
Center for Energy Studies
http://www.enrg.lsu.edu/staff/peters
Energy, Coast & Environment Building
Louisiana State University
Baton Rouge, LA 70803
Telephone: 225-578-4400
Fax: 225-578-4541

[[alternative HTML version deleted]]

__
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.


Re: [R] For loop by factor.

2011-06-19 Thread jim holtman
try this:

>  test <- data.frame(A=c("a", "a", "a", "b", "b", "c", "c", "c", "c"), 
> B=c(3,2,1,3,2,2,3,1,1))
>  test
  A B
1 a 3
2 a 2
3 a 1
4 b 3
5 b 2
6 c 2
7 c 3
8 c 1
9 c 1
>  # determine which group is not decreasing
>  tapply(test$B, test$A, function(x) any(diff(x) > 0))
a b c
FALSE FALSE  TRUE
>


On Sun, Jun 19, 2011 at 4:20 PM, Christopher Peters  wrote:
> I have a data.frame as follows:
>
> a  3
> a  2
> a  1
> b  3
> b  2
> c  2
> c  3
> c  1
> c  1
>
> Each factor (a, b, c) should be monotonically decreasing, notice that factor
> 'c' is not.
>
> I could use some help to figure out how to form a logical structure (mostly
> just syntax), that will check each 'next value' for each factor to see if it
> is less than the previous value.  If it is less than the previous value, do
> nothing, else subtract 'next value' from 'current value', add that amount to
> the starting value and each previous value to the 'next value' is greater
> than 'previous value'.
>
> So basically the data.frame would look like:
>
> a 3
> a 2
> a 1
> b 3
> b 2
> c 3
> c 3
> c 1
> c 1
>
> Thanks for your help!
> __
> Christopher P. Peters
> Research Associate
> Center for Energy Studies
> http://www.enrg.lsu.edu/staff/peters
> Energy, Coast & Environment Building
> Louisiana State University
> Baton Rouge, LA 70803
> Telephone: 225-578-4400
> Fax: 225-578-4541
>
>        [[alternative HTML version deleted]]
>
> __
> 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.
>



-- 
Jim Holtman
Data Munger Guru

What is the problem that you are trying to solve?

__
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.


Re: [R] For loop by factor.

2011-06-19 Thread Sarah Goslee
This works, but I'm still hunting for a more elegant final step:
> test <- data.frame(A=c("a", "a", "a", "b", "b", "c", "c", "c", "c"), 
> B=c(3,2,1,3,2,2,3,1,1))
> test2 <- lapply(split(test$B, test$A), sort, dec=TRUE)
> test3 <- data.frame(A=rep(names(test2), times=lapply(test2, length)), 
> B=unlist(test2))

It will also group data by factor, which was already done in your example.

Sarah

On Sun, Jun 19, 2011 at 4:20 PM, Christopher Peters  wrote:
> I have a data.frame as follows:
>
> a  3
> a  2
> a  1
> b  3
> b  2
> c  2
> c  3
> c  1
> c  1
>
> Each factor (a, b, c) should be monotonically decreasing, notice that factor
> 'c' is not.
>
> I could use some help to figure out how to form a logical structure (mostly
> just syntax), that will check each 'next value' for each factor to see if it
> is less than the previous value.  If it is less than the previous value, do
> nothing, else subtract 'next value' from 'current value', add that amount to
> the starting value and each previous value to the 'next value' is greater
> than 'previous value'.
>
> So basically the data.frame would look like:
>
> a 3
> a 2
> a 1
> b 3
> b 2
> c 3
> c 3
> c 1
> c 1
>
-- 
Sarah Goslee
http://www.functionaldiversity.org

__
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.