我在R. 假設我有一個矩陣,我想洗掉一組指定的行和列。這是一個非常有效的示例。
#Create a matrix
MATRIX <- matrix(1:50, nrow = 4, ncol = 5)
rownames(MATRIX) <- c('a', 'b', 'c', 'd')
colnames(MATRIX) <- c('a', 'b', 'c', 'd', 'e')
#Specify rows and columns to remove
REMOVE.ROW <- 3
REMOVE.COL <- 2
#Print the matrix without these rows or columns
MATRIX[-REMOVE.ROW, -REMOVE.COL]
a c d e
a 1 9 13 17
b 2 10 14 18
d 4 12 16 20
但是,當一個或兩個物件REMOVE.ROWorREMOVE.COL為空時,它不會洗掉任何內容(因此回傳原始矩陣),而是回傳一個空矩陣。
#Specify rows and columns to remove
REMOVE.ROW <- integer(0)
REMOVE.COL <- integer(0)
#Print the matrix without these rows or columns
MATRIX[-REMOVE.ROW, -REMOVE.COL]
<0 x 0 matrix>
直觀地說,我本希望洗掉一組空索引會給我留下原始索引集,因此我本希望從這個命令回傳完整的矩陣。出于某種原因,R在這種情況下從矩陣中洗掉所有行和列。據我所知,這似乎是 中的一個錯誤R,但也許有一些我不知道的充分理由。
問題:有人可以解釋為什么R要這樣做嗎?除了使用 if-then 陳述句來處理特殊情況外,是否有任何簡單的調整可以讓R我按照自己的意愿行事?
uj5u.com熱心網友回復:
空物件有一個奇怪的屬性,它們不是NULL,長度為 0 但不是子集化的。一種可能的解決方法是考慮每種可能的組合并使用length(integer0)等于零的屬性。我知道這個解決方案可能并不理想。
is.na(integer(0))
#> logical(0)
is.null(integer(0))
#> [1] FALSE
length(integer(0))
#> [1] 0
integer(0)[[1]]
#> Error in integer(0)[[1]]: subscript out of bounds
integer(0)[[0]]
#> Error in integer(0)[[0]]: attempt to select less than one element in get1index <real>
MATRIX <- matrix(1:50, nrow = 4, ncol = 5)
#> Warning in matrix(1:50, nrow = 4, ncol = 5): data length [50] is not a sub-
#> multiple or multiple of the number of rows [4]
REMOVE.ROW <- integer(0)
REMOVE.COL <- integer(0)
if (all(length(REMOVE.ROW > 0) , length(REMOVE.COL) > 0)) {
MATRIX[-REMOVE.ROW, -REMOVE.COL]
} else {
if (length(REMOVE.ROW) > 0 && length(REMOVE.COL) == 0) {
MATRIX[-REMOVE.ROW, ]
} else {
if (length(REMOVE.ROW) == 0 && length(REMOVE.COL) > 0) {
MATRIX[, -REMOVE.COL]
} else {
MATRIX
}
}
}
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 1 5 9 13 17
#> [2,] 2 6 10 14 18
#> [3,] 3 7 11 15 19
#> [4,] 4 8 12 16 20
由reprex 包(v2.0.1)于 2021 年 11 月 27 日創建
uj5u.com熱心網友回復:
問題是R使用算術否定,而不是設定否定
根據一個有用的評論(給IceCreamToucan 的帽子提示),這似乎是因為使用負索引建立索引矩陣涉及兩步程序,這些程序使用算術否定而不是集合否定來構造。這似乎是操作的標準數學解釋與計算解釋不同的情況之一。
在對一組索引上的矩陣進行索引的數學解釋中,我們將集合否定視為生成一個新集合,該集合由位于原始“樣本空間”中但位于否定集合之外的元素組成。在計算解釋中R,負號的應用是產生負算術值,這些值隨后被解釋為在呼叫矩陣時要洗掉的元素。
在這種情況下發生了什么:對于我們有一組非空索引的通常情況,使用否定符號只是將索引轉換為負值,然后當我們呼叫矩陣時,它會查看除負值以外的所有索引值。
#Specify rows and columns to remove
REMOVE.ROW <- 3
REMOVE.COL <- 2
#See negatives of the removed indices
identical(MATRIX[-REMOVE.ROW, -REMOVE.COL], MATRIX[-3, -2])
[1] TRUE
然而,當我們使用索引的空向量時,該向量的負數仍然是索引的空向量——即,向量integer(0)與其負數相同-integer(0)。因此,當我們嘗試洗掉索引的空向量時,我們實際上是要求在空向量的負數上呼叫矩陣,該空向量仍然是空向量。
#The empty vector is equivalent to its negative
identical(integer(0), -integer(0))
[1] TRUE
#Therefore, calling over these vectors is equivalent
identical(MATRIX[-integer(0), -integer(0)], MATRIX[integer(0), integer(0)])
[1] TRUE
所以,這里的問題是你正在解釋-REMOVE.ROW并且-REMOVE.COL好像他們在使用集合否定,而實際上他們只是取值的初始向量并將它們變成負數(即,將它們乘以負數)。
解決問題:似乎沒有一個標準函式以使用集合否定解釋索引的方式呼叫矩陣,因此您需要使用條件邏輯來為特定情況或自定義函式構建解決方案。這是一個sub.matrix用于洗掉特定行和列的自定義函式,在設定否定的意義上解釋這些行和列。
sub.matrix <- function(x, remove.rows = integer(0), remove.cols = integer(0)) {
#Check that input x is a matrix
if (!('matrix' %in% class(x))) {
stop('This function is only for objects of class \'matrix\'') }
#Create output matrix
R <- length(remove.rows)
C <- length(remove.cols)
if ((R > 0)&(C > 0)) { OUT <- MATRIX[-remove.rows, -remove.cols] }
if ((R == 0)&(C > 0)) { OUT <- MATRIX[, -remove.cols] }
if ((R > 0)&(C == 0)) { OUT <- MATRIX[-remove.rows, ] }
if ((R == 0)&(C == 0)) { OUT <- MATRIX }
#Return the output matrix
OUT }
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/368709.html
下一篇:找出有多少df1在df2中不可用
