163

I would like to create a vector in which each element is the i+6th element of another vector.

For example, in a vector of length 120 I want to create another vector of length 20 in which each element is value i, i+6, i+12, i+18... of the initial vector, i.e. I want to extract every 6th element of the original.

7 Answers 7

204
a <- 1:120 b <- a[seq(1, length(a), 6)] 
Sign up to request clarification or add additional context in comments.

4 Comments

It is better to use seq.int(1L, length(a), 6L), at least for long vectors
@WojciechSobala Could you comment why it is better?
@DavidPell seq.int is faster in microbenchmarks, but I suspect that any performance increases in an actual program would be dwarfed by the running time of other parts.
I hate to compare Python with R, but how great could PyRon be? a = 1:120; b = [::6]. Python can't do the former, R not the latter.
56

Another trick for getting sequential pieces (beyond the seq solution already mentioned) is to use a short logical vector and use vector recycling:

foo[ c( rep(FALSE, 5), TRUE ) ] 

2 Comments

An advantage of this approach is it can be used on a temporary; in order to use seq you have to be able to call length on the vector. letters[letters < 'm'][c(TRUE, FALSE, FALSE)]
This also made it easy to leave out every nth element by swapping places for FALSE and TRUE. (My problem was that I had two time series where one had 20 % higher resolution than the other. I could align them by selecting items 1, 2, 3, 4, 5 and then dropping 6, repeatedly.)
31

I think you are asking two things which are not necessarily the same

I want to extract every 6th element of the original

You can do this by indexing a sequence:

foo <- 1:120 foo[1:20*6] 

I would like to create a vector in which each element is the i+6th element of another vector.

An easy way to do this is to supplement a logical factor with FALSEs until i+6:

foo <- 1:120 i <- 1 foo[1:(i+6)==(i+6)] [1] 7 14 21 28 35 42 49 56 63 70 77 84 91 98 105 112 119 i <- 10 foo[1:(i+6)==(i+6)] [1] 16 32 48 64 80 96 112 

2 Comments

So slick! I've used it in the other direction also, foo[1:(i+6)!=(i+6)] i.e. output all values except the sixth.
a more general way to subset every nth element of a vector x would be x[1:(length(x)/n)*n]
3

To select every nth element from any starting position in the vector

nth_element <- function(vector, starting_position, n) { vector[seq(starting_position, length(vector), n)] } # E.g. vec <- 1:12 nth_element(vec, 1, 3) # [1] 1 4 7 10 nth_element(vec, 2, 3) # [1] 2 5 8 11 

Comments

2

To select every n-th element with an offset/shift of f=0,...,n-1, use

vec[mod(1:length(vec), n)==f] 

Of course, you can wrap this in a nice function:

nth_element <- function(vec, interval, offset=0){ vec[mod(1:length(vec), interval)==mod(offset, interval)] } 

Comments

0

I wanted to end up with a vector of the same length so I made this:

extract_nth_wraparound <- function(x, n) { index <- (seq_along(x) - 1) %% n + 1 ordered_indices <- order(index) return(x[ordered_indices]) } 

Comments

0
s = 6 # selection step, i.e., every s'th element will be selected p = 1 # starting position, i.e., position of the first element to be selected v = LETTERS # vector to select from v %>% .[seq_along(.) %% s == p] # [1] "A" "G" "M" "S" "Y" 

Check (position of the selected elements)

v %>% .[seq_along(.) %% s == p] %>% match(v) # [1] 1 7 13 19 25 

From ?Arithmetic :

%% indicates x mod y (“x modulo y”), i.e., computes the ‘remainder’

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.