在R中如何使用dplyr或其他方法对行组合进行除法计算
实现代码
你可以借助dplyr+tidyr的组合完成需求,核心思路是先定义除法规则,再通过分组关联、宽表转换完成所有组合的计算:
首先加载依赖包:
library(dplyr) library(tidyr)
步骤1:定义除法规则
你可以根据自己的需求补充所有treatment组合的计算规则,示例如下:
div_rules <- tibble( # 组合展示名称 treatment_comb = c("A.low/A.high", "A.low/A.mix"), # 分子对应的treatment名 trt_n = c("A.low", "A.low"), # 分子取的列名 col_n = c("sp.1", "sp.1"), # 分母对应的treatment名 trt_d = c("A.high", "A.mix"), # 分母取的列名 col_d = c("sp.1", "sp.2") )
如果需要生成所有treatment的有序两两组合,可以用expand.grid批量生成规则表,再统一配置列对应关系。
步骤2:批量计算结果
result <- df.dummy %>% group_by(site) %>% # 关联除法规则,同site内生成所有待计算组合 crossing(div_rules) %>% # 筛选出匹配分子/分母要求的行 filter(treatment %in% c(trt_n, trt_d)) %>% # 把分子、分母的数值和重复号拆分为独立列 pivot_wider( id_cols = c(site, treatment_comb, trt_n, trt_d, col_n, col_d), names_from = treatment, values_from = c(sp.1, sp.2, rep), values_fn = list ) %>% # 展开重复样本为独立行 unnest(everything()) %>% rowwise() %>% mutate( # 拼接重复号,和示例输出格式一致 rep = paste(get(paste0("rep_", trt_n)), get(paste0("rep_", trt_d)), sep = "/"), # 按规则计算除法,处理除以0返回Inf的情况 value = ifelse(get(paste0(col_d, "_", trt_d)) == 0, Inf, get(paste0(col_n, "_", trt_n)) / get(paste0(col_d, "_", trt_d))) ) %>% ungroup() %>% # 整理输出列顺序 select(site, rep, treatment = treatment_comb, value)
运行后得到的result就是你需要的输出格式。
内容的提问来源于stack exchange,提问作者Rspacer
相关产品推荐
相关产品推荐

