Reputation: 385
I have a problem, where I need to multiply estimated growth rates on base-numbers. The growth rates are stored in a matrix (see data example below) and so are the base-numbers. This itself is easy - the problem is that I have several growth rates for several types of entities behind the base-numbers.
set.seed(1223)
Typ1.rates <- c(1.1,1.2,0.9,1.4)
Typ2.rates <- c(1.4,5.2,1.9,0.4)
g.rates <- t(cbind(Typ1.rates, Typ2.rates))
x <- as.data.frame(matrix(rexp(16, rate=.2), ncol=4)*100)
x$Type <- c(1,1,1,2)
So if the type == 1 for a given row, I want to multiply the first observation with the first observation in Typ1.rates (that is [1,1]) and so on.
This is obvisously easy if I have two types of rates, but if I have 25 types, and large matrices/data frames, this becomes tough to do manually.
Anyone with a good way of doing this?
If any more explanation or data/code is needed, please let me know
EDIT:
Using the seed set above I hope to get the following matrix
V1 V2 V3 V4
1: 141.8580480 1149.9857213 303.4234747 1014.77951629
2: 770.1481988 407.0247813 1219.3383377 156.62140585
3: 554.1117304 983.2339648 239.1584652 50.52442765
4: 584.8300270 1207.7605414 2252.7680594 43.13052390
Upvotes: 2
Views: 106
Reputation: 754
Summary
You can make conditions directly in the dataframe to assign new values like so:
x[x$Type == 1, ]
This will display all the x
values that match ==1
What you need next is to use the rates you have added, so for example :
x[x$Type == 1, ] * Typ1.rates
Final code
Let's say you want to loop through all the types you have and use conditions, like so:
Typ1.rates <- c(1.1,1.2,0.9,1.4)
Typ2.rates <- c(1.4,5.2,1.9,0.4)
g.rates <- t(cbind(Typ1.rates, Typ1.rates))
x <- as.data.frame(matrix(rexp(16, rate=.2), ncol=4)*100)
x$Type <- c(1,1,1,2)
for(i in 1:nrow(g.rates)) {
# We apply the change to the n-1 columns in order to prevent any change to the type column
x[x$Type == i, 1:(ncol(x)-1) ] <- x[x$Type == i, 1:(ncol(x) -1) ] * as.list(g.rates[i,])
}
This should be pretty fast to be executed.
Upvotes: 1
Reputation: 8413
Either using a simple multiplication
set.seed(1223)
g.rates[x[, 5], ] * x[, -5] # Note in your question you missed to include Typ2.rates
Or using data.table
library(data.table)
setDT(x)[, .SD*g.rates[x$Type,] , .SDcols = paste0("V", 1:4)]
# V1 V2 V3 V4
#1 141.8580 1149.9857 303.4235 1014.77952
#2 770.1482 407.0248 1219.3383 156.62141
#3 554.1117 983.2340 239.1585 50.52443
#4 584.8300 1207.7605 2252.7681 43.13052
Upvotes: 5
Reputation: 887531
We can do this in base R
do.call(rbind, Map(`*`, split(x[-5], x$Type),
split(g.rates, row(g.rates))))
# V1 V2 V3 V4
#1.1 141.8580 1341.650 303.4235 869.81101
#1.2 840.1617 373.106 1896.7485 100.68519
#1.3 453.3641 983.234 292.3048 50.52443
#2 584.8300 1207.761 2252.7681 43.13052
Upvotes: 1