There is probably a more elegant way to do this, but this worked for me:
# a function to identify the first occurrence of a run of values
first <- function(x) {
l <- length(x)
c(1, 1-(x[-1]==x[-l]))
}
# identify the first occurrence of a run of Rev values
df$frst <- first(df$Rev)
# assign each run a unique value
df$run <- cumsum(df$frst)
# number the elements of each run
df$no.elements <- unlist(lapply(table(df$run), seq))
# identify the first occurrence of FF=0 within each run
first.FF.0 <- tapply(df$FF, df$run, function(x) match(0, x))
# subset the original data frame, selecting those rows that correspond to
the first occurrence of FF=0 in each run
result <- data.frame(t(sapply(1:max(df$run), function(g) df[df$run==g,
][first.FF.0[g], ])))
# identify the rows that have bin=0
result$valid <- result$bin==0
# since you only want the "transitions", ignore the first row of results
# the last two columns are the results you want,
# the number of elements that occurred in the valid and non-valid cases
result[-1, ]
df[1:15, ]
Rev FF bin frst run no.elements
1 1 1 NA 1 1 1
2 1 1 1 0 1 2
3 1 0 1 0 1 3
4 1 1 1 0 1 4
5 1 1 1 0 1 5
6 1 1 1 0 1 6
7 1 1 0 0 1 7
8 1 1 0 0 1 8
9 1 0 1 0 1 9
10 1 1 1 0 1 10
11 2 0 1 1 2 1
12 2 1 1 0 2 2
13 2 1 1 0 2 3
14 2 1 1 0 2 4
15 2 1 0 0 2 5
result[-1, ]
Rev FF bin frst run no.elements valid
2 2 0 1 1 2 1 FALSE
3 3 0 1 0 3 2 FALSE
4 1 0 0 1 4 1 TRUE
5 2 0 0 0 5 3 TRUE
6 3 0 1 0 6 5 FALSE
7 1 0 1 0 7 4 FALSE
8 2 0 1 0 8 2 FALSE
9 3 0 0 0 9 2 TRUE
Jean
Edward Patzelt <[email protected]> wrote on 08/22/2011 04:09:55 PM:
> that is exactly correct, assuming we did not start at the beginning,
> but started at the first transition (this is the correct way to
> think about it)
> On Mon, Aug 22, 2011 at 4:08 PM, Jean V Adams <[email protected]> wrote:
>
> So, using the full data set, what should the result look like?
>
> c(NA, NA, NA, 3, NA, NA, NA, 2) ?
>
> Jean
>
> Edward Patzelt <[email protected]> wrote on 08/22/2011 03:58:38 PM:
>
> > [image removed]
> >
> > Re: [R] Counting Elements Conditionally
> >
> > Edward Patzelt
> >
> > to:
> >
> > Jean V Adams
> >
> > 08/22/2011 03:58 PM
> >
> > Cc:
> >
> > r-help
> >
> > Awesome, this is close, couple changes. Below is full data set for
> > 1 person. I want the code to look at the first time it sees a 0 in
> > FF after the transition in Rev. I then want it to test whether bin
> > is also a 0. If and only if this is the first 0 in FF after the
> > transition, and bin = 0, then count the number of elements between
> > the transition in Rev and the 0 in FF.
> >
> >
> > structure(list(Rev = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
> > 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L,
> > 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 1L, 1L,
> > 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
> > 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
> > 3L, 3L, 3L, 3L, 3L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
> > 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
> > 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
> > 3L, 3L, 3L), FF = c(1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 0L,
> > 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L,
> > 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 1L, 1L,
> > 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L,
> > 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 1L,
> > 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 1L, 1L, 1L,
> > 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 1L,
> > 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 0L, 1L, 1L,
> > 1L, 1L), bin = c(NA, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0,
> > 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
> > 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1,
> > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,
> > 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> > 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1,
> > 1, 1, 1, 1, 1)), .Names = c("Rev", "FF", "bin"), row.names = c(NA,
> > -125L), class = "data.frame")
> >
> > On Mon, Aug 22, 2011 at 3:57 PM, Jean V Adams <[email protected]>
wrote:
> >
> > > Re: [R] Counting Elements Conditionally
> > > Jean V Adams
> > > to:
> > > Edward Patzelt
> > > 08/22/2011 03:53 PM
> > >
> > > > [R] Counting Elements Conditionally
> > > > Edward Patzelt
> > > > to:
> > > > r-help
> > > > 08/22/2011 02:33 PM
> > > >
> > > > R -
> > > >
> > > > I have 3 variables with data below. Variable "Rev" is a vector
that
> > > changes
> > > > from 1 to 2, 2 to 3, etc.... Variable "FF" is a binary variable
with
> > > 1's
> > > > and 0's. Variable "bin" is a different binary variable with 1's
and
> > > 0's.
> > > >
> > > > I want to calculate the number of elements:
> > > >
> > > > 1. Starting with the first element where Rev switches (i.e. 1 to
2)
> > > >
> > > > 2. The number of elements between the transition and the first 0
in the
> > > > "FF" vector; *when "bin" is also a 0.*
> > > > *
> > > > *
> > > > 3. I want to do this for each transition in Rev, but ignore all
> > > elements
> > > > after calculating #2 until another transition has occurred.
> > > >
> > > >
> > > > structure(list(Rev = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
> > > > 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L,
> > > > 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), FF =
c(0L,
> > > > 1L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L, 1L,
> > > > 1L, 1L, 0L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 1L, 1L,
> > > > 1L, 1L, 1L, 0L, 1L, 1L, 1L), bin = c(NA, 1, 1, 1, 1, 1, 1, 1,
> > > > 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
> > > > 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1)), .Names = c("Rev", "FF", "bin"
> > > > ), row.names = c(NA, -40L), class = "data.frame")
> > > >
> > > >
> > > > --
> > > > Edward H. Patzelt
> > > > Research Assistant ? TRiCAM Lab
> > > > University of Minnesota ? Psychology/Psychiatry
> > > > VA Medical Center
> > > > Office: S355 Elliot Hall - Twin Cities Campus
> > > > Phone: 612-626-0072 Email: [email protected]
> > > >
> > >
> > > Try this (I'm assuming your data.frame is called "df":
> > >
> > >
> > > uR <- unique(df$Rev)
> > > uR0 <- uR*10L
> > >
> > > first.Rev <- match(uR, df$Rev)
> > > first.Rev0 <- match(uR0, df$Rev * 10L + df$FF)
> > >
> > > no.elements <- first.Rev0 - first.Rev + 1
> > >
> > >
> > > This starts with Rev=1 (rather than Rev=2), but you can get rid
> of that by
> > > dropping the first result ...
> > >
> > >
> > > no.elements[-1]
> > >
> > >
> > > Jean
> > >
>
> > Ooops. Too hasty in my reply. I missed the part about bin also
> > being zero. Try this instead.
> >
> >
> > uR <- unique(df$Rev)
> > uR00 <- uR*100L
> >
> > first.Rev <- match(uR, df$Rev)
> > first.Rev00 <- match(uR00, df$Rev * 100L + df$FF * 10L + df$bin)
> >
> > no.elements <- first.Rev00 - first.Rev + 1
> >
> >
> > Jean
> >
>
> >
> > --
> > Edward H. Patzelt
> > Research Assistant ? TRiCAM Lab
> > University of Minnesota ? Psychology/Psychiatry
> > VA Medical Center
> > Office: S355 Elliot Hall - Twin Cities Campus
> > Phone: 612-626-0072 Email: [email protected]
> >
> > Please consider the environment before printing this email
> > www.psych.umn.edu/research/tricam
>
>
> --
> Edward H. Patzelt
> Research Assistant ? TRiCAM Lab
> University of Minnesota ? Psychology/Psychiatry
> VA Medical Center
> Office: S355 Elliot Hall - Twin Cities Campus
> Phone: 612-626-0072 Email: [email protected]
>
> Please consider the environment before printing this email
> www.psych.umn.edu/research/tricam
[[alternative HTML version deleted]]
______________________________________________
[email protected] 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.