如何在dplyr分组后将数据框值与对应权重矩阵相乘?
按分组匹配权重矩阵完成自定义函数计算的解决方案
核心解决方案(适用于分组name与矩阵行/列名完全匹配的场景)
你的示例数据中每个site分组的name顺序和d_matrix的行/列名完全一致,因此可以直接在分组summarise中传入全局的权重矩阵,无需额外合并操作:
library(dplyr) library(tibble) # 生成示例数据 set.seed(45) tibble(site = rep(c(LETTERS[1:3]), each = 6), name = rep(c(letters[10:15]), 3), size = runif(18)) %>% arrange(site, name) -> d_tibble # 构建权重矩阵 d_matrix <- matrix(0, 6, 6) diag(d_matrix) <- 1 rownames(d_matrix) <- letters[10:15] colnames(d_matrix) <- letters[10:15] # 自定义计算函数 test_fct <- function(a, b) { p <- a / sum(a) sum(p * (p %*% b)) } # 分组计算 d_tibble %>% group_by(site) %>% summarise(y = test_fct(size, d_matrix), .groups = "drop")
运行后会得到每个site对应的计算结果:
# A tibble: 3 × 2 site y <chr> <dbl> 1 A 0.167 2 B 0.167 3 C 0.167
适配name顺序不一致或缺失的场景
如果实际业务中分组的name可能存在顺序混乱、部分缺失的情况,需要先对每组的size按矩阵行名重新对齐,再传入函数计算:
d_tibble %>% group_by(site) %>% summarise( y = { # 按矩阵行名匹配并排序当前组的size向量 aligned_size <- size[match(rownames(d_matrix), name)] test_fct(aligned_size, d_matrix) }, .groups = "drop" )
这里用match(rownames(d_matrix), name)确保当前组的size顺序完全对应权重矩阵的行/列,即使分组内name顺序乱了也能正确匹配。如果存在缺失值,可以在函数中加入na.rm = TRUE处理:
test_fct <- function(a, b) { p <- a / sum(a, na.rm = TRUE) sum(p * (p %*% b), na.rm = TRUE) }
内容的提问来源于stack exchange,提问作者Stefan
相关产品推荐
相关产品推荐

