[This article was first published on John Myles White: Die Sudelbücher » Statistics, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
This morning, I got a chance to read enough of the R Language Definition to finish my implementations of push
and pop
. While I was at it, I also wrote implementations of unshift
, shift
, queue
and dequeue
. Here they are:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | push <- function(vector, item) { vector.lvalue.symbol <- substitute(vector) new.expression <- paste(vector.lvalue.symbol, ' <- c(', vector.lvalue.symbol, ', ', item, ')', sep = '') eval(parse(text = new.expression), sys.frame(sys.parent())) } pop <- function(vector) { vector.lvalue.symbol <- substitute(vector) temp.env <- new.env() last.element <- eval(parse(text = paste(vector.lvalue.symbol, '[length(', vector.lvalue.symbol, ')]', sep = '')), sys.frame(sys.parent())) assign('tmp', last.element, envir = temp.env) eval(parse(text = paste(vector.lvalue.symbol, ' <- ', vector.lvalue.symbol, '[-length(', vector.lvalue.symbol, ')]', sep = '')), sys.frame(sys.parent())) return(get('tmp', envir = temp.env)) } unshift <- function(vector, item) { vector.lvalue.symbol <- substitute(vector) new.expression <- paste(vector.lvalue.symbol, ' <- c(', item, ', ', vector.lvalue.symbol, ')', sep = '') eval(parse(text = new.expression), sys.frame(sys.parent())) } shift <- function(vector) { vector.lvalue.symbol <- substitute(vector) temp.env <- new.env() last.element <- eval(parse(text = paste(vector.lvalue.symbol, '[1]', sep = '')), sys.frame(sys.parent())) assign('tmp', last.element, envir = temp.env) eval(parse(text = paste(vector.lvalue.symbol, ' <- ', vector.lvalue.symbol, '[-1]', sep = '')), sys.frame(sys.parent())) return(get('tmp', envir = temp.env)) } queue <- function(vector, item) { vector.lvalue.symbol <- substitute(vector) new.expression <- paste(vector.lvalue.symbol, ' <- c(', vector.lvalue.symbol, ', ', item, ')', sep = '') eval(parse(text = new.expression), sys.frame(sys.parent())) } dequeue <- function(vector) { vector.lvalue.symbol <- substitute(vector) temp.env <- new.env() last.element <- eval(parse(text = paste(vector.lvalue.symbol, '[1]', sep = '')), sys.frame(sys.parent())) assign('tmp', last.element, envir = temp.env) eval(parse(text = paste(vector.lvalue.symbol, ' <- ', vector.lvalue.symbol, '[-1]', sep = '')), sys.frame(sys.parent())) return(get('tmp', envir = temp.env)) } |
In general, the secret to writing these pseudo-macros is to use substitute
. For the three functions that need to return a value as well as edit the passed parameter, you also need to use new.env
, assign
and get
to edit the relevant symbol tables during function execution.
To check that these functions work, try the following examples after defining the functions above:
1 2 3 4 5 6 7 8 9 10 11 12 13 | v <- c(1) push(v, 2) v pop(v) == 2 v unshift(v, 0) v shift(v) == 0 v queue(v, 2) v dequeue(v) == 1 v |
To leave a comment for the author, please follow the link and comment on their blog: John Myles White: Die Sudelbücher » Statistics.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.