【问题标题】:Idiomatic matrix type conversion, say convert Integer (0/1) matrix to boolean matrix惯用矩阵类型转换,例如将整数(0/1)矩阵转换为布尔矩阵
【发布时间】:2019-02-06 18:44:27
【问题描述】:

我有:

 B <- matrix(c(1, 0, 0, 1, 1, 1), 
             nrow=3, 
             ncol=2)

我想要:

 B
      [,1] [,2]
[1,]  TRUE TRUE
[2,] FALSE TRUE
[3,] FALSE TRUE

as.logical(B)给出一维向量。有没有一种惯用的方法来进行矩阵类型转换?

我目前正在罗嗦:

boolVector <- as.logical(B)

m <- nrow(B)
n <- ncol(B)

m <- matrix(boolVector, m , n)
m

【问题讨论】:

    标签: r matrix type-conversion


    【解决方案1】:

    matrix 是带有dim 属性的vector。当我们应用as.logical 时,dim 属性会丢失。可以分配dim&lt;-

    `dim<-`(as.logical(B), dim(B))
    #      [,1] [,2]
    #[1,]  TRUE TRUE
    #[2,] FALSE TRUE
    #[3,] FALSE TRUE
    

    或者另一种选择是创建一个保留属性结构的逻辑条件

    B != 0
    

    或者

    !!B
    

    【讨论】:

      【解决方案2】:

      mode(B) &lt;- "logical""mode&lt;-"(B, "logical")。我们也可以使用storage.mode函数。

      这种解决方法很好有两个原因:

      1. 代码可读性强;
      2. 逻辑通常有效(请参见下面的示例)。

      我在阅读一些带有编译代码的包的源代码时学到了这个技巧。将 R 数据结构传递给 C 或 FORTRAN 函数时,可能需要某种类型的强制转换,他们经常为此使用 modestorage.mode。这两个函数都保留了 R 对象的属性,例如矩阵的“dim”和“dimnames”。

      ## an integer matrix
      A <- matrix(1:4, nrow = 2, dimnames = list(letters[1:2], LETTERS[1:2]))
      #  A B
      #a 1 3
      #b 2 4
      

      "mode<-"(A, "numeric")
      #  A B
      #a 1 3
      #b 2 4
      
      "mode<-"(A, "logical")
      #     A    B
      #a TRUE TRUE
      #b TRUE TRUE
      
      "mode<-"(A, "chracter")
      #  A   B  
      #a "1" "3"
      #b "2" "4"
      
      "mode<-"(A, "complex")
      #     A    B
      #a 1+0i 3+0i
      #b 2+0i 4+0i
      
      str("mode<-"(A, "list"))  ## matrix list
      #List of 4
      # $ : int 1
      # $ : int 2
      # $ : int 3
      # $ : int 4
      # - attr(*, "dim")= int [1:2] 2 2
      # - attr(*, "dimnames")=List of 2
      #  ..$ : chr [1:2] "a" "b"
      #  ..$ : chr [1:2] "A" "B"
      

      请注意,模式更改只能在向量的合法模式之间进行(请参阅?vector)。 R中有许多模式,但向量只允许一些模式。我在my this answer 中介绍了这一点。

      此外,“因子”不是向量(请参阅?vector),因此您不能对因子变量进行模式更改。

      f <- factor(c("a", "b"))
      
      ## this "surprisingly" doesn't work
      mode(f) <- "character"
      #Error in `mode<-`(`*tmp*`, value = "character") : 
      #  invalid to change the storage mode of a factor
      
      ## this also doesn't work
      mode(f) <- "numeric"
      #Error in `mode<-`(`*tmp*`, value = "numeric") : 
      #  invalid to change the storage mode of a factor
      
      ## this does not give any error but also does not change anything
      ## because a factor variable is internally coded as integer with "factor" class
      mode(f) <- "integer"
      f
      #[1] a b
      #Levels: a b
      

      【讨论】:

        猜你喜欢
        • 2021-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-25
        相关资源
        最近更新 更多