Сравните значения столбца с первой строкой и сохраните исходные значения в R - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть большая (конечно) матрица спектроскопических данных, где каждый столбец представляет различное значение массы, а строки представляют образцы из анализа.Небольшой пример ...

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

Первая строка представляет собой пороговое значение, и для рассмотрения значение выборки должно в 3 раза превышать пороговое значение.Я хочу сравнить первое значение строки со всеми значениями в последующих строках столбца и вернуть значение ячейки, если оно равно>> 3-кратному значению первой строки, а в противном случае заменить ячейку на «0».

Итак, для этих небольших выборочных данных выходная матрица, на которую я бы надеялся, выглядела бы так:

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

Я думаю, что есть способ использовать apply для запуска этого, но мойзнание R не распространяется так далеко (пока)

Следует отметить, что пороговая (первая) строка изначально представляла собой отдельную матрицу 1xn, которая была вставлена ​​в первую строку с помощью InsertRow.Если было бы проще сравнивать матрицу данных с «пороговой» матрицей, а не сравнивать строки внутри матрицы, тем лучше.

Спасибо за помощь в решении этой проблемы!

Ответы [ 4 ]

0 голосов
/ 16 ноября 2018

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
0 голосов
/ 15 ноября 2018

Вы определенно можете использовать 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
0 голосов
/ 16 ноября 2018

Ответ на этот вопрос в значительной степени дан выше, но есть другая альтернатива в случае использования строки порога в качестве отдельной матрицы (или эквивалентного вектора).

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

Предполагая, что 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
0 голосов
/ 15 ноября 2018

Вы можете повторить первый ряд вашей матрицы до того же размера, что и остальные строки.Затем сделайте сравнение, которое дает логическую матрицу.Умножьте это на исходные значения.

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

Тот же принцип можно использовать, если ваши пороговые значения хранятся в отдельной матрице.

...