提问人:Mr Frog 提问时间:11/14/2023 最后编辑:Mr Frog 更新时间:11/14/2023 访问量:71
R 中不同长度的向量的绑定列表
Binding list of vectors of different lengths in R
问:
考虑具有不同长度的向量列表,例如定义为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)
答:
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
使用 和 的矢量化方法:sequence
cumsum
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 解决方案的性能要高得多:lV
apply
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
评论
cbind(v1[3 : 5], v2[2 : 4], v3)
n = min()
n = max()