矩阵和向量中的测试条件

testing condition in matrix and vector

我想检查这个矩阵 m 是否 <= 1 或 >= 10。如果是这样,我想更改另一个向量的值,val。如果 val 是 "A",则应将其更改为 "B",反之亦然。如果 val 是 "C",则应将其更改为 "D",反之亦然。如果矩阵 m 中没有值 <= 1 或 >= 10,那么它应该 return val

m
     x y
[1,] 2 11
[2,] 4 6
[3,] 5 6
[4,] 0 6
[5,] 2 6

val = "A"

因此输出应该是

out 
"B"

我目前拥有的是以下

x = m[, 1]
y = m[, 2]

x.test = any(x <= 1)
x.test = cbind(x.test, any(x >= 10) )

y.test = any(y <= 1) 
y.test = cbind(y.test, any(y >= 10) ) 

 if (any(x.test)==TRUE || any(y.test)==TRUE && val == 'A')
  { val2 = 'B'
} else if (any(x.test)==TRUE || any(y.test)==TRUE && val == 'B') 
  { val2 = 'A'
} else if (any(x.test)==TRUE || any(y.test)==TRUE && val == 'C') 
  {val2 = 'D'
} else if (any(x.test)==TRUE || any(y.test)==TRUE && val == 'D') 
  {val2 = 'C'
} else { val2 = val }

但是看起来很麻烦,而且效果不好……

您可以创建一个像字典一样的数据框,并在满足条件的情况下帮助您找出对应的 val2。同时,你不需要单独测试矩阵的每一列,就像一个一维向量一样,一条语句就足够了:

dicFrame <- data.frame(val = c("A", "B", "C", "D"), val2 = c("B", "A", "D", "C"), stringsAsFactors = F)

#  val val2
#1   A    B
#2   B    A
#3   C    D
#4   D    C

val = "A"
val2 = if(any(mat >= 10 | mat <= 1)) dicFrame[dicFrame$val == val, 'val2'] else val
val2
# [1] "B"

我同意 Psidom 使用查找的建议 table,但要正确矢量化解决方案,您需要使用 match():

if (any(m<=1L | m>=10L)) map$value[match(val,map$key)] else val;
##  [1] "A" "A" "D" "C" "B" "C" "C" "D" "D" "B"

数据

set.seed(1L);
NV <- 10L; val <- sample(LETTERS[1:4],NV,T);
m <- matrix(c(2L,4L,5L,0L,2L,11L,6L,6L,6L,6L),5L);
map <- data.frame(key=c('A','B','C','D'),value=c('B','A','D','C'),stringsAsFactors=F);

val;
##  [1] "B" "B" "C" "D" "A" "D" "D" "C" "C" "A"
map;
##   key value
## 1   A     B
## 2   B     A
## 3   C     D
## 4   D     C

另请注意,==TRUE 永远不是必需的。如果你已经有一个逻辑值,那么它已经是真的,在这种情况下比较会把它留为真,或者它已经是假的,在这种情况下比较会留它为假(或者它已经是 NA ,在这种情况下,比较会将其保留为 NA)。