I am trying to find the most efficient/shortest/prettiest solution to multiplying an array with another array. The arrays have different dimensions.
I want to multiply array consumption (dim = c(4, 5, 4)) with the array emissionFactors which is dim = c(1, 5, 4). I want one column value in emissionFactors to affect the whole column in consumption, per dimension. The result should be in the same array format and dimensions as consumption. All necessary code is provided here:
Right now I have a for loop which does the job, but I would like to get rid of it. I tried to use sapply to find a shorter/prettier solution to this problem but I could not get it any better than before.
Can this multiplying be done in shorter form, yet retaining its readability?
# needed vars
decades <- c("2020", "2030", "2040", "2050")
energyTypes <- c("Wood", "Fossils", "Ambient energy", "District heating",
"Electricity")
housingTypes <- c("Detached houses", "Terraced houses",
"Residential blocks of flats", "Service buildings")
# consumption, array to be multiplied
consumption <- array(0, dim = c(4, 5, 4), dimnames = list(housingTypes, energyTypes, decades))
consumption[1, , 1] <- c(11385, 3148, 4958, 2629, 9607)
consumption[2, , 1] <- c(126, 186, 591, 3105, 1385)
consumption[3, , 1] <- c(47, 543, 81, 13635, 1136)
consumption[4, , 1] <- c(874, 3273, 183, 11902, 2106)
consumption[1, , 2] <- c(7447, 1463, 7114, 1645, 7253)
consumption[2, , 2] <- c(80, 0, 824, 2174, 1132)
consumption[3, , 2] <- c(0, 0, 836, 10355, 810)
consumption[4, , 2] <- c(1085, 1460, 953, 9027, 1810)
consumption[1, , 3] <- c(6256, 295, 7880, 639, 5323)
consumption[2, , 3] <- c(73, 0, 878, 1594, 861)
consumption[3, , 3] <- c(0, 0, 1180, 7767, 686)
consumption[4, , 3] <- c(919, 434, 1788, 6870, 1612)
consumption[1, , 4] <- c(4677, 0, 7686, 131, 4199)
consumption[2, , 4] <- c(53, 0, 811, 1221, 650)
consumption[3, , 4] <- c(0, 0, 1179, 6082, 435)
consumption[4, , 4] <- c(435, 3, 2249, 5328, 1260)
# emissionFactors is the array to multiply with
emissionFactors <- array(0, dim = c(1, 5, 4), dimnames = list("kg", energyTypes, decades))
emissionFactors[1, , 1] <- c(0, 263, 0, 160, 65)
emissionFactors[1, , 2] <- c(0, 263, 0, 76, 31)
emissionFactors[1, , 3] <- c(0, 263, 0, 64, 24)
emissionFactors[1, , 4] <- c(0, 263, 0, 45, 12)
# this array will be populated with the multiplied data from consumption * emissionFactors
emissions <- array(0, dim = c(4, 5, 4), dimnames = list(housingTypes, energyTypes, decades))
# Original version of the multiplying, has an undesired for loop
for (decade in 1:length(decades)) {
emissions[, , decade] <-
consumption[, , decade] %*%
diag(emissionFactors[, , decade])
}
# An further attempt, not any prettier. I thought one of the functions in the apply family would do the job but I can't get apply to work the way I would want
emissions2 <- sapply(1:dim(consumption)[3],
function(i)
consumption[, , i] %*%
diag(emissionFactors[, , i]))
emissions2 <- array(emissions2,
c(4, 5, 4),
dimnames = list(housingTypes, energyTypes, decades))
Thank you for any advice you might have.