Omry Atia
Omry Atia

Reputation: 2443

vectorially calculating the product of specific columns

I have a matrix with 2 types of column names: those ending with "min" and those ending with "max". for example, the first row and first 6 columns of this matrix can be:

M = matrix(c(0.2, 0.3, 0.5, 0.9, 0.7, 0.6), nrow = 1, ncol = 6)
colnames(M) = c("a_min", "b_min", "c_min", "a_max", "b_max", "c_max")

I would like, for each row of M, to calculate the product of the difference between a_max and a_min, b_max and b_min, and so on for all pairs of columns.

In the example above, the final product is:

(0.9-0.2)*(0.7-0.3)*(0.6-0.5) = 0.028.

How can I do it vectorially for a general 2N columns and P rows?

Upvotes: 0

Views: 35

Answers (2)

Sotos
Sotos

Reputation: 51592

Here is an idea via base R,

Reduce(`*`, lapply(split.default(M, sub('_.*', '', colnames(M))), diff))
#[1] 0.028

If you have multiple rows then, i.e. M <- rbind(M, M)

Reduce(`*`, lapply(split.default(as.data.frame(M), sub('_.*', '', colnames(M))), 
                                                             function(i) abs(i[1] - i[2])))
#  a_min
#1 0.028
#2 0.028

Upvotes: 2

konvas
konvas

Reputation: 14346

To calculate max - min differences, just subtract matrices, e.g.

D <- M[, grep('_max', colnames(M))] - M[, grep('_min', colnames(M))]

(you must check that the columns are ordered correctly or the wrong differences will be calculated).

This will give you a matrix of differences, and now you want to calculate row products. You can do this e.g. with a loop or apply but it's much faster to use rowProds from the matrixstats package

matrixStats::rowProds(D)

Upvotes: 2

Related Questions