Why does R column interval slicing not work when interval has length 1?

Viewed 84

I was running some code yesterday that involved slicing a matrix into intervals of columns. That is, given an nxp matrix A and a sequence of break points, I sliced A using a for loop. The first piece was A[,1:break_points[1]]. The second piece was A[,break_points[1]+1:break_points[2]]. The third piece was A[,break_points[2]+1:break_points[3]], etc.

Unfortunately, the execution ended in an error. After a bit of digging, I found the root of the problem: One of the column intervals was length 1. As it turns out, A[,3679:3679] does not work as expected. More specifically,

A0 <- A[,3679:3680]
ncol(A0)
> 2

but

A0 <- A[,3679:3679]
ncol(A0)
> NULL

I know how to fix this: Just create an if-else exception for the case that break_points[i+1] - break_points[i] = 1. But I'm curious why R treats column slices of length 1 differently in the first place.

1 Answers

When subsetting a matrix, R by default converts slices of length 1 to a vector. To prevent this you have to or should add argument drop = FALSE, e.g. A[ ,3679:3679, drop = FALSE] will give you a one-column matrix instead of a vector. A discusion on simplyfing vs. preserving subsetting can be found in Hadley Wickham's Book Advanced R.

Related