我写了一个 R
函数 insert
来在 a 的给定位置 p
插入一个给定的元素 e
矢量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
函数编写等效函数?
任何建议、帮助或更优雅、更有效的解决方案?提前致谢。
最佳答案
似乎存在许多问题,例如,插入顺序如何受先前插入的影响,以及插入多个元素的序列时该怎么做。这里我们有一个原始序列
x <- letters[1:10]
还有一些我们想插入的东西
v <- LETTERS[1:4]
以及我们想插入它们的地方
at <- c(4, 7, 2, 6)
插入的一种方法是找出新索引值 at
相对于原始索引值的顺序; order
提供稳定订单
o <- order(c(seq_along(x), at))
然后进行插入
> c(x, v)[o]
[1] "a" "b" "C" "c" "d" "A" "e" "f" "D" "g" "B" "h" "i" "j"
插入规则和你原来的不太一样
> 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
关于r - 向量化插入元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15937681/