R 中不同长度的向量的绑定列表

Binding list of vectors of different lengths in R

提问人:Mr Frog 提问时间:11/14/2023 最后编辑:Mr Frog 更新时间:11/14/2023 访问量:71

问:

考虑具有不同长度的向量列表,例如定义为lV

set.seed(123)
v1 = rnorm(n = 5)
v2 = rnorm(n = 4)
v3 = rnorm(n = 3)
lV = list(v1, v2, v3)

我怎样才能以类似于

do.call("cbind", lV)

但获得

cbind(v1[3 : 5], v2[2 : 4], v3)

?最好不要使用慢速函数。

如果不清楚,我正在尝试保留每个向量的最后元素,其中n

n = min(sapply(X = lV, FUN = length))
print(n)
r 列表 向量 绑定

评论

1赞 Gregor Thomas 11/14/2023
从示例输出来看,您似乎不想像您所说的那样。我在回答中做出了这个假设。cbind(v1[3 : 5], v2[2 : 4], v3)n = min()n = max()
1赞 jpsmith 11/14/2023
我同意格雷戈尔·托马斯(Gregor Thomas)的观点,如果您可以编辑您的问题以包含所需的输出,那就太好了。祝你好运!

答:

4赞 Gregor Thomas 11/14/2023 #1
n = min(lengths(lV))
do.call(cbind, lapply(lV, tail, n))
#            [,1]       [,2]       [,3]
# [1,] 1.55870831  0.4609162 -0.4456620
# [2,] 0.07050839 -1.2650612  1.2240818
# [3,] 0.12928774 -0.6868529  0.3598138
3赞 jblood94 11/14/2023 #2

使用 和 的矢量化方法:sequencecumsum

n <- min(lengths(lV))
matrix(unlist(lV)[sequence(rep(n, length(lV)), cumsum(lengths(lV)) - n + 1L)], n)
#>            [,1]       [,2]       [,3]
#> [1,] 1.55870831  0.4609162 -0.4456620
#> [2,] 0.07050839 -1.2650612  1.2240818
#> [3,] 0.12928774 -0.6868529  0.3598138

根据 中向量的大小,这可能比循环或 -family 解决方案的性能要高得多:lVapply

lV <- lapply(sample(100, 100, 1), runif)
n <- min(lengths(lV))

microbenchmark::microbenchmark(
  do.call = do.call(cbind, lapply(lV, tail, n)),
  sequence = matrix(unlist(lV)[sequence(rep(n, length(lV)), cumsum(lengths(lV)) - n + 1L)], n),
  check = "identical"
)
#> Unit: microseconds
#>      expr   min     lq    mean median     uq    max neval
#>   do.call 459.2 562.25 594.879 588.25 604.40 1985.1   100
#>  sequence  21.6  28.70  33.822  29.95  34.15   81.7   100

评论

0赞 jay.sf 11/14/2023
尝试 ,变得很慢。lV <- lapply(sample(10000, 10000, 1), runif)
0赞 jblood94 11/14/2023
是的。因此,需要注意的是“取决于”......lV
1赞 ThomasIsCoding 11/14/2023 #3

短代码选项

> sapply(lV, tail, min(lengths(lV)))
           [,1]       [,2]       [,3]
[1,] 1.55870831  0.4609162 -0.4456620
[2,] 0.07050839 -1.2650612  1.2240818
[3,] 0.12928774 -0.6868529  0.3598138