I want an easy way to access the last values of objects. I have implemented a function that allows for Python-like negative indexing (count-backwards-and-keep-only-those-elements instead of R's remove-those-elements-and-keep-all-other-elements). There are some questions about this, but no one attempted to do this:
- How to access the last value in a vector?
- Getting the last n elements of a vector. Is there a better way than using the length() function?
Basically, I want to redefine [
and [[
, so that one can user a special operator (e.g. _
) to use Python-like indexing. For instance, like this:
iris[1, ] #first row
iris[-1, ] #everything but first row
iris[_1, ] #last row, equivalent to tail(iris, 1)
iris[, _1] #last column, equivalent to iris[ncol(iris)]
Is it possible? I know it is possible to redefine e.g. +
to introduce character concatenation like other languages have (see this answer).
In case it's not possible, here's my workaround function:
extract_last = function(x, margin_1, margin_2, drop = FALSE) {
#check types
if (!(is.vector(x) || is.matrix(x) || is.data.frame(x))) stop("x was an unsupported type (not a vector, matrix or data.frame)!")
#vector
if (is.vector(x)) return(rev(x)[margin_1])
#get dims
x_dims = dim(x)
#make indices
if (missing("margin_1")) {
margin_1 = 1:x_dims[1]
} else {
margin_1 = (x_dims[1] + 1) - margin_1
}
if (missing("margin_2")) {
margin_2 = 1:x_dims[2]
} else {
margin_2 = (x_dims[2] + 1) - margin_2
}
#subset
return(x[margin_1, margin_2, drop = drop])
}
#tests
extract_last(iris, 1) == tail(iris, 1)
extract_last(iris, 10:1) == tail(iris, 10)
extract_last(iris, , 1) == iris[5]
extract_last(iris, , 2:1) == iris[4:5]
extract_last(iris, 10:1, 1) == iris[141:150, 5, drop = FALSE]