代码之家  ›  专栏  ›  技术社区  ›  merv

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

  •  4
  • merv  · 技术社区  · 7 年前

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

    我可以这样分割矩阵

    > mat[2:3, 2]
    [1] 25 36
    

    如何将下标存储为变量? my_sub 是,这样

    > mat[my_sub]
    [1] 25 36
    

    A. list

    我知道我可以通过向量寻址访问矩阵,这意味着从 [2:3, 2] c(5, 6) ,但该映射假设了解矩阵形状。如果我只是想 [2:3, 2]

    3 回复  |  直到 7 年前
        1
  •  3
  •   G. Grothendieck    7 年前

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

    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 这似乎过于复杂。

    这种方法没有标量限制。 mat a

    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)
    
        2
  •  1
  •   Rui Barradas    7 年前

    使用 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
    
        3
  •  1
  •   Damiano Fantini    7 年前

    这是一个有趣的问题。这个 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