我希望使用 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