Вычесть максимум на строку - PullRequest
0 голосов
/ 08 ноября 2018

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

# create matrix
mat <- matrix(rnorm(100),ncol=5,nrow=20)

for(i in 1:nrow(mat)){    #for each row
  row.max <- max( mat[i,] ) #take the maximum of the row
  mat[i,] <- mat[i,] - row.max  #subtract it from the row
}

Я думаю о способе сделать это векторизованным способом, возможно, используя max.col(), однако я не смог придумать что-то до сих пор. Есть идеи?

Спасибо!

Редактировать:

Спасибо за ваши ответы, я принял (безусловно) самое быстрое решение.

Unit: microseconds
    expr      min        lq       mean    median        uq       max neval
    loop 4671.687 4906.6820 5124.78995 5019.7965 5214.5935 12318.986   100
   apply   41.055   47.0430   60.58208   57.0925   71.6320   158.661   100
 rowMaxs    2.139    2.9945    6.21019    5.3465    8.9810    12.402   100
 do.call  111.618  125.0890  154.46904  142.4095  170.2065   422.522   100

Ответы [ 3 ]

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

Опция Base R будет

mat - do.call(pmax, data.frame(mat))

 #           [,1]       [,2]       [,3]       [,4]       [,5]
 #[1,] -2.6565620 -1.9266890 -1.3154080 -0.3471987  0.0000000
 #[2,]  0.0000000 -1.2758157 -0.7681151 -0.7530223 -1.3460720
 #[3,]  0.0000000 -1.8606951 -1.5249890 -1.7938812 -1.9398058
 #[4,] -2.8052871 -0.3951306  0.0000000 -0.9608475 -0.7402124
 #[5,] -0.5303694  0.0000000 -1.6532143 -2.5885875 -1.9538341
 #[6,]  0.0000000 -0.6163414 -1.9542608 -1.6736752 -1.4745702
 #[7,] -1.1494957 -1.0857652  0.0000000 -2.7547954 -1.6820739
 #[8,]  0.0000000 -0.3645636 -0.4770239 -0.7943613 -0.7053540
 #[9,] -0.5493137 -0.8220334  0.0000000 -0.2791556 -0.5086898
 #[10,] -3.3058730  0.0000000 -3.3517838 -2.8817327 -2.9126851

Данные

set.seed(1234)
mat <- matrix(rnorm(100),ncol=5,nrow=10)
0 голосов
/ 08 ноября 2018

Существует пакет с именем qlcMatrix, который имеет функции rowMax;colMax;rowMin;colMin.

Используя этот пакет, вы можете сделать что-то в форме mat - rowMax(mat).

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

Вы можете использовать library(matrixStats) и просто использовать,

mat - rowMaxs(mat)

Как видно из строки matrixStats, это решение молниеносно (сравнительный анализ предоставлен @ hrbrmstr )

## Unit: microseconds
##         expr     min       lq      mean   median       uq      max neval
##     base_mat  33.084  39.3215  46.93637  46.3575  49.6435  116.293   100
##      base_df  80.769  98.9870 116.05771 112.8985 127.6595  201.791   100
##  matrixStats   2.111   3.0170   4.99795   4.9655   5.8415   27.240   100
##    qlcMatrix 716.229 742.2140 834.73351 782.1605 888.4960 1491.734   100
...