Arrays 从数组中提取数组
我希望从Arrays 从数组中提取数组,arrays,r,Arrays,R,我希望从数组中提取数组。下面是一个小示例array,my.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.arr
数组
中提取数组
。下面是一个小示例array
,my.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
然后这个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]
我更喜欢base
R
中的解决方案我不确定这是否是最佳答案,但有一种方法是
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
对它们进行循环,并从每个矩阵中选择单独的行,然后将其转换为数据帧。使用从数组中获取元素,我们可以执行以下操作:
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
这将首先构造一个矩阵,在不满足这些列条件(因此c(1,3)索引)的位置使用空值,在满足这些条件的位置使用所需的“行”,然后将
rbind
它们:
Reduce( rbind, apply(my.array2, c(1,3), function(x)if(x[1]==3&x[2]==8){x}) )
[,1] [,2] [,3]
[1,] 3 8 14
[2,] 3 8 7
[3,] 3 8 39
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
谢谢你的回答。所有四个都值得勾选。我想知道您是否可以考虑检查哪个最快。另外,奇怪的是,所有四个似乎都直接转到data.frame,而不创建中间数组。我不知道创建中间数组是否有任何价值。
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