簡體   English   中英

如何在 R 中使用條件 if 更改矩陣條目

[英]How to change matrix entries using conditional if in R

我有這個示例矩陣,我想根據條件if語句用"YES""NO"更改矩陣的條目。

a<-c(5,1,0,3,2,0.6,1.6,7,9,0)
b<-c(11,0,1,18,11,11,0,13,20,10)
c<-c(10,20,0.7,0.8,0.3,0.4,0,0.9,1,1)

MAT<-cbind(a,b,c)
MAT

for (i in 1:nrow(MAT)){
  for (j in 1:ncol(MAT)){
  if (MAT[i,j]>5){
    MAT[i,j]="YES"
    } else {
    MAT[i,j]="NO"
    }
  }
}
print(MAT)

我得到的輸出是這樣的,它是錯誤的。 請幫助告訴我出了什么問題以及如何解決?

      a     b    c   
[1,] "NO"  "NO" "NO"
[2,] "NO"  "NO" "NO"
[3,] "NO"  "NO" "NO"
[4,] "NO"  "NO" "NO"
[5,] "NO"  "NO" "NO"
[6,] "NO"  "NO" "NO"
[7,] "NO"  "NO" "NO"
[8,] "YES" "NO" "NO"
[9,] "YES" "NO" "NO"
[10,] "NO"  "NO" "NO"

這里不需要循環。 只需在調用x>5時使用整個矩陣

ifelse(MAT>5, "YES", "NO")

這將對整個矩陣進行邏輯運算,並輸出一個邏輯矩陣。

您可以使用空括號[]ifelse()的輸出中重新分配VALUES ,同時保持MATSTRUCTURE ,如下所示:

MAT[]<-ifelse(MAT>5, "YES", "NO")

失敗原因

您嘗試失敗的原因來自這一部分:

  if (MAT[i,j]>5){
    MAT[i,j]="YES"
    } else {
    MAT[i,j]="NO"
    }
  }

您應該知道MAT是數字,但是您使用if...else...語句將字符分配給MAT ,這將使MAT轉換為字符矩陣。 在這種情況下,當您運行MAT[i,j] > 5時,您正在將一個字符與一個數值進行比較,例如"18" > 5 ,這將返回一個不想要的FALSE


解決方法

一種解決方法是使用另一個變量來存儲if...else...之后的值,而不是替換MAT中的值:

a <- c(5, 1, 0, 3, 2, 0.6, 1.6, 7, 9, 0)
b <- c(11, 0, 1, 18, 11, 11, 0, 13, 20, 10)
c <- c(10, 20, 0.7, 0.8, 0.3, 0.4, 0, 0.9, 1, 1)

MAT <- cbind(a, b, c)
out <- MAT

for (i in 1:nrow(MAT)) {
  for (j in 1:ncol(MAT)) {
    if (MAT[i, j] > 5) {
      out[i, j] <- "YES"
    } else {
      out[i, j] <- "NO"
    }
  }
}

這樣

> out
      a     b     c
 [1,] "NO"  "YES" "YES"
 [2,] "NO"  "NO"  "YES"
 [3,] "NO"  "NO"  "NO"
 [4,] "NO"  "YES" "NO"
 [5,] "NO"  "YES" "NO"
 [6,] "NO"  "YES" "NO"
 [7,] "NO"  "NO"  "NO"
 [8,] "YES" "YES" "NO"
 [9,] "YES" "YES" "NO"
[10,] "NO"  "YES" "NO"

選擇

這個問題已經有很多答案了,下面是另一個base R選項

> `dim<-`(as.character(factor(MAT > 5, labels = c("NO", "YES"))), dim(MAT))
      [,1]  [,2]  [,3]
 [1,] "NO"  "YES" "YES"
 [2,] "NO"  "NO"  "YES"
 [3,] "NO"  "NO"  "NO"
 [4,] "NO"  "YES" "NO"
 [5,] "NO"  "YES" "NO"
 [6,] "NO"  "YES" "NO"
 [7,] "NO"  "NO"  "NO"
 [8,] "YES" "YES" "NO"
 [9,] "YES" "YES" "NO"
[10,] "NO"  "YES" "NO"

僅使用轉換為數字索引的邏輯矩陣

MAT[] <- c("NO", "YES")[1 + (MAT > 5)]

-輸出

> MAT
      a     b     c    
 [1,] "NO"  "YES" "YES"
 [2,] "NO"  "NO"  "YES"
 [3,] "NO"  "NO"  "NO" 
 [4,] "NO"  "YES" "NO" 
 [5,] "NO"  "YES" "NO" 
 [6,] "NO"  "YES" "NO" 
 [7,] "NO"  "NO"  "NO" 
 [8,] "YES" "YES" "NO" 
 [9,] "YES" "YES" "NO" 
[10,] "NO"  "YES" "NO" 

試試這個:

apply(MAT, 2, function(x) ifelse(x > 5, "YES", "NO"))
      a     b     c    
 [1,] "NO"  "YES" "YES"
 [2,] "NO"  "NO"  "YES"
 [3,] "NO"  "NO"  "NO" 
 [4,] "NO"  "YES" "NO" 
 [5,] "NO"  "YES" "NO" 
 [6,] "NO"  "YES" "NO" 
 [7,] "NO"  "NO"  "NO" 
 [8,] "YES" "YES" "NO" 
 [9,] "YES" "YES" "NO" 
[10,] "NO"  "YES" "NO" 

更新:在 Jean-Claude Arbaut、ThomasIsCoding 和 GuedesBF 的有用說明之后,請注意第一個答案是錯誤的,這里是dplyr的替代方案:

我們可以acrossmatrix更改為tibble類並在操作后重新更改為matrix后使用 cross:

library(tibble)
library(dplyr)

MAT <- MAT %>% 
  as_tibble() %>% 
  mutate(across(everything(), ~ifelse(. > 5, "YES", "NO"))) %>% 
  as.matrix()

第一個答案:警告!

不要使用此代碼

MAT[MAT>5] <- "yes"
MAT[MAT<=5] <- "no"

正如 Jean-Claude Arbaut、ThomasIsCoding 和 GuedesBF 所指出的,它將在第一次分配后強制轉換字符,這可能會導致下游操作出現意外結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM