Arrays 在三维阵列中添加列或行
我有一个这样的数组:Arrays 在三维阵列中添加列或行,arrays,r,Arrays,R,我有一个这样的数组: , , 1 [,1] [,2] [,3] [1,] 1 4 7 [2,] 2 5 8 [3,] 3 6 9 , , 2 [,1] [,2] [,3] [1,] 10 13 16 [2,] 11 14 17 [3,] 12 15 18 , , 3 [,1] [,2] [,3] [1,] 19 22 25 [2,] 20 23
, , 1
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
, , 2
[,1] [,2] [,3]
[1,] 10 13 16
[2,] 11 14 17
[3,] 12 15 18
, , 3
[,1] [,2] [,3]
[1,] 19 22 25
[2,] 20 23 26
[3,] 21 24 27
我想为每个组件添加一列,用0填充,以最终得到:
, , 1
[,1] [,2] [,3] [,4]
[1,] 1 4 7 0
[2,] 2 5 8 0
[3,] 3 6 9 0
, , 2
[,1] [,2] [,3] [,4]
[1,] 10 13 16 0
[2,] 11 14 17 0
[3,] 12 15 18 0
, , 3
[,1] [,2] [,3] [,4]
[1,] 19 22 25 0
[2,] 20 23 26 0
[3,] 21 24 27 0
有没有一种简单的方法可以使用R来实现这一点?这里有一种方法:
library(abind)
abind(x, array(0, replace(dim(x), 2, 1)), along = 2)
还有一个:
aperm(apply(x, c(1, 3), c, 0), c(2, 1, 3))
您也可以尝试类似的方法(虽然有点手动,但应该比其他BaseR解决方案更快)
indx仅针对挑战,另一个想法(加上一些额外的调味汁)似乎有效,除非我错过了什么:
add_col_or_row = function(x, n = 1, add_col = T, fill = 0)
{
m1 = matrix(x, ncol = if(add_col) nrow(x) * ncol(x) else nrow(x), byrow = T)
m2 = matrix(fill, nrow = if(add_col) dim(x)[3] else prod(dim(x)[-1]),
ncol = if(add_col) nrow(x) * n else n)
array(t(cbind(m1, m2)),
c(nrow(x) + ((!add_col) * n), ncol(x) + (add_col * n), dim(x)[3]))
}
aa = array(1:24, c(3, 4, 2))
aa
#, , 1
#
# [,1] [,2] [,3] [,4]
#[1,] 1 4 7 10
#[2,] 2 5 8 11
#[3,] 3 6 9 12
#
#, , 2
#
# [,1] [,2] [,3] [,4]
#[1,] 13 16 19 22
#[2,] 14 17 20 23
#[3,] 15 18 21 24
add_col_or_row(aa, 2, T)
#, , 1
#
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 1 4 7 10 0 0
#[2,] 2 5 8 11 0 0
#[3,] 3 6 9 12 0 0
#
#, , 2
#
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 13 16 19 22 0 0
#[2,] 14 17 20 23 0 0
#[3,] 15 18 21 24 0 0
#
add_col_or_row(aa, 2, F)
#, , 1
#
# [,1] [,2] [,3] [,4]
#[1,] 1 4 7 10
#[2,] 2 5 8 11
#[3,] 3 6 9 12
#[4,] 0 0 0 0
#[5,] 0 0 0 0
#
#, , 2
#
# [,1] [,2] [,3] [,4]
#[1,] 13 16 19 22
#[2,] 14 17 20 23
#[3,] 15 18 21 24
#[4,] 0 0 0 0
#[5,] 0 0 0 0
以及使用David Arenburg数据的基准:
microbenchmark(flodel1(df), add_col_or_row(df), times = 20)
#Unit: milliseconds
# expr min lq median uq max neval
# flodel1(df) 35.69158 54.88014 55.58363 56.40300 58.31250 20
# add_col_or_row(df) 19.87134 38.57792 39.11297 39.58347 44.59873 20
identical("dimnames<-"(flodel1(df), NULL), add_col_or_row(df))
#[1] TRUE
microbenchmark(flodel1(df),添加列或行(df),时间=20)
#单位:毫秒
#expr最小lq中值uq最大neval
#flodel1(df)35.69158 54.88014 55.58363 56.40300 58.31250 20
#添加列或列(df)19.87134 38.57792 39.11297 39.58347 44.59873 20
相同(“DIMNAMES”)另一个与您类似的选项是a2David(df)418.48397 602.08168 735.11478 712.36795 880.6805 1199.8118 100 akrun(df)478.91923 550.22464 765.16181 776.65756 908.5238 1159.0865 100
另一个问题是太手动了。您需要按照我的解决方案使用indx
,而不是1:3
或c(3,4,3)
因此这将是一个通用的解决方案。除此之外,您可以将其作为自己的答案发布。谢谢,作为单独的解决方案发布并没有多大优势,所以我将其保留。要添加到第三维,请使用下一个表单:abind(x,数组(0,replace(dim(x),3,1)),以及=3)
注意两处的变化。
add_col_or_row = function(x, n = 1, add_col = T, fill = 0)
{
m1 = matrix(x, ncol = if(add_col) nrow(x) * ncol(x) else nrow(x), byrow = T)
m2 = matrix(fill, nrow = if(add_col) dim(x)[3] else prod(dim(x)[-1]),
ncol = if(add_col) nrow(x) * n else n)
array(t(cbind(m1, m2)),
c(nrow(x) + ((!add_col) * n), ncol(x) + (add_col * n), dim(x)[3]))
}
aa = array(1:24, c(3, 4, 2))
aa
#, , 1
#
# [,1] [,2] [,3] [,4]
#[1,] 1 4 7 10
#[2,] 2 5 8 11
#[3,] 3 6 9 12
#
#, , 2
#
# [,1] [,2] [,3] [,4]
#[1,] 13 16 19 22
#[2,] 14 17 20 23
#[3,] 15 18 21 24
add_col_or_row(aa, 2, T)
#, , 1
#
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 1 4 7 10 0 0
#[2,] 2 5 8 11 0 0
#[3,] 3 6 9 12 0 0
#
#, , 2
#
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 13 16 19 22 0 0
#[2,] 14 17 20 23 0 0
#[3,] 15 18 21 24 0 0
#
add_col_or_row(aa, 2, F)
#, , 1
#
# [,1] [,2] [,3] [,4]
#[1,] 1 4 7 10
#[2,] 2 5 8 11
#[3,] 3 6 9 12
#[4,] 0 0 0 0
#[5,] 0 0 0 0
#
#, , 2
#
# [,1] [,2] [,3] [,4]
#[1,] 13 16 19 22
#[2,] 14 17 20 23
#[3,] 15 18 21 24
#[4,] 0 0 0 0
#[5,] 0 0 0 0
microbenchmark(flodel1(df), add_col_or_row(df), times = 20)
#Unit: milliseconds
# expr min lq median uq max neval
# flodel1(df) 35.69158 54.88014 55.58363 56.40300 58.31250 20
# add_col_or_row(df) 19.87134 38.57792 39.11297 39.58347 44.59873 20
identical("dimnames<-"(flodel1(df), NULL), add_col_or_row(df))
#[1] TRUE