From a vector of integers, build a longer vector including all integers whose distance from the original ones is at most 10

Viewed 31

I have this integer vector:

m <- 10
n <- 1000
index <- sample(seq_len(n), m)

I want to extend index, by including all integers whose distance from one of the values in index is no greater than 10, and eliminate duplicates. Duplicates are not very likely, with the current values of n and m, but better safe than sorry, and anyway the solution must work with generic values of n and m, with m<n.

Right now I do the following:

library(purrr)
index <- unique(sort(unlist(map(index, function(x) seq(x - 10, x + 10)))))

This works, but it's not exactly very readable. Any better ideas?

2 Answers

We can pipe it to make this readable

library(tidyverse)
out <- map(index, ~ seq(.x - 10, .x + 10) ) %>% # get the sequence 
         unlist %>%    # unlist the list to a vector
         unique %>%    # get the unique values
         sort          # sort

Instead of looping, we can also vectorize this by replicating the index and then add the sequence of number from -10:10, get the unique elements and sort

out2 <- sort(unique(rep(index, each = 21) + (-10:10)))
identical(out, out2)
#[1] TRUE

Personally I'd use outer rather than map for this:

sort(unique(outer(index, -10:10, "+")))

And, as akrun shows, you can use piping if you prefer not to nest things.

Related