如何在Tidyverse中对数据框应用outer函数?
用Tidyverse实现组间
outer函数计算汇总结果 你需要针对数据框中的每个分组组合,对指定列应用outer函数并求和,这里我们用Tidyverse工具链来替代双层循环实现需求。
原始循环实现(参考示例)
首先回顾你用双层循环完成的代码:
df <- iris groups = as.character(levels(df$Species)) n <- length(groups) out <- matrix(numeric(n*n), nrow = n, ncol = n) colnames(out) <- groups rownames(out) <- groups for (sp1 in 1:n) { for (sp2 in 1:n) { out[sp1, sp2] <- sum(outer( unlist(subset(df, Species == groups[sp1], Sepal.Length)), unlist(subset(df, Species == groups[sp2], Sepal.Length)), ">" )) } } out
输出结果:
setosa versicolor virginica setosa 1128 139 34 versicolor 2302 1169 479 virginica 2457 1927 1165
Tidyverse实现方案
方法一:直接遍历分组对
library(tidyverse) df <- iris # 生成所有分组的笛卡尔积组合 group_pairs <- expand_grid( sp1 = unique(df$Species), sp2 = unique(df$Species) ) # 对每个分组对计算sum(outer(...)) result_df <- group_pairs %>% mutate( sum_gt = map2_dbl(sp1, sp2, ~{ # 提取两个分组的Sepal.Length数据 x <- df %>% filter(Species == .x) %>% pull(Sepal.Length) y <- df %>% filter(Species == .y) %>% pull(Sepal.Length) # 计算outer比较后的总和 sum(outer(x, y, ">")) }) ) # 转换为与原输出一致的矩阵格式 out_matrix <- result_df %>% pivot_wider(names_from = sp2, values_from = sum_gt) %>% column_to_rownames("sp1") %>% as.matrix() out_matrix
方法二:预存分组数据(更高效)
如果数据量较大,先预存每个分组的数据可以避免重复筛选,提升效率:
library(tidyverse) df <- iris # 按分组存储Sepal.Length向量,生成命名列表 group_data <- df %>% group_by(Species) %>% summarise(data = list(Sepal.Length)) %>% deframe() # 生成分组对并计算结果 result_df <- expand_grid(sp1 = names(group_data), sp2 = names(group_data)) %>% mutate( sum_gt = map2_dbl(sp1, sp2, ~sum(outer(group_data[[.x]], group_data[[.y]], ">"))) ) # 转换为矩阵格式 out_matrix <- result_df %>% pivot_wider(names_from = sp2, values_from = sum_gt) %>% column_to_rownames("sp1") %>% as.matrix() out_matrix
两种方法的输出结果都和原始循环实现完全一致,符合你的需求。
内容的提问来源于stack exchange,提问作者Mankka
相关产品推荐
相关产品推荐

