[R] expanding some values in logical vector

Petr Pikal petr.pikal at precheza.cz
Mon Mar 15 11:57:55 CET 2004


Dear all

In automatic dropout evaluation function I construct an index (pointer), which 
will be TRUE at "unusual" values. Then I need to expand these TRUE values a 
little bit forward and backward.

Example:

having span=5, from vector

idx<-rep(F,10)
idx[4]<-T

> idx
 [1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE 
FALSE

I need

> idx
 [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE 
FALSE


I was using embed() for this task (myfun1):

idx <- rep(F,20)
idx[c(4,11,13)] <- T

> idx
 [1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE 
FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE 
FALSE

iii <- myfun1(idx)

> iii
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  
TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE 
FALSE


It is close to what I want, but it is slow and when idx vector is long enough it 
goes short of memory. Then I tried to accomplish it with rle() and some fiddling 
with $values and $lengths (myfun2), which works as long as the true values are 
completely separated.

idx <- rep(F,20)
idx[c(4,12)] <- T

> idx
 [1] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE 
FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
FALSE

iii <- myfun2(idx)
> iii
 [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  
TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE 
FALSE
	
But when using previous idx

idx <- rep(F,20)
idx[c(4,11,13)] <- T

iii <- myfun2(idx)
Error in rep.default(kody$values, opak) : invalid number of copies in "rep"

Problem is, if TRUE values are closer than span allows. Then some values in 
"opak" for FALSE kody$values are negative, what is not allowed. Setting them 
to zero will expand the length of index vector. Instead number of repetitions of 
neighbour TRUE values should be decreased accordingly. 

I greatly appreciated, if somebody could give me a hint if there is some another 
built in function which can help me or what to do with myfun2 or how to get 
properly expanded index values by some another way.

Sorry for the long post but I was not able to explain my problem and what I have 
done yet to solve it in shorter.

Thank you and best regards.

Petr Pikal




##### Here are functions used #####



myfun1 <- function(idx,span=5)

{
n <- length(idx)
s <- span%/%2
z <- embed(idx,span)
sumy <- rowSums(z)>0
index <- c(rep(sumy[1],s),sumy,rep(sumy[n-span+1],s))
}



myfun2 <- function(idx,span=5)

{
n <- length(idx)

kody <- rle(idx)
test <- letters[sum(cumsum(c(kody$values[1],idx[n])))+1] ####is some of true 
values at the end of vector idx?
opak <- kody$values*(span-1)*2-(span-1)+kody$lengths #### enlarge number of 
TRUE repetitions according to the span
delka <- length(opak)

#### some ifs to ensure the end points will have correct number of repetitions

opak[c(1,delka)] <- opak[c(1,delka)]+span%/%2
if (sum(kody$values)==0) opak <- n
if (opak[1]<0) {opak[2] <- opak[2]+opak[1]; opak[1] <- 0}
if (opak[delka]<0) {opak[delka-1] <- opak[delka-1]+opak[delka]; opak[delka] <- 
0}

switch(test,

a = opak<-opak,
b = opak[delka]<-opak[delka]-(span-1), 
c = opak[1]<-opak[1]-(span-1), 
d = opak[c(1,delka)]<-opak[c(1,delka)]-(span-1),

)

#### here should opak contain correct number of repetitions but does not

index<-rep(kody$values,opak)

}
Petr Pikal
petr.pikal at precheza.cz




More information about the R-help mailing list