R语言如何对两个tibble按列全组合匹配并相乘对应数值列
问题描述
我有两个tibble对象,构造代码如下:
library(dplyr) my_tib1 <- tibble(feature1 = c("A", "A", "B", "B", "C", "C"), feature2 = c("AA", "BB", "AA", "BB", "AA", "BB"), number = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6)) my_tib2 <- tibble(feature3 = c("TT", "TT", "FF", "FF"), feature2 = c("AA", "BB", "AA", "BB"), number = c(0.6, 0.4, 0.3, 0.8))
两个tibble的结构预览如下:
# A tibble: 6 × 3 feature1 feature2 number <chr> <chr> <dbl> 1 A AA 0.1 2 A BB 0.1 3 B AA 0.3 4 B BB 0.4 5 C AA 0.05 6 C BB 0.05 # A tibble: 4 × 3 feature3 feature2 number <chr> <chr> <dbl> 1 TT AA 0.1 2 TT BB 0.4 3 FF AA 0.3 4 FF BB 0.2
相关前提说明:
- 两个tibble中
feature2的类别完全一致 number列在my_tib1中对应feature1与feature2的每类组合取唯一值,在my_tib2中对应feature2与feature3的每类组合取唯一值- 业务背景:
number列存储的是边际概率,需要将两个边际分布相乘得到联合分布(该计算的前提假设已明确成立)
实现需求
- 生成feature1、feature2、feature3的所有可能组合:共3种feature1取值、2种feature2取值、2种feature3取值,总计12行
- 新增列存储两个表对应number值的乘积
- 最终结果中乘积列的数值总和应为1
预期结果结构示例如下:
# A tibble: 12 × 6 feature1 feature2 feature3 number.x number.y number.mult <chr> <chr> <chr> <dbl> <dbl> <dbl> 1 A AA TT 0.1 0.1 0.01 2 A AA FF 0.1 0.4 0.04 ...
现有方案问题
目前尝试的实现方案如下:
my_tib1 %>% full_join(my_tib2, by = "feature2") %>% mutate(number.mult = number.x*number.y)
该代码虽然返回了12行6列符合结构预期的tibble,但计算得到的number.mult列数值总和不为1,需要正确的实现方法。
解决方案
问题原因
直接按feature2全连接后相乘的写法,算出来的是P(f1,f2) * P(f3,f2),不符合条件独立下的联合概率计算规则。
既然已经明确feature1和feature3在给定feature2时条件独立,三个变量的联合概率公式应该是:P(f1,f2,f3) = P(f1,f2) * P(f3,f2) / P(f2)
之前的代码漏了除以feature2的边际概率P(f2),所以乘出来的列总和不对。
正确实现代码
library(dplyr) # 计算feature2的边际概率P(f2),从任意一个原表按feature2分组求和即可 p_f2 <- my_tib1 %>% group_by(feature2) %>% summarise(p_f2 = sum(number), .groups = "drop") # 连接两个表,关联P(f2)后计算正确的联合概率 result <- my_tib1 %>% full_join(my_tib2, by = "feature2") %>% left_join(p_f2, by = "feature2") %>% mutate(number.mult = number.x * number.y / p_f2) # 验证乘积和是否为1 sum(result$number.mult)
代码说明
p_f2表存储每个feature2取值对应的边际概率,即该feature2分组下所有number的和- 连接后通过
number.x * number.y / p_f2计算得到的联合概率,总和必然为1,符合概率分布要求 - 如果你的
number列存储的是条件概率(即每个feature2分组下number和为1),只需要提前把feature2的边际概率乘入对应表的number列,再执行上述步骤即可。
内容的提问来源于stack exchange,提问作者Tea Tree
相关产品推荐
相关产品推荐

