How to build this binary variable in R?

The goal is to check if the value in the index i is 1, and then make the previous six entries equal to 1.

x <- c(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1) ## Required output y <- c(1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) ## Attempt for(j in seq_along(x)){ if(x[j] == 1){ for(i in (j-6):j) x[i] = 1 }} 

Could you help solve this or the best approach?

Thanks.

+5
source share
4 answers

You can try the following options (although remember to initialize x when trying each option, as I redefine it)

 indx <- mapply(function(x, y) x:y, which(x == 1) - 6 , which(x == 1)) x[indx[indx > 0]] <- 1 x ## [1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 

Or even easier

 indx <- sapply(which(x == 1) - 6, function(x) x:(x + 6)) x[indx[indx > 0]] <- 1 x ## [1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 

or

 indx <- apply(cbind(which(x == 1) - 6 , which(x == 1)), 1, function(x) x[1]:x[2]) x[indx[indx > 0]] <- 1 x ## [1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 

or

 indx <- seq_len(6) indx <- sapply(which(x == 1), function(x) x - indx) x[indx[indx > 0]] <- 1 x ## [1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 
+5
source

A fully vectorized solution using filter :

 as.integer( #turn logical value into numbers as.logical( #coerce to logical --> 0 becomes FALSE, everything else TRUE rev( #reverse order filter( #linear filtering c(rep(0, 6), #pad with zeros in the beginning to avoid NAs rev(x)), #revers order of input vector c(rep(1, 7)), sides=1 #y_i = x_i * 1 + x_(i-1) * 1 +...+ x_(i-6) * 1 )[-(1:6)]))) #remove NA values #[1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 
+5
source

Using the 'for' loop:

 ddf = data.frame(x,y=0) for(i in 1:nrow(ddf)){ if(ddf[i,'x']==1){ j = i-5 if(j<1) j=1 ddf[j:i,'y'] = 1 } } ddf xy 1 0 1 2 0 1 3 0 1 4 1 1 5 0 0 6 0 0 7 0 0 8 0 0 9 0 0 10 0 0 11 0 0 12 0 1 13 0 1 14 0 1 15 0 1 16 0 1 17 1 1 18 0 1 19 1 1 y = ddf$y y [1] 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 
+3
source
 y<-x y[unlist(sapply(which(x==1), function(val){ val:(max(val-6,1)) } ) ) ]<-1 > y [1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 

Explanation:

First, I look for the indices x = 1 with which(x==1) . Then for each of the indices I get indices from one from x = 1 to the 6th before with sapply(...) , after which I exclude the result only for the index vector, for which y should be 1. Then I assigned 1 to the appropriate y values.

another letter, in 2 stages:

 y<-x ind<-unlist(sapply(which(x==1),function(val){val:(max(val-6,1))})) y[ind]<-1 > y [1] 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 
+2
source

Source: https://habr.com/ru/post/1206799/


All Articles