Charly Castro
Charly Castro

Reputation: 21

Subtraction of column by column, by a single element

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.

Upvotes: 0

Views: 151

Answers (4)

juliamm2011
juliamm2011

Reputation: 136

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)]

Upvotes: 1

lmo
lmo

Reputation: 38500

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))

Upvotes: 3

d.b
d.b

Reputation: 32548

apply(A, 2, function(x) x - max(x))
#       Toyota Audi
#Blanco     -9    0
#Negro     -10   -6
#Rojo        0   -4

Upvotes: 3

Sandipan Dey
Sandipan Dey

Reputation: 23101

You need to do:

t(t(A)-mx)
#      Toyota Audi
#Blanco     -9    0
#Negro     -10   -6
#Rojo        0   -4

Upvotes: 3

Related Questions