Search code examples
rmatrix-multiplicationname-attribute

R: multiply vector by matrix according to names


I've looked at some answers on matrix multiplication (e.g. R: matrix by vector multiplication) but still can't find an answer to my question:

I sell four types of fruit, with per-item prices in this vector:

prices <- c(2.25, 0.42, 0.85, 1.24)
names(prices) <- c("pomegranate", "banana", "apple", "mango")

> prices
pomegranate      banana       apple       mango 
       2.25        0.42        0.85        1.24 

The following matrix gives the number of each item sold on each day of the week:

vv <- c(43, 87, 48,  90,  99,  60,   1,  62,  62, 107,  34,  10, 130,  15,   5, 124, 124, 101,  22, 104)
M <- matrix(vv, nrow=4, ncol=5, dimnames=list(c("banana", "mango", "pomegranate", "apple"), c("M", "Tu", "W", "Th", "F")))

> M
             M Tu   W  Th   F
banana      43 99  62 130 124
mango       87 60 107  15 101
pomegranate 48  1  34   5  22
apple       90 62  10 124 104

Notice that the rows of the matrix are in a different order than the prices vector.

I want to generate a vector of my revenue for each day, i.e.:

> dailyrevenue
     M     Tu      W     Th      F 
310.44 170.93 243.72 189.85 315.22

Is there any quick way to tell R to multiply each price by its corresponding row name? The standard forms of multiplication would assume that each banana costs $2.25 rather than the correct amount, $0.42.

To get what I want, I can use the following code:

OrderOfPrices <- order(match(names(prices), rownames(M))) # per https://stackoverflow.com/a/2117080/8436923
r.prices      <- prices[OrderOfPrices]
dailyrevenue  <- colSums(r.prices * M)

I also wouldn't mind using %*% or crossprod (returning a 1-row matrix rather than a vector) if I could avoid calling the order function.


Solution

  • You can use subsetting to create a prices vector in the correct order:

    pricesm <- prices[rownames(M)]
    pricesm
    #banana       mango pomegranate       apple 
    #  0.42        1.24        2.25        0.85 
    
    rev <- pricesm %*% M
    rev
    #          M     Tu      W     Th      F
    #[1,] 310.44 170.93 243.72 189.85 315.22