Vectorization insert element

I wrote an R function to insert a given element E at a given position P of vector v

Here 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)],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 also inserts the name of the element, if any

This is a simple example:

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 am trying to write a vectorized (efficient) version of this function

Now I have written an elegant solution:

vinsert <- function(v,elems,positions) {
  out <- v
  for (i in 1:length(elems)) {
    out <- insert(out,elems[i],positions[i])
  }
  out
}

Here is a simple example:

a <- c(1,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

Therefore, the two functions I am considering (insert and vinsert) are:

>Return a new vector or modify the vector and return it? > Write an equivalent function with rcpp? > Can I write an equivalent function using a first-order R function?

Any suggestions, help or more elegant and effective solutions? Thank you in advance

Solution

There seem to be many problems, such as how the insertion order is affected by previous insertion and what to do when inserting a sequence of more than one element Here we have a primitive sequence

x <- letters[1:10]

And what we want to insert

v <- LETTERS[1:4]

Where we want to insert them

at <- c(4,6)

One way to insert is to calculate the order of the new index value relative to the original value; Orders provide stable orders

o <- order(c(seq_along(x),at))

Then insert

> c(x,v)[o]
 [1] "a" "b" "C" "c" "d" "A" "e" "f" "D" "g" "B" "h" "i" "j"

The insertion rule is not exactly the same as the original insertion rule

> 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
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>