【问题标题】:How can I output residuals from multiple models in a single new data frame using R?如何使用 R 在单个新数据框中输出多个模型的残差?
【发布时间】:2017-03-15 18:57:09
【问题描述】:

我想针对多个不同的因变量为一组静态自变量运行多个回归模型,并将残差输出到一个看起来像...的新文件中。

SampleID     site_residual1    site_residual2    site_residual3
F001         0.003             0.988             0.776
F001         0.002             0.876             0.665
F002         0.134             0.234             0.786
...

我一直在使用以下代码来获取单个剩余输出,但未能成功实现将贯穿我所有站点的循环。

infile = sprintf("/path/siteinput.txt.gz")

infile 看起来像...

SampleID     site1  site2   site3   etc...
F001         0.003  0.988   0.776   etc...
F001         0.002  0.876   0.665   etc...
F002         0.134  0.234   0.786   etc...
...

...

pheno = read.table("/path/pheno_covar.txt", header=T, sep="\t")

现象看起来...

SampleID     indep1 indep2  indep3  chip1   etc...
F001         0.003  0.988   0.776   2       etc...
F001         0.002  0.876   0.665   2       etc...
F002         0.134  0.234   0.786   1       etc...
...

...

residfile = sprintf("/path/test_resid_out.txt")

library(lme4)

beta = read.table(infile, header=T, sep="\t")

merged = merge(beta, pheno, by="SampleID")

site<-merged$site1
chip <- as.factor(merged$chip1)

model1 <- lmer (formula= site ~ indep1 +indep2 + indep3 + (1|chip), data=merged)

print(summary(model1))
print(resid(model1))

site1_resid = resid(model1, na.action=na.exclude)

residout<-(data.frame(SampleID, site1_resid))
write.table(residout, file=residfile, sep="\t", col.names=TRUE, row.names=FALSE, quote=FALSE)

我的输出看起来像......

SampleID    site1_resid
F001        0.0110177454696274
F002        0.0923483180517723
F003        0.103686493563883
F004        -0.106193404096636
F005        -0.124621172636435
....

...

所以,我真的在寻找一种方法来为我的“infile”中的每个站点运行 model1 并将所有残差输出到一个新文件中。另外,我希望列标题包含“站点”的原始名称。我确实有一些缺失的信息(所有协变量都是完整的,但是某些 ID 缺少一些站点)。

任何建议将不胜感激。

【问题讨论】:

  • 也许看看专为这种情况设计的broom 包:cran.r-project.org/web/packages/broom/vignettes/broom.html
  • 感谢您的建议。 Broom 对于向原始数据框添加残差确实很有用,但我真的很想为每个结果变量创建一个带有残差列的新数据框。我在 Broom 包中看不到这个功能,但也许我在某个地方错过了这个功能?

标签: r dataframe lme4 genetics


【解决方案1】:

借助 magrittr 管道 (%&gt;%) 使其更易于阅读(虽然不是必需的):

library(magrittr)
names(beta) %>% 
  setdiff("SampleID") %>% 
  setNames(., .) %>% 
  lapply(function(x) {
    model <- lmer(data = merged, formula = paste(x, "~ indep1 +indep2 + indep3 + (1|chip)"))
    # print(summary(model))
    # print(resid(model))
    resid(model, na.action=na.exclude)
  }) %>% 
  c(list(SampleID = merged$SampleID), .) %>% 
  do.call(what = "data.frame")

(顺便说一句,我担心你有重复的SampleIDs。这是有意的吗?如果是,你确定要SampleIDmerge()吗?你宁愿不要cbind(beta, pheno[, - 1, drop = FALSE]) ?)

【讨论】:

  • SampleID 不应包含重复项,但会产生 1:1 合并。但是,它们在两个文件中的排序方式不同。
  • 谢谢,@a-p-o-m。当我应用您的建议时,我收到以下错误...Error in data.frame(SampleID = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, : arguments imply differing number of rows: 2684, 2676 Calls: %&gt;% ... withVisible -&gt; &lt;Anonymous&gt; -&gt; do.call -&gt; data.frame Execution halted。我认为这来自某些网站的缺失值,但我不清楚为什么na.action=na.exclude 不处理这个问题。欢迎和赞赏任何其他建议。
  • 谢谢,@Apom。我能够在 na.action=na.exclude 进入模型语句而不是 resid 之后让它工作。
猜你喜欢
  • 2021-07-26
  • 2012-09-23
  • 2020-08-01
  • 1970-01-01
  • 2015-12-01
  • 1970-01-01
  • 2018-01-04
  • 1970-01-01
相关资源
最近更新 更多