从数组中提取数组

时间:2019-03-22 01:15:37

标签: arrays r

我希望从array中提取一个array。这是一个小示例arraymy.array2

x = cbind(1:5, 6:10, 12:16)
y = cbind(c(11,3,12,14,15), c(16,8,15,17,20), 6:10)
z = cbind(c(21,21,22,3,25), c(26,28,25,8,20), 36:40)

my.array  <- array(c(x, y), dim = c(5, 3, 2))
my.array2 <- array(c(my.array, z), dim = c(5, 3, 3))
my.array2
, , 1

     [,1] [,2] [,3]
[1,]    1    6   12
[2,]    2    7   13
[3,]    3    8   14
[4,]    4    9   15
[5,]    5   10   16

, , 2

     [,1] [,2] [,3]
[1,]   11   16    6
[2,]    3    8    7
[3,]   12   15    8
[4,]   14   17    9
[5,]   15   20   10

, , 3

     [,1] [,2] [,3]
[1,]   21   26   36
[2,]   21   28   37
[3,]   22   25   38
[4,]    3    8   39
[5,]   25   20   40

我希望提取第一列为3而第二列为8的行,从而得到以下array

, , 1

     [,1] [,2] [,3]
[1,]    3    8   14

, , 2

     [,1] [,2] [,3]
[1,]    3    8    7

, , 3

     [,1] [,2] [,3]
[1,]    3    8   39

然后是这个data.frame

     [,1] [,2] [,3]
[1,]    3    8   14
[2,]    3    8    7
[3,]    3    8   39

以下是几次失败的尝试:

my.array2[my.array2[,1,] == 3 & my.array2[,2,] == 8,,]

my.array2[my.array2[,1,] == 3 & my.array2[,2,] == 8,my.array2[,1,] == 3 & my.array2[,2,] == 8,my.array2[,1,] == 3 & my.array2[,2,] == 8]

我希望在基础R中使用一个解决方案。

4 个答案:

答案 0 :(得分:3)

使用R: extract matrix from array, using a matrix of indices从数组中获取元素,我们可以执行以下操作:

df = apply(my.array2, 2, as.vector)
# Select rows which meet criteria
df = data.frame(df[df[,1] == 3 & df[,2] == 8, ])
> df
  X1 X2 X3
1  3  8 14
2  3  8  7
3  3  8 39

答案 1 :(得分:2)

这将首先在不满足这些列条件(因此满足c(1,3)索引的位置,以及满足它们的所需“行”)的位置构造一个带有NULL的矩阵,然后它将{{1 }}他们:

rbind

答案 2 :(得分:2)

1):该解决方案不使用apply或迭代应用其他函数的函数。

使用aperm排列数组的索引,以使第二维为最后,将其重构为具有dim(my.array2)[2]列的矩阵,将其转换为数据框并将其子集化为所需的行。一个简单的声明就是这样:

subset(as.data.frame(matrix(aperm(my.array2, c(1, 3, 2)),, dim(my.array2)[2])), 
   V1 == 3 & V2 == 8)

给予:

   V1 V2 V3
3   3  8 14
7   3  8  7
14  3  8 39

2)如果对尺寸大小进行硬编码不是问题,我们可以通过将dim(my.array2)[2]替换为3来略微缩短此时间。

3)我们也可以使用这样的管道来表达这一点:

library(dplyr)

my.array2 %>%
  aperm(c(1, 3, 2)) %>%
  matrix(ncol = dim(.)[3]) %>%
  as.data.frame %>%
  filter(V1 == 3 & V2 == 8)
##   V1 V2 V3
## 1  3  8 14
## 2  3  8  7
## 3  3  8 39

答案 3 :(得分:1)

我不确定这是否是最佳答案,但是一种方法是

data.frame(t(mapply(function(x, y) my.array2[y, , x], 1:dim(my.array2)[3], 
          data.frame(my.array2[, 1,] == 3 & my.array2[, 2,] == 8))))

#  X1 X2 X3
#1  3  8 14
#2  3  8  7
#3  3  8 39

我们首先检查第一行中有3行,第二行中有8行

my.array2[, 1,] == 3 & my.array2[, 2,] == 8

#       [,1]  [,2]  [,3]
#[1,] FALSE FALSE FALSE
#[2,] FALSE  TRUE FALSE
#[3,]  TRUE FALSE FALSE
#[4,] FALSE FALSE  TRUE
#[5,] FALSE FALSE FALSE

现在我们应该从这里得到答案,因为这表明我们要从第一矩阵中选择第三行,从第二矩阵中选择第二行,从第三矩阵中选择第四行,但是要从每个矩阵中选择那些单独的行,我们需要循环使用mapply覆盖它们,然后从每个矩阵中选择单独的行,然后将其转换为数据框。