R 中的 ifelse:如果在 3 个向量上评估的 3 个条件为真,则向所有向量添加一个常量



我希望使用 ifelse 编写一个条件语句,它将同时评估 3 个向量上的 3 个条件。如果任一条件为真,沿着向量,我喜欢为所有三个向量添加一个常量。

下面是一个示例数据集:

a<-c(rep(0,5),rep(1,2))
b<-c(rep(0,6),rep(1,1))
c<-rep(5,7)
(data <- cbind(a,b,c))
     a b c
[1,] 0 0 5
[2,] 0 0 5
[3,] 0 0 5
[4,] 0 0 5
[5,] 0 0 5
[6,] 1 0 5
[7,] 1 1 5

对于每一行,如果 a、b 或 c 为零,我想在值中添加一个常量 k = 0.5。

这是我在条件语句之后的预期数据集:

k <- 0.5
     exp.a exp.b exp.c
[1,]   0.5   0.5   5.5
[2,]   0.5   0.5   5.5
[3,]   0.5   0.5   5.5
[4,]   0.5   0.5   5.5
[5,]   0.5   0.5   5.5
[6,]   1.5   0.5   5.5
[7,]   1.0   1.0   5.0

我尝试了类似以下内容:

(exp.a <- (a + ifelse((a == 0), k, 0)))

上面的代码不会计算向量 b 和 c 如果它们为零,所以这不是我要找的。我如何编写 ifelse 语句,以便在每行的值为零时计算所有 3 个向量,如果其中任何一个为零,则向行中的所有值添加一个常量 k?

谢谢!

这是一种矢量化的可能性。一般来说,如果你只有一个条件(等于0),你实际上并不需要多个ifelse语句,你可以只对等于0的行求和并只分配给它们

indx <- rowSums(data == 0L)
data[indx > 0L, ] <- data[indx > 0L, ] + 0.5
data
#        a   b   c
# [1,] 0.5 0.5 5.5
# [2,] 0.5 0.5 5.5
# [3,] 0.5 0.5 5.5
# [4,] 0.5 0.5 5.5
# [5,] 0.5 0.5 5.5
# [6,] 1.5 0.5 5.5
# [7,] 1.0 1.0 5.0

或者,您可以尝试 data.table 包,它可能可以更有效地节省内存(如果您的矩阵很大)并通过引用更新您的列

library(data.table)
data <- as.data.table(data)
data[rowSums(data == 0L) > 0L, names(data) := lapply(.SD, function(x) x + 0.5)][]
#      a   b   c
# 1: 0.5 0.5 5.5
# 2: 0.5 0.5 5.5
# 3: 0.5 0.5 5.5
# 4: 0.5 0.5 5.5
# 5: 0.5 0.5 5.5
# 6: 1.5 0.5 5.5
# 7: 1.0 1.0 5.0

另一种使用 for 循环的解决方案:

a<-c(rep(0.0,5),rep(1.0,2))
b<-c(rep(0.0,6),rep(1.0,1))
c<-rep(5.0,7)
(data <- cbind(a,b,c))
k <- 0.5
for(i in 1:nrow(data)) {
  if(any(data[i,]==0))
    data[i,] <- data[i,] + k
}
data
       a   b   c
[1,] 0.5 0.5 5.5
[2,] 0.5 0.5 5.5
[3,] 0.5 0.5 5.5
[4,] 0.5 0.5 5.5
[5,] 0.5 0.5 5.5
[6,] 1.5 0.5 5.5
[7,] 1.0 1.0 5.0

最新更新