0

I need to do a subtraction of two objects, but I don't get the expected result

library(matrixStats)
A<-matrix(c(5, 7, 4, 1, 14, 3), nrow=3, ncol=2, byrow=T, 
        dimnames=list(c("Blanco", "Negro", "Rojo"), c("Toyota", "Audi")))

> A
       Toyota Audi
Blanco      5    7
Negro       4    1
Rojo       14    3

mx <- colMaxs(A)

> mx
[1] 14  7

A-mx

           Toyota Audi
Blanco     -9    0
Negro      -3  -13
Rojo        0   -4

What I want is that the maximum number is subtracted with its corresponding column, like this:

          Toyota Audi
Blanco     -9    0
Negro      -10  -6
Rojo        0   -4

The error in in the row "Negro". It's inverted.

Sandipan Dey
  • 21,482
  • 2
  • 51
  • 63
  • Possible duplicate of http://stackoverflow.com/questions/24520720/subtract-a-constant-vector-from-each-row-in-a-matrix-in-r or http://stackoverflow.com/questions/3643555/multiply-rows-of-matrix-by-vector – akrun Jan 27 '17 at 18:50

4 Answers4

3

You can do this with sweep, which, by default subtracts out ("sweeps") values across a margin:

sweep(A, 2, colMaxs(A))
       Toyota Audi
Blanco     -9    0
Negro     -10   -6
Rojo        0   -4

Completely with base R, use, apply instead of colMaxs:

sweep(A, 2, apply(A, 2, max))

This may be a bit slower.


An alternative uses rep to repeat the max values and performs a vectorized operation.

A - rep(colMaxs(A), each=nrow(A))

or

A - rep(apply(A, 2, max), each=nrow(A))
lmo
  • 37,904
  • 9
  • 56
  • 69
3

You need to do:

t(t(A)-mx)
#      Toyota Audi
#Blanco     -9    0
#Negro     -10   -6
#Rojo        0   -4
Sandipan Dey
  • 21,482
  • 2
  • 51
  • 63
3
apply(A, 2, function(x) x - max(x))
#       Toyota Audi
#Blanco     -9    0
#Negro     -10   -6
#Rojo        0   -4
d.b
  • 32,245
  • 6
  • 36
  • 77
1

You can also use an lapply if you want to first turn your matrix into a data.table:

dt <- as.data.table(A)
dt[, (colnames(dt)) := lapply(.SD, function(x) x - max(x)), .SDcols=colnames(dt)]
juliamm2011
  • 136
  • 3