将列值与第一行进行比较,并在R中保留原始值
我有一个很大的(当然)光谱数据矩阵,每一列代表不同的质量值,每一行代表分析中的样本。一个小例子将列值与第一行进行比较,并在R中保留原始值,r,matrix,compare,R,Matrix,Compare,我有一个很大的(当然)光谱数据矩阵,每一列代表不同的质量值,每一行代表分析中的样本。一个小例子 mydata <- matrix(c(c(1.95,6,1,0),c(1.76,3,2,14),c(3.67,2,1.55,7),c(0.57,3,8,12),c(2.33,3,16,2)),nrow = 4, ncol = 5) rnames <- c("threshold", "S1", "S2", "S3") row.names(mydata)<- rnames #
mydata <- matrix(c(c(1.95,6,1,0),c(1.76,3,2,14),c(3.67,2,1.55,7),c(0.57,3,8,12),c(2.33,3,16,2)),nrow = 4, ncol = 5)
rnames <- c("threshold", "S1", "S2", "S3")
row.names(mydata)<- rnames
# [,1] [,2] [,3] [,4] [,5]
# threshold 1.95 1.76 3.67 0.57 2.33
# S1 6.00 3.00 2.00 3.00 3.00
# S2 1.00 2.00 1.55 8.00 16.00
# S3 0.00 14.00 7.00 12.00 2.00
mydata您可以将矩阵的第一行重复到与重新标记行相同的大小。然后进行比较,得到一个布尔矩阵。将其与原始值相乘
mydata[-1, ] <- mydata[-1, ] * (mydata[-1, ] >= 3 * mydata[rep(1, nrow(mydata) - 1), ])
mydata
# [,1] [,2] [,3] [,4] [,5]
# threshold 1.95 1.76 3.67 0.57 2.33
# S1 6.00 0.00 0.00 3.00 0.00
# S2 0.00 0.00 0.00 8.00 16.00
# S3 0.00 14.00 0.00 12.00 0.00
mydata[-1,]=3*mydata[rep(1,nrow(mydata)-1),]
我的数据
# [,1] [,2] [,3] [,4] [,5]
#阈值1.95 1.76 3.67 0.57 2.33
#S1 6.00 0.00 0.00 3.00 0.00
#S2 0.00 0.00 0.00 8.00 16.00
#S3 0.00 14.00 0.00 12.00 0.00
如果阈值存储在单独的矩阵中,则可以使用相同的原则。您肯定可以使用apply
,只需编写一个函数,其中包含需要应用于每列的逻辑
apply(mydata, 2, function(x) c(x[1], x[-1]*(x[-1] >= 3*x[1])))
> [,1] [,2] [,3] [,4] [,5]
> threshold 1.95 1.76 3.67 0.57 2.33
> S1 6.00 0.00 0.00 3.00 0.00
> S2 0.00 0.00 0.00 8.00 16.00
> S3 0.00 14.00 0.00 12.00 0.00
这个问题在上面已经得到了很好的回答,但在将阈值行作为单独的矩阵(或等效向量)的情况下,这里有另一种选择
sweep
就是为此而做的,而且会很快:
mydata[-1,][sweep(mydata[-1,], 2, mydata[1,], FUN=`/`) < 3] <- 0
mydata
# [,1] [,2] [,3] [,4] [,5]
#threshold 1.95 1.76 3.67 0.57 2.33
#S1 6.00 0.00 0.00 3.00 0.00
#S2 0.00 0.00 0.00 8.00 16.00
#S3 0.00 14.00 0.00 12.00 0.00
谢谢你,杰克!让我困惑的是如何简单地引用第一行;我应该想到x[1],这就把一切都弄清楚了!非常感谢,非常感谢。将您的观察结果纳入我的答案中。谢谢您Henrik,这是一种快速的方法,我喜欢它可以在不将阈值插入数据矩阵的情况下完成。我感谢你的帮助!
threshold <- c(1.95, 1.76, 3.67, 0.57, 2.33)
t(apply(mydata, 1, function(x) ifelse(x < 3*threshold, 0, x)))
# [,1] [,2] [,3] [,4] [,5]
# S1 6 0 0 3 0
# S2 0 0 0 8 16
# S3 0 14 0 12 0
mydata[-1,][sweep(mydata[-1,], 2, mydata[1,], FUN=`/`) < 3] <- 0
mydata
# [,1] [,2] [,3] [,4] [,5]
#threshold 1.95 1.76 3.67 0.57 2.33
#S1 6.00 0.00 0.00 3.00 0.00
#S2 0.00 0.00 0.00 8.00 16.00
#S3 0.00 14.00 0.00 12.00 0.00