如何从数据框列表的B列计算对应行平均值并生成新数据框?
问题描述
我有一个名为my.list的列表,结构如下:
$S1 Study_ID B C D 1 100 3.4 C1 0.9124000 2 100 1.5 PTA NA 3 200 1.8 C1 0.5571429 4 200 2.1 PTA 0.7849462 5 300 3.2 C1 0.3271900 6 300 1.4 PTA NA 7 400 5.6 C1 0.8248200 8 400 9.3 PTA 0.2847020 $S2 Study_ID B C D 1 100 0.15 C1 0.9124000 2 100 0.70 PTA NA 3 200 0.23 C1 0.5571429 4 200 0.45 PTA 0.7849462 5 300 0.91 C1 0.3271900 6 300 0.78 PTA 0.6492000 7 400 0.65 C1 0.8248200 8 400 0.56 PTA NA
我希望创建一个仅包含列表中对应行B列平均值的数据框,期望输出如下:
Average 1 2.1 2 1.2 3 0.5 4 1.5 5 1.9 6 2.1 7 3.6 8 5.9
可复现数据:
my.list <- structure(list(S1 = structure(list(Study_ID = c(100, 100, 200, 200, 300,300,400,400), B = c(3.4, 1.5, 1.8, 2.1, 3.2, 1.4, 5.6, 9.3), C = c("C1", "PTA", "C1", "PTA", "C1", "PTA","C1", "PTA"), D = c(0.9124, NA, 0.5571429, 0.7849462, 0.32719, NA, 0.82482, 0.284702)), .Names = c("Study_ID", "B", "C", "D"), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6", "7", "8")), S2 = structure(list(Study_ID = c(100, 100, 200, 200, 300,300,400,400), B = c(0.15, 0.7, 0.23, 0.45,0.91, 0.78, 0.65, 0.56), C = c("C1", "PTA", "C1", "PTA", "C1", "PTA", "C1", "PTA"), D = c(0.9124, NA, 0.5571429, 0.7849462, 0.32719,0.6492, 0.82482, NA)), .Names = c("Study_ID", "B", "C","D"), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6", "7", "8"))), .Names = c("S1", "S2"))
解决方案
方法1:基础R实现
直接提取列表中每个数据框的B列,合并成矩阵后按行求均值,最后转为数据框:
# 提取所有B列并合并为矩阵 b_cols <- sapply(my.list, function(x) x$B) # 按行计算平均值,保留一位小数匹配期望输出 average_vals <- rowMeans(b_cols) # 转为指定格式的数据框 result <- data.frame(Average = round(average_vals, 1))
运行后result即为目标输出:
> result Average 1 2.1 2 1.2 3 0.5 4 1.5 5 1.9 6 2.1 7 3.6 8 5.9
方法2:tidyverse风格实现(dplyr + purrr)
若习惯使用tidyverse工具链,可采用以下方式:
library(dplyr) library(purrr) # 提取每个数据框的B列,按行绑定后计算均值 result <- map_dfc(my.list, ~ .x$B) %>% rowwise() %>% mutate(Average = round(mean(c_across(everything())), 1)) %>% select(Average)
方法3:data.table实现(大场景高效)
如果处理的数据集较大,data.table的效率优势更明显:
library(data.table) # 将列表转为data.table对象,合并B列后按行求均值 dt_list <- lapply(my.list, as.data.table) result <- data.table(Average = round(rowMeans(cbind(dt_list[[1]]$B, dt_list[[2]]$B)), 1))
内容的提问来源于stack exchange,提问作者sabc04
相关产品推荐
相关产品推荐

