Get Back for R

David Hugh-Jones

This is lame

letters[length(letters)]   # so unreadable
[1] "z"


letters[(length(letters) - 3):(length(letters))]   # even worse
[1] "w" "x" "y" "z"


letters[length(letters) - 3:0]   # what am I a maths nerd
[1] "w" "x" "y" "z"

Tail

tail(letters, 4)   # ok
[1] "w" "x" "y" "z"


tail(letters, 2:4)  # boring
Error in tail.default(letters, 2:4): invalid 'n' - must have length one when dim(x) is NULL, got 3


tail(letters, 1) <- "Z"   # boooring
Error in tail(letters, 1) <- "Z": could not find function "tail<-"

Reverse of helpful

rev(letters)[1:3]                     # ok...
[1] "z" "y" "x"


rev(letters)[1:3] <- c("Z", "Y", "X") # why :-(
Error in rev(letters)[1:3] <- c("Z", "Y", "X"): could not find function "rev<-"

Why don’t people do this, are they stupid

.back_ix <- function (x, ix) {
  stopifnot(is.numeric(ix), all(abs(ix) <= length(x)))
  ix <- ix[ix != 0]
  neg <- ix < 0
  ix <- length(x) + 1 - abs(ix)
  ix[neg] <- -1 * ix[neg]
  ix
}

back <- function (x, ix) {
  x[.back_ix(x, ix)]
}

`back<-` <- function (x, ix, value) {
  x[.back_ix(x, ix)] <- value
  x
}

So obvious

back(letters, 4)
[1] "w"


back(letters, 1:4) # as it should be
[1] "z" "y" "x" "w"


back(letters, 2:4) # not a problem
[1] "y" "x" "w"


back(letters, 4:1) # just count from the back
[1] "w" "x" "y" "z"

As God intended

back(letters, 4) <- "W"
back(letters, 2:3) <- c("Y", "X")

cat(back(letters, 10:1)) 
q r s t u v W X Y z

Backwardation

letters[-(1:21)]
[1] "v" "W" "X" "Y" "z"
back(letters, -(1:21)) # of course!
[1] "a" "b" "c" "d" "e"


letters[0]
character(0)
back(letters, 0)
character(0)


letters[30]
[1] NA
back(letters, 30) # don't get over-excited
Error in .back_ix(x, ix): all(abs(ix) <= length(x)) is not TRUE

Gist

No I will not be producing a CRAN package

Conclusion

The Beatles recording Get Back