I wrote a R function insert to insert a given element e at a given position p of a vector v.
Here it is:
insert <- function(v, e, p) {
if (length(e) != 1 || length(p) != 1) {
stop('supported the insertion of only one element per call.')
}
len <- length(v)
nms <- names(v)
enm <- names(e)
res <- NULL
if (p > 1 && p <= len) {
res <- c(v[1:(p-1)], e, v[p:len]) # insert
} else if (p == 1) {
res <- c(e, v) # prepend
} else if (p == (len+1)) {
res <- c(v, e) # append
} else {
stop('wrong position')
}
if (!is.null(enm)) {
names(res) <- insert(nms, enm, p)
}
res
}
Note that this function, like almost everything in R, returns a new vector. In addition (see recursive call), it inserts also the name of the element, if it has one.
Here is a simple example of use:
a <- c(1,2,3,4,5,7,8,10)
names(a) <- c(letters[1:5], letters[7:8], letters[10])
a
# a b c d e g h j
# 1 2 3 4 5 7 8 10
b <- c(9)
names(b) <- letters[9]
insert(a, b, 8)
# a b c d e g h i j
# 1 2 3 4 5 7 8 9 10
I'm trying to write a vectorized (and efficient) version of this function.
For now, I wrote a little elegant solution:
vinsert <- function(v, elems, positions) {
out <- v
for (i in 1:length(elems)) {
out <- insert(out, elems[i], positions[i])
}
out
}
And here a simple example of use:
a <- c(1,2,3,4,5,7,8,10)
names(a) <- c(letters[1:5], letters[7:8], letters[10])
a
# a b c d e g h j
# 1 2 3 4 5 7 8 10
z <- c(6,9)
names(z) <- c(letters[6], letters[9])
z
# f i
# 6 9
vinsert(a, z, z)
# a b c d e f g h i j
# 1 2 3 4 5 6 7 8 9 10
So, the issues that I am considering about both functions (insert and vinsert) are:
Rcpp?R function?Any suggest, help or more elegant and efficient solution? Thanks in advance.
It seems like there are a number of issues, e.g., how the order of insertion is influenced by prior insertions, and what to do when inserting sequences of more than one element. Here we have an original sequence
x <- letters[1:10]
and some things we'd like to insert into it
v <- LETTERS[1:4]
and where we'd like to insert them
at <- c(4, 7, 2, 6)
One way of doing the insertion is to figure out the order of the new index values at relative to the original; order is providing a stable order
o <- order(c(seq_along(x), at))
and then to do the insertion
> c(x, v)[o]
[1] "a" "b" "C" "c" "d" "A" "e" "f" "D" "g" "B" "h" "i" "j"
The insertion rules are not quite the same as your original
> o = order(c(seq_along(a), z))
> c(a, z)[o]
a b c d e g f h j i
1 2 3 4 5 7 6 8 10 9
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With