在每 n 个元素之后插入列表
interleave list after every n elements
我想在每 2 个列表元素之后交错 interElem
。
数据:
listi <- c(rbind(letters[1:4], list(c(13,37))))
interElem <- c("inter","leavistan")
看起来像:
> listi
[[1]]
[1] "a"
[[2]]
[1] 13 37
[[3]]
[1] "b"
[[4]]
[1] 13 37
[[5]]
[1] "c"
[[6]]
[1] 13 37
[[7]]
[1] "d"
[[8]]
[1] 13 37
>
想要的结果(列表元素编号不准确)
> listi
[[1]]
[1] "a"
[[2]]
[1] 13 37
[[XXX]]
[1] "inter" "leavistan"
[[3]]
[1] "b"
[[4]]
[1] 13 37
[[XXX]]
[1] "inter" "leavistan"
[[5]]
[1] "c"
[[6]]
[1] 13 37
[[XXX]]
[1] "inter" "leavistan"
[[7]]
[1] "d"
[[8]]
[1] 13 37
>
我们可以创建一个分组变量,用 gl
拆分每 2 个元素,然后在每个嵌套的 list
末尾附加 'interElem' 并用 [=15= 展平它]
res <- head(do.call(c, lapply(split(listi, as.integer(gl(length(listi), 2,
length(listi)))), function(x) c(x, list(interElem )))), -1)
names(res) <- NULL
或者另一种选择是将其转换为 matrix
、rbind
和 'interElem' 并连接到 list
head(c(rbind(matrix(listi, nrow=2), list(interElem))), -1)
#[[1]]
#[1] "a"
#[[2]]
#[1] 13 37
#[[3]]
#[1] "inter" "leavistan"
#[[4]]
#[1] "b"
#[[5]]
#[1] 13 37
#[[6]]
#[1] "inter" "leavistan"
#[[7]]
#[1] "c"
#[[8]]
#[1] 13 37
#[[9]]
#[1] "inter" "leavistan"
#[[10]]
#[1] "d"
#[[11]]
#[1] 13 37
或者我们可以在 for
循环中使用 append
listn <- listi
i1 <- seq(2, length(listi), by = 2)
i2 <- i1 + (seq_along(i1) - 1)
for(i in seq_along(i2)) listn <- append(listn, list(interElem), after = i2[i])
head(listn, -1)
这是新列表的长度
len = length(listi) + max(0, floor((length(listi) - 1) / 2))
以及应为原始值的元素索引
idx = seq_len(len) %% 3 != 0
使用这些创建新列表并插入旧值和插页式值
res = vector("list", len)
res[idx] = l
res[!idx] = list(v)
为了稳健性和重用而打包为函数。
fun = function(l, v, n = 2) {
## validate arguments
stopifnot(
is.numeric(n), length(n) == 1, !is.na(n),
is.list(l), is.vector(v)
)
## length and index for original values
len = length(l) + max(0, floor((length(l) - 1) / n))
idx = seq_len(len) %% (n + 1) != 0
## create and populate result
res = vector("list", len)
res[idx] = l
res[!idx] = list(v)
res
}
和
> str(fun(listi, interElem))
List of 11
$ : chr "a"
$ : num [1:2] 13 37
$ : chr [1:2] "inter" "leavistan"
$ : chr "b"
$ : num [1:2] 13 37
$ : chr [1:2] "inter" "leavistan"
$ : chr "c"
$ : num [1:2] 13 37
$ : chr [1:2] "inter" "leavistan"
$ : chr "d"
$ : num [1:2] 13 37
这适用于您的示例和奇数长度的列表,包括 2 和 1。如果列表的长度为奇数,matrix()
和 cbind()
会发出警告。空列表作为条目 returns 插入列表。我在这里要做的就是为聚合 listi
和 list(interElem)
.
的后续子集形成索引向量
l <- length(listi)
i <- rbind(matrix(1:l, nrow = 2), rep(l+1,l%/%2))[1:(l + l%/%2 - (l+1)%%2)]
c(listi, list(interElem))[i]
我想在每 2 个列表元素之后交错 interElem
。
数据:
listi <- c(rbind(letters[1:4], list(c(13,37))))
interElem <- c("inter","leavistan")
看起来像:
> listi
[[1]]
[1] "a"
[[2]]
[1] 13 37
[[3]]
[1] "b"
[[4]]
[1] 13 37
[[5]]
[1] "c"
[[6]]
[1] 13 37
[[7]]
[1] "d"
[[8]]
[1] 13 37
>
想要的结果(列表元素编号不准确)
> listi
[[1]]
[1] "a"
[[2]]
[1] 13 37
[[XXX]]
[1] "inter" "leavistan"
[[3]]
[1] "b"
[[4]]
[1] 13 37
[[XXX]]
[1] "inter" "leavistan"
[[5]]
[1] "c"
[[6]]
[1] 13 37
[[XXX]]
[1] "inter" "leavistan"
[[7]]
[1] "d"
[[8]]
[1] 13 37
>
我们可以创建一个分组变量,用 gl
拆分每 2 个元素,然后在每个嵌套的 list
末尾附加 'interElem' 并用 [=15= 展平它]
res <- head(do.call(c, lapply(split(listi, as.integer(gl(length(listi), 2,
length(listi)))), function(x) c(x, list(interElem )))), -1)
names(res) <- NULL
或者另一种选择是将其转换为 matrix
、rbind
和 'interElem' 并连接到 list
head(c(rbind(matrix(listi, nrow=2), list(interElem))), -1)
#[[1]]
#[1] "a"
#[[2]]
#[1] 13 37
#[[3]]
#[1] "inter" "leavistan"
#[[4]]
#[1] "b"
#[[5]]
#[1] 13 37
#[[6]]
#[1] "inter" "leavistan"
#[[7]]
#[1] "c"
#[[8]]
#[1] 13 37
#[[9]]
#[1] "inter" "leavistan"
#[[10]]
#[1] "d"
#[[11]]
#[1] 13 37
或者我们可以在 for
循环中使用 append
listn <- listi
i1 <- seq(2, length(listi), by = 2)
i2 <- i1 + (seq_along(i1) - 1)
for(i in seq_along(i2)) listn <- append(listn, list(interElem), after = i2[i])
head(listn, -1)
这是新列表的长度
len = length(listi) + max(0, floor((length(listi) - 1) / 2))
以及应为原始值的元素索引
idx = seq_len(len) %% 3 != 0
使用这些创建新列表并插入旧值和插页式值
res = vector("list", len)
res[idx] = l
res[!idx] = list(v)
为了稳健性和重用而打包为函数。
fun = function(l, v, n = 2) {
## validate arguments
stopifnot(
is.numeric(n), length(n) == 1, !is.na(n),
is.list(l), is.vector(v)
)
## length and index for original values
len = length(l) + max(0, floor((length(l) - 1) / n))
idx = seq_len(len) %% (n + 1) != 0
## create and populate result
res = vector("list", len)
res[idx] = l
res[!idx] = list(v)
res
}
和
> str(fun(listi, interElem))
List of 11
$ : chr "a"
$ : num [1:2] 13 37
$ : chr [1:2] "inter" "leavistan"
$ : chr "b"
$ : num [1:2] 13 37
$ : chr [1:2] "inter" "leavistan"
$ : chr "c"
$ : num [1:2] 13 37
$ : chr [1:2] "inter" "leavistan"
$ : chr "d"
$ : num [1:2] 13 37
这适用于您的示例和奇数长度的列表,包括 2 和 1。如果列表的长度为奇数,matrix()
和 cbind()
会发出警告。空列表作为条目 returns 插入列表。我在这里要做的就是为聚合 listi
和 list(interElem)
.
l <- length(listi)
i <- rbind(matrix(1:l, nrow = 2), rep(l+1,l%/%2))[1:(l + l%/%2 - (l+1)%%2)]
c(listi, list(interElem))[i]