我编写了一个R
函数来在向量的给定位置insert
插入给定元素。e
p
v
这里是:
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
}
请注意,此函数与 R 中的几乎所有内容一样,返回一个新向量。此外(参见递归调用),它还插入元素的名称,如果它有一个。
下面是一个简单的使用示例:
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
我正在尝试编写此函数的矢量化(高效)版本。
现在,我写了一个优雅的解决方案:
vinsert <- function(v, elems, positions) {
out <- v
for (i in 1:length(elems)) {
out <- insert(out, elems[i], positions[i])
}
out
}
这里有一个简单的使用示例:
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
因此,我正在考虑的有关这两个功能(insert
和vinsert
)的问题是:
- 返回一个新的向量或修改向量并返回它?
Rcpp
用?写一个等价的函数- 可以使用一阶函数编写等效
R
函数吗?
有什么建议、帮助或更优雅有效的解决方案吗?提前致谢。