简体   繁体   English

将列值与第一行进行比较,并保留R中的原始值

[英]Compare column values against first row and retain original values in R

I have a large (of course) matrix of spectroscopic data, with each column representing a different mass value, and the rows representing samples from the analysis. 我有一个很大的(当然)光谱数据矩阵,每一列代表一个不同的质量值,行代表来自分析的样品。 A small example... 一个小例子

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

The first row represents a threshold value, and to be considered, the sample value must be 3x the threshold. 第一行代表阈值,要考虑的是,样本值必须是阈值的3倍。 I want to compare the first row value against all values in the subsequent rows within the column, and return the cell value if it is =>3x the first row value, and replace the cell with a "0" otherwise. 我想将第一行值与该列中后续行中的所有值进行比较,如果单元格值=> 3x第一行值,则返回该单元格值,否则将其替换为“ 0”。

So, for that small sample data, the output matrix I would hope to achieve would look like: 因此,对于少量样本数据,我希望实现的输出矩阵如下所示:

mydata2 <- matrix(c(c(1.95,6,0,0),c(1.76,0,0,14),c(3.67,0,0,0),c(0.57,3,8,12),c(2.33,0,16,0)),nrow = 4, ncol = 5)
row.names(mydata2) <- rnames

#           [,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

I'm thinking there is a way to use apply to run this, but my knowledge of R does not extend that far (yet). 我在想有一种方法可以使用apply来运行它,但是我对R的了解还没有扩展到这个程度。

I should note that the threshold (first) row was initially a separate 1xn matrix, which was inserted into the first row using InsertRow . 我应该注意,阈值(第一)行最初是一个单独的1xn矩阵,该矩阵使用InsertRow插入第一行。 If it would be easier to compare the data matrix against a 'threshold' matrix, rather than comparing rows intra-matrix, all the better. 如果将数据矩阵与“阈值”矩阵进行比较而不是比较矩阵内的行,则更好。

Thank you for your help in solving this! 多谢您协助解决此问题!

You can repeat the first row of your matrix to the same size as the remainding rows. 您可以将矩阵的第一行重复到与其余行相同的大小。 Then do the comparison, which gives a boolean matrix. 然后进行比较,得到一个布尔矩阵。 Multiply this with the original values. 将此乘以原始值。

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

The same principle could be used if your thresholds are stored in a separate matrix. 如果您的阈值存储在单独的矩阵中,则可以使用相同的原理。

sweep is made for this, and will be quick: 为此,将进行快速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

You definitely can use apply , and you just need to write a function with the logic you need to apply over each column. 您绝对可以使用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

The question's pretty much answered above but here's another alternative in case of having the threshold row as a separate matrix (or equivalent vector). 上面已经回答了很多问题,但是在将阈值行作为单独的矩阵(或等效向量)的情况下,这是另一种选择。

threshold <- c(1.95, 1.76, 3.67, 0.57, 2.33)   

Assuming mydata is the original matrix without the threshold row: 假设mydata是没有threshold行的原始矩阵:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM