矩阵和向量中的测试条件

时间:2016-07-08 23:11:49

标签: r if-statement matrix conditional

我想检查这个矩阵 m 如果它是&lt; = 1或&gt; = 10.如果是这样,我想改变另一个向量的值, val < / em>的。如果 val 为“A”,则应将其更改为“B”,反之亦然。如果 val 为“C”,则应将其更改为“D”,反之亦然。如果矩阵 m 中没有&lt; = 1或&gt; = 10,那么它应该返回 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 }

但它似乎很麻烦而且效果不好......

2 个答案:

答案 0 :(得分:2)

我同意Psidom建议使用查找表,但为了正确地向量化解决方案,您需要使用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)。

答案 1 :(得分:0)

您可以创建一个像字典一样的数据框,并在条件满足时帮助您找到相应的val2。与此同时,你不需要分别测试矩阵的每一列,只需要一个D矢量就可以了:

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"