我想检查这个矩阵 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 }
但它似乎很麻烦而且效果不好......
答案 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"