Reputation: 23
I have 2 data frames.
M
looks like this:
vec_a vec_b vec_c
A 0.0 0 0
B 0.5 0 0
C 0.5 1 1
Rank
looks like this:
rk_ini
0.3333333
0.3333333
0.3333333
I would like to multiply each values in row 1 of M
by the value in row 1 of Rank
and add these products together. Then do the same for row 2 and then row 3.
Afterwards I would like to concatenate these 3 values into a vector and column bind them on to the second data frame Rank
. This should be repeated with the new values I just calculated to produce 3 more values to bind on to Rank
and repeated whatever number of times I specify in the beginning of my function. Continually binding on a new column on to `Rank.
## iterate t times to get rank
for(i in 1:t) {
for (j in 1:(nrow(M))) {
nr1[j] <- sum((Rank[j, i] * M[j, 1]),
(Rank[j, i] * M[j, 2]),
(Rank[j, i] * M[j, 3]))
nextrank <- c(nextrank, nr1[j])
}
Rank <- cbind(Rank, nextrank[i])
}
Finally here are the results:
rk_ini nextrank[i] nextrank[i] nextrank[i] nextrank[i] nextrank[i]
A 0.3333333 0 0.1666667 0.8333333 0 0
B 0.3333333 0 0.1666667 0.8333333 0 0
C 0.3333333 0 0.1666667 0.8333333 0 0
The results should look more like this:
rk_ini nextrank[i] nextrank[i] nextrank[i] nextrank[i] nextrank[i]
A 0.3333333 0 ....
B 0.3333333 0.1666667 ....
C 0.3333333 0.8333333 ....
With each successive row in the new column being the sum of the products of the previous column multiplied by each value in the corresponding row in M
.
I've tried numerous things and this last does not produce any errors, however it also does not produce the results I am looking for. Any help you can provide in understanding what is going on here will be greatly appreciated.
Thanks!
Upvotes: 2
Views: 145
Reputation: 27388
If I understand correctly, then referring to the data in your post, you want the first element of your new Rank
vector to be the sum of the products the first element of Rank
and the elements of row A
(i.e., sum(M[1, ] * R[1])
), the second element to be the sum of the products of second element of Rank
and the elements of row B
(sum(M[2, ] * R[2])
), and so on. You then want to repeat this calculation with the new Rank
vector taking the place of the original Rank
vector.
If this is the case, then I believe the output of the solution provided by @rnso is accurate.
Here's a vectorised approach that achieves the same, taking advantage of the fact that the nth operation for row i
is equivalent to Rank[i] * rowSums(M)[i]^n
.
M <- matrix(c(0, 0, 0,
0.5, 0, 0,
0.5, 1, 1), ncol=3, byrow=TRUE)
R.init <- c(0.3333333, 0.3333333, 0.3333333)
n <- 5
t(mapply(function(m, r) r * m^(seq_len(n)), rowSums(M), R.init))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0.0000000 0.00000000 0.00000000 0.00000000 0.00000000
# [2,] 0.1666666 0.08333332 0.04166666 0.02083333 0.01041667
# [3,] 0.8333333 2.08333312 5.20833281 13.02083203 32.55208008
Upvotes: 0
Reputation: 121568
Here a vectorized way using matrix multiplication %*%
and replicate
:
M <- as.matrix(M)
R <- as.matrix(R)
mm <- replicate(5,R <<- M%*%R,simplify = TRUE)
[,1] [,2] [,3] [,4] [,5]
[1,] 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
[2,] 0.1666666 0.0000000 0.0000000 0.0000000 0.0000000
[3,] 0.8333332 0.9999999 0.9999999 0.9999999 0.9999999
Where M and R are;
M <- read.table(text='
vec_a vec_b vec_c
A 0.0 0 0
B 0.5 0 0
C 0.5 1 1',header=TRUE)
R <- read.table(text='
rk_ini
0.3333333
0.3333333
0.3333333',header=TRUE)
Upvotes: 3
Reputation: 24535
Try:
> M
vec_a vec_b vec_c
A 0.0 0 0
B 0.5 0 0
C 0.5 1 1
>
> rank
rank
1 0.3333333
2 0.3333333
3 0.3333333
>
> for(i in 1:4){
+ M$rank = rank[,length(rank)]
+ M$new = apply(M, 1, function(x) x[4]*sum(x[1],x[2],x[3]) )
+ rank[,length(rank)+1] = M$new
+ }
> M = M[c(1:3)]
> M
vec_a vec_b vec_c
A 0.0 0 0
B 0.5 0 0
C 0.5 1 1
> print(rank)
rank V2 V3 V4 V5
1 0.3333333 0.0000000 0.00000000 0.00000000 0.00000000
2 0.3333333 0.1666666 0.08333332 0.04166666 0.02083333
3 0.3333333 0.8333333 2.08333313 5.20833281 13.02083203
>
Upvotes: 0
Reputation: 3158
Modify your code as shown:
for(i in 1:t) {
for (j in 1:(nrow(M))) {
nr1[j] <- sum((Rank[j, i] * M[j, 1]), (Rank[j, i] * M[j, 2]), (Rank[j, i] * M[j, 3]))
nextrank <- c(nextrank, nr1[j])
}
Rank <- cbind(Rank, nextrank[i*(1:3)]) **key step**
}
Rank
}
Upvotes: 1