我有以下数据:
orig.vec <- c(1:10)
idx <- c(3,5,6)
rep.vec <- list(c(7,7,7), c(8,8,8), c(9,9,9))
第一。如何将rep.vec
的元素插入orig.vec
中idx
所包含的位置,并将orig.vec
值移至左/右?
期望的结果:
orig.vec
向右移动:1,2,7,7,7,3,4,8,8,8,5,9,9,9,6,7,8,9,10
orig.vec
向左移动:1,2,3,7,7,7,4,5,8,8,8,6,9,9,9,7,8,9,10
第二。如何使用orig.vec
的元素替换idx
中包含的位置rep.vec
的元素?
期望的结果:
1,2,7,7,7,4,8,8,8,9,9,9,7,8,9,10
答案 0 :(得分:2)
第一和第二部分
lst <- split(orig.vec,cumsum(seq_along(orig.vec) %in% idx))
lst1 <- split(orig.vec,cumsum(seq_along(orig.vec) %in% (idx+1)))
i1 <- seq_along(rep.vec)
unlist(c(Map(c, lst[i1], rep.vec), lst[setdiff(seq_along(lst), i1)]), use.names=FALSE)
#[1] 1 2 7 7 7 3 4 8 8 8 5 9 9 9 6 7 8 9 10
unlist(c(Map(c, lst1[i1], rep.vec), lst1[setdiff(seq_along(lst1), i1)]), use.names=FALSE)
#[1] 1 2 3 7 7 7 4 5 8 8 8 6 9 9 9 7 8 9 10
第三部分可以使用
完成lst <- split(seq_along(orig.vec),cumsum(seq_along(orig.vec) %in% idx))
i2 <- sapply(lst, function(i) any(i %in% idx))
lst[i2] <- Map(c, rep.vec, lapply(lst[i2], `[`, -1))
unlist(lst, use.names=FALSE)
#[1] 1 2 7 7 7 4 8 8 8 9 9 9 7 8 9 10
另一种选择是使用append
idx1 <- idx+c(0,lengths(rep.vec)[-1])
for(i in seq_along(rep.vec)){
orig.vec <- append(orig.vec, rep.vec[[i]], after = idx1[i]-1)
}
orig.vec
#[1] 1 2 7 7 7 3 4 8 8 8 5 9 9 9 6 7 8 9 10
在上面的循环中替换after = idx1[i]
(重置'orig.vec'后给出
orig.vec
#[1] 1 2 3 7 7 7 4 5 8 8 8 6 9 9 9 7 8 9 10
第三部分
v1 <- orig.vec[-idx]
for(i in seq_along(rep.vec)){
v1 <- append(v1, rep.vec[[i]], after = idx1[i]-i)
}
v1
#[1] 1 2 7 7 7 4 8 8 8 9 9 9 7 8 9 10
答案 1 :(得分:2)
与akrun后来发布的解决方案没什么不同,但是将orig.vec
转换为“列表”以附加另一个“列表”的元素会使连接/替换更清晰:
ff = function(x, v, i)
{
if(!length(i)) return(unlist(x))
Recall(append(as.list(x), v[1L], i[[1L]]), v[-1L], i[-1L])
}
#1
ff(orig.vec, rep.vec, idx + seq_along(idx) - 2L)
# [1] 1 2 7 7 7 3 4 8 8 8 5 9 9 9 6 7 8 9 10
#2
ff(orig.vec, rep.vec, idx + seq_along(idx) - 1L)
# [1] 1 2 3 7 7 7 4 5 8 8 8 6 9 9 9 7 8 9 10
#3 here, simply, replace between two "list"s
unlist(replace(as.list(orig.vec), idx, rep.vec))
# [1] 1 2 7 7 7 4 8 8 8 9 9 9 7 8 9 10
请注意,对于非常大的对象,连续级联通常很麻烦。
答案 2 :(得分:2)
另一种可能的方法:
doit<-function(orig.vec,idx,rep.vec,how){
left <- c(1,idx + (how != "R"))
right <- c(idx - (how != "L"),length(orig.vec))
parts <- apply(cbind(left,right),1,
function(x) if(x[1]>x[2]) c() else orig.vec[x[1]:x[2]])
unlist(c(lapply(1:length(idx),
function(x) c(parts[[x]],rep.vec[[x]])),
tail(parts,1)))
}
> doit(orig.vec,idx,rep.vec,"R")
[1] 1 2 7 7 7 3 4 8 8 8 5 9 9 9 6 7 8 9 10
> doit(orig.vec,idx,rep.vec,"L")
[1] 1 2 3 7 7 7 4 5 8 8 8 6 9 9 9 7 8 9 10
> doit(orig.vec,idx,rep.vec,"X")
[1] 1 2 7 7 7 4 8 8 8 9 9 9 7 8 9 10
答案 3 :(得分:2)
orig.vec <- c(1:10)
idx <- c(3,5,6)
rep.vec <- list(c(7,7,7), c(8,8,8), c(9,9,9))
left <- Map('c', idx, rep.vec)
right <- Map('c', rep.vec, idx)
repl <- rep.vec
l <- as.list(orig.vec)
l[idx] <- left
l[idx] <- right
l[idx] <- repl
unlist(l)
## left
# [1] 1 2 3 7 7 7 4 5 8 8 8 6 9 9 9 7 8 9 10
## right
# [1] 1 2 7 7 7 3 4 8 8 8 5 9 9 9 6 7 8 9 10
## repl
# [1] 1 2 7 7 7 4 8 8 8 9 9 9 7 8 9 10
编辑:作为一个功能
insert <- function(x, index, replacement, how = c('replace','left','right')) {
how <- match.arg(how)
repl <- switch (how,
replace = replacement,
left = Map('c', index, replacement),
right = Map('c', replacement, index)
)
x[index] <- repl
unlist(x)
}
sapply(c('replace','left','right'), insert,
x = orig.vec, index = idx, replacement = rep.vec)
# $replace
# [1] 1 2 7 7 7 4 8 8 8 9 9 9 7 8 9 10
#
# $left
# [1] 1 2 3 7 7 7 4 5 8 8 8 6 9 9 9 7 8 9 10
#
# $right
# [1] 1 2 7 7 7 3 4 8 8 8 5 9 9 9 6 7 8 9 10