如何将多维下标存储为R中的变量

时间:2017-09-23 21:51:51

标签: r matrix multidimensional-array slice

假设我有一个矩阵,

while True:
    if a <= b:
        x = random.randint(-300, 301)
        y = random.randint(-300, 301)
        star(size, x, y, color)
        drawer.hideturtle()
        a += 1

        continue
    else:
        break

screen.mainloop()

我可以像这样切割矩阵

mat <- matrix((1:9)^2, 3, 3)

如何将下标存储为变量?> mat[2:3, 2] [1] 25 36 应该是什么,

my_sub

> mat[my_sub] [1] 25 36 获取“无效的下标类型”错误。向量将失去多维度。似乎这样的基本操作没有适合这种用法的原始类型。

我知道我可以通过向量寻址访问矩阵,这意味着从list转换为[2:3, 2],但该映射假定了矩阵形状的知识。如果我只想要c(5, 6)任何矩阵形状(假设它至少是那些尺寸),该怎么办?

3 个答案:

答案 0 :(得分:3)

以下是一些替代方案。它们都推广到更高维数的阵列。

1)矩阵下标如果索引都是标量,除了可能的一个,如问题所示,那么:

mi <- cbind(2:3, 2)
mat[mi]

# test
identical(mat[mi],   mat[2:3, 2])
## [1] TRUE

更高维度:

a <- array(1:24, 2:4)
mi <- cbind(2, 2:3, 3)
a[mi]

# test
identical(a[mi],   a[2, 2:3, 3])
## [1] TRUE

可以使用以下方法扩展它以消除标量限制:

L <- list(2:3, 2:3)
array(mat[as.matrix(do.call(expand.grid, L))], lengths(L))

然而,鉴于(2)也使用do.call,但避免了expand.grid的需要,它似乎不必要地复杂。

2)do.call 此方法没有标量限制。 mata来自上方:

L2 <- list(2:3, 1:2)
do.call("[", c(list(mat), L2))

# test
identical(do.call("[", c(list(mat), L2)),   mat[2:3, 1:2])
## [1] TRUE


L3 <- list(2, 2:3, 3:4)
do.call("[", c(list(a), L3))

# test
identical(do.call("[", c(list(a), L3)),   a[2, 2:3, 3:4])
## [1] TRUE

通过定义:

可以使这更漂亮
`%[%` <- function(x, indexList) do.call("[", c(list(x), indexList))
mat %[% list(2:3, 1:2)
a %[% list(2, 2:3, 3:4)

答案 1 :(得分:1)

使用which参数arr.ind = TRUE

x <- c(25, 36)
inx <- which(mat == x, arr.ind = TRUE)
Warning message:
In mat == x :
  longer object length is not a multiple of shorter object length

mat[inx]
#[1] 25 36

答案 2 :(得分:1)

这是一个有趣的问题。 subset函数实际上可以提供帮助。您不能使用向量或列表直接对矩阵进行子集化,但您可以将索引存储在列表中并使用subset来完成这一操作。

mat <- matrix(1:12, nrow=4)
mat[2:3, 1:2]
# example using subset
subset(mat, subset = 1:nrow(mat) %in% 2:3, select = 1:2)

# double check
identical(mat[2:3, 1:2], 
          subset(mat, subset = 1:nrow(mat) %in% 2:3, select = 1:2))

# TRUE

实际上,如果我们想将行和列索引存储在同一个列表中,我们可以编写一个自定义函数。

cust.subset <- function(mat, dim.list){
  subset(mat, subset = 1:nrow(mat) %in% dim.list[[1]], select = dim.list[[2]])
}

# initialize a list that includes your sub-setting indexes
sbdim <- list(2:3, 1:2)
sbdim
# [[1]]
# [1] 2 3

# [[2]]
# [1] 1 2

# subset using your custom f(x) and your list
cust.subset(mat, sbdim)
#      [,1] [,2]
# [1,]    2    6
# [2,]    3    7