问题:如何将for循环的结果转成数据框
熟悉for循环的朋友都知道,一般我们会将分析结果存到向量、数据框或者列表中。而大部分分析结果都是嵌套类型的list,即一个list中套了很多个小list,比如线性回归结果(如下所示 lm.D9)。如果用for 循环做了300个分析,如何提取其中某些个系数值,形成数据框呢?
> lm.D9 <- lm(weight ~ group)
> str(lm.D9)
List of 13
$ coefficients : Named num [1:2] 5.032 -0.371
..- attr(*, "names")= chr [1:2] "(Intercept)" "groupTrt"
$ residuals : Named num [1:20] -0.862 0.548 0.148 1.078 -0.532 ...
..- attr(*, "names")= chr [1:20] "1" "2" "3" "4" ...
$ effects : Named num [1:20] -21.674 -0.83 0.197 1.127 -0.483 ...
..- attr(*, "names")= chr [1:20] "(Intercept)" "groupTrt" "" "" ...
$ rank : int 2
$ fitted.values: Named num [1:20] 5.03 5.03 5.03 5.03 5.03 ...
..- attr(*, "names")= chr [1:20] "1" "2" "3" "4" ...
$ assign : int [1:2] 0 1
# .......
# 线性回归结果list包含13个元素,仅显示上面几个
Method1: 直接提取
直接用$提取目标系数,构建向量,组成数据框。以前,都是用paste函数+notepad替换实现,太麻烦了。
# for循环结果存储于res8中
res8 = list()
for (i in 1:33) {
res8[[i]] <- rma(yi, vi, data = da8[i,])
}
res9 <- data.frame(
da8,
ci.lb = c(res8[[1]]$ci.lb,res8[[2]]$ci.lb,res8[[3]]$ci.lb,res8[[4]]$ci.lb,res8[[5]]$ci.lb,
res8[[6]]$ci.lb,res8[[7]]$ci.lb,res8[[8]]$ci.lb,res8[[9]]$ci.lb,res8[[10]]$ci.lb,
res8[[11]]$ci.lb,res8[[12]]$ci.lb,res8[[13]]$ci.lb,res8[[14]]$ci.lb,res8[[15]]$ci.lb,
res8[[16]]$ci.lb,res8[[17]]$ci.lb,res8[[18]]$ci.lb,res8[[19]]$ci.lb,res8[[20]]$ci.lb,
res8[[21]]$ci.lb,res8[[22]]$ci.lb,res8[[23]]$ci.lb,res8[[24]]$ci.lb,res8[[25]]$ci.lb,
res8[[26]]$ci.lb,res8[[27]]$ci.lb,res8[[28]]$ci.lb,res8[[29]]$ci.lb,res8[[30]]$ci.lb,
res8[[31]]$ci.lb,res8[[32]]$ci.lb,res8[[33]]$ci.lb),
ci.ub = c(
res8[[1]]$ci.ub,res8[[2]]$ci.ub,res8[[3]]$ci.ub,res8[[4]]$ci.ub,res8[[5]]$ci.ub,
res8[[6]]$ci.ub,res8[[7]]$ci.ub,res8[[8]]$ci.ub,res8[[9]]$ci.ub,res8[[10]]$ci.ub,
res8[[11]]$ci.ub,res8[[12]]$ci.ub,res8[[13]]$ci.ub,res8[[14]]$ci.ub,res8[[15]]$ci.ub,
res8[[16]]$ci.ub,res8[[17]]$ci.ub,res8[[18]]$ci.ub,res8[[19]]$ci.ub,res8[[20]]$ci.ub,
res8[[21]]$ci.ub,res8[[22]]$ci.ub,res8[[23]]$ci.ub,res8[[24]]$ci.ub,res8[[25]]$ci.ub,
res8[[26]]$ci.ub,res8[[27]]$ci.ub,res8[[28]]$ci.ub,res8[[29]]$ci.ub,res8[[30]]$ci.ub,
res8[[31]]$ci.ub,res8[[32]]$ci.ub,res8[[33]]$ci.ub),
pval = c(res8[[1]]$pval,res8[[2]]$pval,res8[[3]]$pval,res8[[4]]$pval,res8[[5]]$pval,
res8[[6]]$pval,res8[[7]]$pval,res8[[8]]$pval,res8[[9]]$pval,res8[[10]]$pval,
res8[[11]]$pval,res8[[12]]$pval,res8[[13]]$pval,res8[[14]]$pval,res8[[15]]$pval,
res8[[16]]$pval,res8[[17]]$pval,res8[[18]]$pval,res8[[19]]$pval,res8[[20]]$pval,
res8[[21]]$pval,res8[[22]]$pval,res8[[23]]$pval,res8[[24]]$pval,res8[[25]]$pval,
res8[[26]]$pval,res8[[27]]$pval,res8[[28]]$pval,res8[[29]]$pval,res8[[30]]$pval,
res8[[31]]$pval,res8[[32]]$pval,res8[[33]]$pval))
Method2 : list.select()+list.stack
直到今天,发现一个“神器”R包“rlist”(https://cran.r-project.org/web/packages/rlist/rlist.pdf ),直接对list进行筛选、合并、重组,简直不要太方便。
res10 = data.frame(
da8,
ci.lb = list.stack(list.select(res8, ci.lb)),
ci.ub = list.stack(list.select(res8, ci.ub)),
pvale = list.stack(list.select(res8, pval))
)
# check 一下
> res10 == res9
meanC meanW sdC sdW nC nW yi vi order ci.lb ci.ub pval gp
NO3 TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
NH4 TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
pltR TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
ShannonT TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
CaC TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
SOC TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MAOC TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
POC TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
ACT TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
AMF TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
G- TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
G+ TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MBN TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
MBC TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
SOCpool TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
TN TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Ra TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Rh TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Rs TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
SAP TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
DIN TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
pH TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
ST TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
SM TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
GPP TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
ER TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
NEP TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
others TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Grass TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Richness TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
NPP TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
BNPP TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
ANPP TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Method 3 : rbindlist
data.table包的函数rbindlist,对list进行行合并,但是仅能用于非嵌套的list。rbindlist一般要求list内的元素整齐,元素属性一致,否则会出问题。而rlist包的list相关函数,可以通过list.select对其中元素进行筛选(例如回归系数,pval,r2),进而组合成数据框。
> DT1 = data.table(A=1:3,B=letters[1:3])
> DT2 = data.table(A=4:5,B=letters[4:5])
> l = list(DT1,DT2)
> rbindlist(l)
A B
1: 1 a
2: 2 b
3: 3 c
4: 4 d
5: 5 e
Method 4 : do.call()
> Fdata <- do.call(rbind, Fdata_list)
> head(Fdata)
Chamber_name Rtu_Date Rtu_Time CO_Flux_nmol..m2.s. N2O_Flux_nmol..m2.s. CH4_W_Flux_nmol..m2.s.
1 C1 04/16/2022 13:04:41 0.16623 -0.01465 0
2 C2 04/16/2022 13:10:01 -3.23607 0.00271 0
3 C3 04/16/2022 13:15:21 -4.62974 0.07171 0
4 C4 04/16/2022 13:20:41 -2.18530 0.01458 0
5 C5 04/16/2022 13:26:01 -1.68973 -0.01348 0
6 C6 04/16/2022 13:31:21 -4.22490 0.00642 0