如何用lapply/map遍历数据框列表,按gen分组生成统计量?
解决方法
1. 先封装单个数据框的统计函数
不管用lapply还是map,关键是先把单个数据框的统计逻辑做成可复用的函数。下面分两种常用场景给出代码:
用dplyr(tidyverse生态)的版本
如果你平时用dplyr做分组统计,函数可以这么写:
library(dplyr) compute_stats <- function(df) { df %>% group_by(gen) %>% summarise( # 对dCt和RQ两个字段,批量计算指定统计量 across( c(dCt, RQ), list( mean = ~mean(., na.rm = TRUE), sd = ~sd(., na.rm = TRUE), median = ~median(., na.rm = TRUE), iqr = ~IQR(., na.rm = TRUE), min = ~min(., na.rm = TRUE), max = ~max(., na.rm = TRUE) ), .names = "{.col}_{.fn}" # 自动生成列名,比如dCt_mean、RQ_sd ) %>% ungroup() }
base R版本(无需额外包)
如果不想用第三方包,用base R实现的函数:
compute_stats_base <- function(df) { # 定义要计算的统计量函数 stats_funs <- list( mean = function(x) mean(x, na.rm = TRUE), sd = function(x) sd(x, na.rm = TRUE), median = function(x) median(x, na.rm = TRUE), iqr = function(x) IQR(x, na.rm = TRUE), min = function(x) min(x, na.rm = TRUE), max = function(x) max(x, na.rm = TRUE) ) # 按gen分组计算 result <- by(df[, c("dCt", "RQ")], df$gen, function(x) { sapply(stats_funs, function(fun) sapply(x, fun)) }) # 把结果整理成规整的data.frame do.call(rbind, lapply(names(result), function(g) { data.frame(gen = g, t(result[[g]]), row.names = NULL) })) }
2. 遍历列表计算
假设你的数据框列表是list_1 <- list(g1, g2, g3),直接用遍历函数调用上面的统计函数就行:
用purrr::map(tidyverse)
library(purrr) # 得到每个数据框的统计结果列表 stats_list <- map(list_1, compute_stats) # 给结果列表命名(对应原g1/g2/g3),方便区分 names(list_1) <- c("g1", "g2", "g3") stats_list_named <- map(list_1, compute_stats)
用base R的lapply
# base R版本 stats_list_base <- lapply(list_1, compute_stats_base) # 同样可以给列表命名 names(list_1) <- c("g1", "g2", "g3") stats_list_base_named <- lapply(list_1, compute_stats_base)
3. 结果使用说明
遍历后得到的stats_list(或stats_list_base)是一个列表,每个元素对应原列表中一个数据框的统计结果:
- 每个元素是一个data.frame,行是
gen的不同分组,列是类似dCt_mean、RQ_median的命名,清晰对应字段和统计量 - 如果给原
list_1命名,直接用stats_list_named$g1就能查看g1的统计结果
内容的提问来源于stack exchange,提问作者Javier Hernando
相关产品推荐
相关产品推荐

