矩阵和向量中的测试条件
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)。
我想检查这个矩阵 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)。