将列值与第一行进行比较,并在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