Преобразование типа идиоматической матрицы, скажем, преобразование целочисленной (0/1) матрицы в логическую матрицу - PullRequest
0 голосов
/ 31 августа 2018

у меня есть:

 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

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

mode(B) <- "logical" или "mode<-"(B, "logical"). Мы также можем использовать функцию storage.mode.

Этот обходной путь хорош по двум причинам:

  1. код хорошо читается;
  2. логика работает в целом (см. Примеры ниже).

Я научился этому трюку при чтении исходного кода некоторых пакетов со скомпилированным кодом. При передаче R структур данных в функции C или FORTRAN может потребоваться принуждение некоторого типа, и они часто используют mode или storage.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
0 голосов
/ 31 августа 2018

A matrix - это vector с dim атрибутами. Когда мы применяем as.logical, атрибуты dim теряются. Может быть назначен с dim<-

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

Или другой вариант - создать логическое условие, сохраняющее структуру атрибута.

B != 0

или

!!B
...