来自回归模型的R提取系数使用lapply和sprintf添加字符串并创建数据框

时间:2018-04-20 11:23:04

标签: r dataframe lapply

假设我有多个模型(为方便起见,这里有两个生存和后勤),我只想看看sex估计值。

library(survival)
data(colon)
sn <- Surv(colon$time, colon$status)
fit <- coxph(sn ~ sex + perfor + age, data = colon)
fit1 <- coxph(sn ~ sex + perfor + surg + rx , data = colon)
fit2 <- glm(factor(status) ~ sex + age, data=colon, family=binomial(link = "logit")) 
fit3 <- glm(factor(status) ~ sex + age + nodes, data=colon, family=binomial(link = "logit")) 

我希望以下数据框(df)作为模型名称和估算的最终输出。我还想要dfdf2的修改版本,以便存在分组效果,其中逻辑和生存模型位于不同的列中。他们被订购的事实(2生存后跟2物流)使这更容易。有没有办法将其扩展为更一般的形式并预先定义数据集的布局,假设我们有五个生存/逻辑/ lme模型,所以我们需要5行x 3列类型数据集。

> df
  model                    estimate
1   fit 0.97 (95 % CI 0.85 to 1.10)
2  fit1 0.94 (95 % CI 0.83 to 1.07)
3  fit2 0.97 (95 % CI 0.81 to 1.17)
4  fit3 0.98 (95 % CI 0.81 to 1.18)

以及

> df2
  model_survival                sur_estimate model_logistic           logistic_estimate
1            fit 0.97 (95 % CI 0.85 to 1.10)           fit2 0.97 (95 % CI 0.81 to 1.17)
2           fit1 0.94 (95 % CI 0.83 to 1.07)           fit3 0.98 (95 % CI 0.81 to 1.18)

到目前为止我的尝试: 我使用了lapply,我认为它比for loop好,并且已经完成了很多工作但是我希望在lapply之外的部分是内部的,所以如果我有更多的话它会更自动化模型等见下文。

mylist<-list(fit,fit1,fit2,fit3)
results <- list()
results <- lapply(mylist, function(x) {
  sprintf("%.2f (95 %% CI %.2f to %.2f)",     
          exp(coef(x))["sex"], 
          exp(confint(x)[,1])["sex"], 
          exp(confint(x)[,2])["sex"])
})          
results <- do.call(rbind.data.frame, results)

我可以通过执行以下操作使results看起来像df但我希望在lapply内部这样做,所以我不需要再次获取名称,只需使用它们来自mylist等但results$model<-names(mylist)无效。

colnames(results)[1]<-"estimate"
results$model<-c("fit","fit1","fit2","fit3")

要获得df2我可以做一些长到宽的转换,但是我可以在lapply内预先定义布局和列名称(我知道我可能需要两个单独的lapply - 一个用于dfdf2)。感谢。

1 个答案:

答案 0 :(得分:1)

我们可以将mapstack

一起使用
library(tidyverse)
out <- mget(ls(pattern = "fit\\d*")) %>% 
        map(~sprintf("%.2f (95 %% CI %.2f to %.2f)",     
           exp(coef(.x))["sex"], 
           exp(confint(.x)[,1])["sex"], 
           exp(confint(.x)[,2])["sex"])) %>%
        stack %>%
        select(model = ind, estimate = values)
out
#  model                    estimate
#1   fit 0.97 (95 % CI 0.85 to 1.10)
#2  fit1 0.94 (95 % CI 0.83 to 1.07)
#3  fit2 0.97 (95 % CI 0.81 to 1.17)
#4  fit3 0.98 (95 % CI 0.81 to 1.18)

从'out',我们可以得到第二个输出

library(data.table)#using dcast as it can take multiple value.vars
out %>%
   group_by(group = rep(c("model_survival", "model_logistic"), each = 2)) %>%
   mutate(rn = row_number()) %>%
   as.data.table %>%
   dcast(., rn ~ group, value.var = c('model', 'estimate')) %>% 
   select(-rn)
# model_model_logistic model_model_survival     estimate_model_logistic     estimate_model_survival
#1:                 fit2                  fit 0.97 (95 % CI 0.81 to 1.17) 0.97 (95 % CI 0.85 to 1.10)
#2:                 fit3                 fit1 0.98 (95 % CI 0.81 to 1.18) 0.94 (95 % CI 0.83 to 1.07)