Reputation: 740
I have a dataframe which consists of four columns, the two first are used for identifying a user and a product, and the last two are conditional probabilities. My final dataframe looks like this:
id1 id2 p(id2|id1) p(id1|id2)
1 1 1 0.1111111 4.290376e-04
2 1 2 0.22222222 8.286866e-03
3 1 3 0.22222222 2.639876e-04
4 1 4 0.44444444 2.850284e-03
5 2 1 0.09090909 1.644470e-03
6 2 5 0.2727273 3.286420e-04
7 2 6 0.4545455 1.002740e-03
8 2 3 0.1818182 1.738019e-05
and with many more users coming after. As you can see, we can have more than one different value for id2 belonging to the same id1. I want to find the probability of getting a certain id2, given that a user already has some id2, i.e. I am interested in finding
p(id2 = x | id2 = y) = sum_id1 ( p(id2 = x | id1 ) * p(id1 | id2 = y) )
and construct it as a matrix for all x and y. In this case we have 6 different id2, so the resulting matrix should look something like this
1 2 3 4 5 6
1 NA 0.0009207628 3.091197e-05 .... .... ....
2 9.534169e-05 NA ...
3 0.0003943363 ...
4 ...
5 ...
6 ...
We get the element (1,2) as
p(id2=1 | id2 = 2) = p(id2 = 1 | id1 = 1) * p(id1 = 1 | id2 = 2)
= 0.1111111*8.286866e-03 = 0.0009207628.
For element (1,3) we get
p(id2 = 1 | id2 = 3) = p(id2 = 1 | id1 = 1) * p(id1 = 1 | id2 = 3)
+ p(id2 = 1 | id1 = 2) * p(id1 = 2 | id2 = 3)
= 0.1111111 * 2.639876e-04 + 0.09090909 * 1.738019e-05 = 3.091197e-05
I hope it is clear what I want to accomplish. Does anyone have any idea how I can construct this matrix in R?
Thanks in advance
Upvotes: 2
Views: 388
Reputation: 2826
It's not pretty, but I think this works:
vec1 = c(0.1111111, 0.22222222, 0.22222222, 0.44444444, 0.09090909,
0.2727273, 0.4545455, 0.1818182)
vec2 = c(4.290376e-04, 8.286866e-03, 2.639876e-04, 2.850284e-03,
1.644470e-03, 3.286420e-04, 1.002740e-03, 1.738019e-05)
df <- data.frame(id1 = rep(c(1, 2), each = 4),
id2 = c(seq.int(4), 1, 5, 6, 3),
p.id2.id1 = vec1,
p.id1.id2 = vec2)
> df
## id1 id2 p.id2.id1 p.id1.id2
## 1 1 1 0.11111110 4.290376e-04
## 2 1 2 0.22222222 8.286866e-03
## 3 1 3 0.22222222 2.639876e-04
## 4 1 4 0.44444444 2.850284e-03
## 5 2 1 0.09090909 1.644470e-03
## 6 2 5 0.27272730 3.286420e-04
## 7 2 6 0.45454550 1.002740e-03
## 8 2 3 0.18181820 1.738019e-05
mat = matrix(NA, nrow = length(unique(df$id2)), ncol = length(unique(df$id2)))
for (i in 1:length(unique(df$id2))) {
for (j in 1:length(unique(df$id2))) {
if (i != j) {
val = 0
for (k in 1:length(unique(df$id1))) {
if (length(df$p.id2.id1[df$id1 == k & df$id2 == i]) > 0 &
length(df$p.id2.id1[df$id1 == k & df$id2 == j]) > 0) {
val <-val + df$p.id2.id1[df$id1 == k & df$id2 == i] *
df$p.id1.id2[df$id1 == k & df$id2 == j]
}
}
mat[i, j] <- val
}
}
}
Here's the result:
> mat
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] NA 0.0009207628 3.091197e-05 0.0003166982 2.987655e-05 9.115818e-05
## [2,] 9.534169e-05 NA 5.866391e-05 0.0006333964 0.000000e+00 0.000000e+00
## [3,] 3.943363e-04 0.0018415258 NA 0.0006333964 5.975310e-05 1.823164e-04
## [4,] 1.906834e-04 0.0036830515 1.173278e-04 NA 0.000000e+00 0.000000e+00
## [5,] 4.484919e-04 0.0000000000 4.740052e-06 0.0000000000 NA 2.734746e-04
## [6,] 7.474864e-04 0.0000000000 7.900087e-06 0.0000000000 1.493827e-04 NA
Upvotes: 1