Maybe this : > foo <- function( x ){ + idx <- 1 + cumsum( is.na( x ) ) + not.na <- ! is.na( x ) + split( x[not.na], idx[not.na] ) + } > foo( x ) $`1` [1] 2 1 2
$`2` [1] 1 1 2 $`3` [1] 4 5 2 3 Romain Le 29/04/10 09:42, Tal Galili a écrit :
Hi all, I would like to have a function like this: split.vec.by.NA<- function(x) That takes a vector like this: x<- c(2,1,2,NA,1,1,2,NA,4,5,2,3) And returns a list of length of 3, each element of the list is the relevant segmented vector, like this: $`1` [1] 2 1 2 $`2` [1] 1 1 2 $`3` [1] 4 5 2 3 I found how to do it with a loop, but wondered if there is some smarter (vectorized) way of doing it. Here is the code I used: x<- c(2,1,2,NA,1,1,2,NA,4,5,2,3) split.vec.by.NA<- function(x) { # assumes NA are seperating groups of numbers #TODO: add code to check for it number.of.groups<- sum(is.na(x)) + 1 groups.end.point.locations<- c(which(is.na(x)), length(x)+1) # This will be all the places with NA's + a nubmer after the ending of the vector group.start<- 1 group.end<- NA new.groups.split.id<- x # we will replace all the places of the group with group ID, excapt for the NA, which will later be replaced by 0 for(i in seq_len(number.of.groups)) { group.end<- groups.end.point.locations[i]-1 new.groups.split.id[group.start:group.end]<- i group.start<- groups.end.point.locations[i]+1 # make the new group start higher for the next loop (at the final loop it won't matter } new.groups.split.id[is.na(x)]<- 0 return(split(x, new.groups.split.id)[-1]) } split.vec.by.NA(x) Thanks, Tal
-- Romain Francois Professional R Enthusiast +33(0) 6 28 91 30 30 http://romainfrancois.blog.free.fr |- http://bit.ly/9aKDM9 : embed images in Rd documents |- http://tr.im/OIXN : raster images and RImageJ |- http://tr.im/OcQe : Rcpp 0.7.7 ______________________________________________ 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.