mdvaan
2012-Jul-16 16:17 UTC
[R] Finding and manipulation clusters of numbers in a sequence of numbers
Hi, I have the following sequence: in <- c(0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 2, 0, 0, 2)>From this sequence I would like to get to the following sequence:out <- c(0, 0, 0, 3, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 0, 2, 0, 2, 0, 0, 2) Basically, what I would like to do for each number greater than 0, is to add all adjacent numbers and the adjacent numbers of those numbers, etc. until one of those numbers is equal to 0. I could manually repeat the loops below until "sequence" stops changing but there must be a smarter way. Any suggestions? Thanks! sequence <- c(0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 2, 0, 0, 2) for (h in 2:(length(sequence) - 1)) { sequence[h] <- ifelse(sequence[h] > 0, sequence[h-1] + sequence[h], 0) } for (h in 1:(length(sequence) - 1)) { sequence[h] <- ifelse(sequence[h] > 0 & sequence[h+1] > sequence[h], sequence[h+1], sequence[h]) } -- View this message in context: http://r.789695.n4.nabble.com/Finding-and-manipulation-clusters-of-numbers-in-a-sequence-of-numbers-tp4636661.html Sent from the R help mailing list archive at Nabble.com.
Gabor Grothendieck
2012-Jul-16 19:47 UTC
[R] Finding and manipulation clusters of numbers in a sequence of numbers
On Mon, Jul 16, 2012 at 12:17 PM, mdvaan <mathijsdevaan at gmail.com> wrote:> Hi, > > I have the following sequence: > in <- c(0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 2, 0, 0, 2) > > >From this sequence I would like to get to the following sequence: > out <- c(0, 0, 0, 3, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, > 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 0, 2, 0, 2, 0, 0, 2) > > Basically, what I would like to do for each number greater than 0, is to > add all adjacent numbers and the adjacent numbers of those numbers, etc. > until one of those numbers is equal to 0. >Here cumsum(input == 0) * (input !=0) replaces each run of non-zeros with a distinct group number and then ave is used to sum over the distinct groups:> ave(input, cumsum(input == 0) * (input != 0), FUN = sum)[1] 0 0 0 3 3 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 11 11 11 11 11 11 11 11 11 11 11 0 2 0 2 0 0 2 -- Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com
William Dunlap
2012-Jul-16 19:51 UTC
[R] Finding and manipulation clusters of numbers in a sequence of numbers
Is f() what you want? It wastes some time doing things that don't have to be done but is pretty easy to understand. > input <- c(0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 2, 0, 0, 2) > out <- c(0, 0, 0, 3, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 0, 2, 0, 2, 0, 0, 2) > f <- function (x) { firstInRun <- function(x) c(TRUE, x[-1] != x[-length(x)]) group <- cumsum(firstInRun(x == 0)) ave(x, group, FUN = sum) } > all.equal(out, f(input)) [1] TRUE Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com> -----Original Message----- > From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On > Behalf Of mdvaan > Sent: Monday, July 16, 2012 9:18 AM > To: r-help at r-project.org > Subject: [R] Finding and manipulation clusters of numbers in a sequence of numbers > > Hi, > > I have the following sequence: > in <- c(0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 2, 0, 0, 2) > > >From this sequence I would like to get to the following sequence: > out <- c(0, 0, 0, 3, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, > 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 0, 2, 0, 2, 0, 0, 2) > > Basically, what I would like to do for each number greater than 0, is to > add all adjacent numbers and the adjacent numbers of those numbers, etc. > until one of those numbers is equal to 0. > > I could manually repeat the loops below until "sequence" stops changing but > there must be a smarter way. Any suggestions? Thanks! > > sequence <- c(0, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, > 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 2, 0, 0, 2) > for (h in 2:(length(sequence) - 1)) > { > sequence[h] <- ifelse(sequence[h] > 0, sequence[h-1] + sequence[h], 0) > } > > for (h in 1:(length(sequence) - 1)) > { > sequence[h] <- ifelse(sequence[h] > 0 & sequence[h+1] > sequence[h], > sequence[h+1], sequence[h]) > } > > -- > View this message in context: http://r.789695.n4.nabble.com/Finding-and- > manipulation-clusters-of-numbers-in-a-sequence-of-numbers-tp4636661.html > Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ > 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.