Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subsetting vector: how to programatically pass negative index safely?

Tags:

indexing

r

Given a vector, say v = 1:10, one can remove elements from v using negative indexing, e.g. v[-1], v[-length(v)], v[-c(2,3)], to remove the first, last and 2nd/3rd element respectively.

I would like to split v by passing in a split index n, taking values 0 to length(v). The code below:

v1 <- v[1:n]
v2 <- v[-c(1:n)]

works perfectly fine except for n = 0. Now I know that 1:n is generally unsafe and should be replaced with seq_len(n), however, the assignment v2 <- v[-seq_len(0)] produces an empty vector.

Is there way of doing this 'safely' using the bracket subsetting notation? Otherwise I know how to do it using head and tails:

v1 <- head(v, n)
v2 <- tail(v, length(v) - n)

Relevant other q/as:

Complement of empty index vector is empty index vector

like image 494
Alex Avatar asked Feb 05 '23 23:02

Alex


2 Answers

You could use an if() statement inside the brackets. For example, this will just return the whole vector if n is zero and remove the sequence 1:n otherwise.

x <- 1:10

n <- 0
x[ if(n == 0) TRUE else -seq_len(n) ]  ## n == 0 is !n for the golfers
# [1]  1  2  3  4  5  6  7  8  9 10

n <- 5
x[ if(n == 0) TRUE else -seq_len(n) ]
# [1]  6  7  8  9 10
like image 73
Rich Scriven Avatar answered May 20 '23 07:05

Rich Scriven


v = 1:10
n = 0; split(v, seq_along(v)/min(n,length(v)) <= 1)
#$`FALSE`
# [1]  1  2  3  4  5  6  7  8  9 10

n = 1; split(v, seq_along(v)/min(n,length(v)) <= 1)
#$`FALSE`
#[1]  2  3  4  5  6  7  8  9 10

#$`TRUE`
#[1] 1

n = 10; split(v, seq_along(v)/min(n,length(v)) <= 1)
#$`TRUE`
# [1]  1  2  3  4  5  6  7  8  9 10

n = -10; split(v, seq_along(v)/min(n,length(v)) <= 1)
#$`TRUE`
# [1]  1  2  3  4  5  6  7  8  9 10

n = 100; split(v, seq_along(v)/min(n,length(v)) <= 1)
#$`TRUE`
# [1]  1  2  3  4  5  6  7  8  9 10

Further simplified by thelatemail in comment

split(v, seq_along(v) > n)
like image 38
d.b Avatar answered May 20 '23 08:05

d.b