【问题标题】:How do I store lm object in a data frame in R [duplicate]如何将lm对象存储在R中的数据框中[重复]
【发布时间】:2016-02-11 03:57:01
【问题描述】:

我需要将 lm fit 对象存储在数据框中以进行进一步处理(这是必需的,因为我将在数据框中存储大约 200 多个回归)。我无法将 fit 对象存储在数据框中。以下代码产生错误消息:

x = runif(100)
y = 2*x+runif(100)
fit = lm(y ~x)

df = data.frame()
df = rbind(df, c(id="xx1", fitObj=fit))

Error in rbind(deparse.level, ...) : 
  invalid list argument: all variables should have the same length

我想获取 dplyr 的“do”调用返回的数据帧,示例如下:

> tacrSECOutput
Source: local data frame [24 x 5]
Groups: <by row>

                            sector control     id1     fit count
1  Chemicals and Chemical Products       S tSector <S3:lm>  2515
2     Construation and Real Estate       S tSector <S3:lm>   985

请注意,这只是一个示例输出。我想以上述格式创建数据框(适合 lm 对象的列),以便我的其余代码可以在添加的模型上工作。

我做错了什么?非常感谢帮助。

【问题讨论】:

标签: r lm


【解决方案1】:

列表法:

显然基于@Pascal 的想法。不喜欢列表,但在某些情况下它们非常有用。

   set.seed(42)
x <- runif(100)
y <- 2*x+runif(100)
fit1 <- lm(y ~x)

set.seed(123)
x <- runif(100)
y <- 2*x+runif(100)
fit2 <- lm(y ~x)


# manually select model names
model_names = c("fit1","fit2")

# create a list based on models names provided
list_models = lapply(model_names, get)

# set names
names(list_models) = model_names

# check the output
list_models

# $fit1
# 
# Call:
#   lm(formula = y ~ x)
# 
# Coefficients:
#   (Intercept)            x  
#        0.5368       1.9678  
# 
# 
# $fit2
# 
# Call:
#   lm(formula = y ~ x)
# 
# Coefficients:
#   (Intercept)            x  
#        0.5545       1.9192 

鉴于您的工作空间中有很多模型,您唯一需要做的“手动”事情就是提供模型名称的向量(它们是如何存储的),然后使用您可以获得的 get 函数具有这些名称的实际模型对象并将它们保存在列表中。


在创建模型对象时将它们存储在数据集中:

如果您计划在创建模型对象时存储它们,则可以使用dplyrdo 创建数据框。

library(dplyr)

set.seed(42)
x1 = runif(100)
y1 = 2*x+runif(100)

set.seed(123)
x2 <- runif(100)
y2 <- 2*x+runif(100)


model_formulas = c("y1~x1", "y2~x2")

data.frame(model_formulas, stringsAsFactors = F) %>%
  group_by(model_formulas) %>%
  do(model = lm(.$model_formulas))

#     model_formulas   model
#              (chr)   (chr)
#   1          y1~x1 <S3:lm>
#   2          y2~x2 <S3:lm>

这真的取决于允许您构建您提到的 200 多个模型的过程的“组织性”。如果模型依赖于特定数据集的列,您可以通过这种方式构建模型。如果你想基于不同数据集的不同列构建模型,可能是不同的工作空间或不同的模型类型(线性/逻辑回归),它将不起作用。


将现有模型对象存储在数据集中:

实际上,我认为您仍然可以使用与list 方法相同的理念来使用 dplyr。如果模型已经构建,您可以像这样使用它们的名称

library(dplyr)

set.seed(42)
x <- runif(100)
y <- 2*x+runif(100)
fit1 <- lm(y ~x)

set.seed(123)
x <- runif(100)
y <- 2*x+runif(100)
fit2 <- lm(y ~x)


# manually select model names
model_names = c("fit1","fit2")

data.frame(model_names, stringsAsFactors = F) %>%
  group_by(model_names) %>%
  do(model = get(.$model_names))


#   model_names   model
#         (chr)   (chr)
# 1        fit1 <S3:lm>
# 2        fit2 <S3:lm>

【讨论】:

  • 我需要获取一个以 lm obejct 为对象的数据框。请参阅问题中的附加说明。感谢您的方法。
  • 恐怕只有当您计划创建/构建模型并将它们存储在数据框中时,我才能为您提供帮助。不知道如何获取已经构建好的模型并存储在数据框中。
  • 感谢代码,它让我知道了如何去做。请查看@MikeWise 答案的评论,因为他的方法也帮助我找到了解决方案。
  • 我已经更新了我的答案,因此即使模型是预先构建的,您也可以使用dplyr。如果您希望我删除我的答案中使用列表的部分,请告诉我。
  • @AntoniosK 您能否添加一个示例,说明如何从列表中提取模型并将它们放入数据框中?这样,即使模型不是使用 dplyr 生成的,您也可以在模型数据帧上使用 broom。
【解决方案2】:

这似乎有效:

x = runif(100)
y = 2*x+runif(100)
fit = lm(y ~x)

df <- data.frame()
fitvec <- serialize(fit,NULL)
df <- rbind(df, data.frame(id="xx1", fitObj=fitvec))

fit1 <- unserialize( df$fitObj )
print(fit1)

产量:

   Call:
lm(formula = y ~ x)

Coefficients:
(Intercept)            x  
      0.529        1.936  

更新好的,现在更复杂,以便每次拟合一行。

vdf <- data.frame()
fitlist <- list()
niter <- 5

for (i in 1:niter){
  # Create a new model each time
  a <- runif(1)
  b <- runif(1)
  n <- 50*runif(1) + 50
  x <- runif(n)
  y <- a*x + b + rnorm(n,0.1)

  fit <- lm(x~y)

  fitlist[[length(fitlist)+1]] <- serialize(fit,NULL)
}

vdf <- data.frame(id=1:niter)
vdf$fitlist <- fitlist

for (i in 1:niter){
  print(unserialize(vdf$fitlist[[i]]))
}

产量:

Call:
lm(formula = x ~ y)

Coefficients:
(Intercept)            y  
    0.45689      0.07766  


Call:
lm(formula = x ~ y)

Coefficients:
(Intercept)            y  
    0.44922      0.00658  


Call:
lm(formula = x ~ y)

Coefficients:
(Intercept)            y  
    0.41036      0.04522  


Call:
lm(formula = x ~ y)

Coefficients:
(Intercept)            y  
    0.40823      0.07189  


Call:
lm(formula = x ~ y)

Coefficients:
(Intercept)            y  
    0.40818      0.08141  

【讨论】:

  • 这会创建一个包含 11000+ 行的数据框。我需要的是每个模型一个数据框行。请参阅问题中添加的评论。
  • 好的,解决了。现在每行一个模型。
  • 这有什么问题吗?
  • 抱歉有点走神了。让我做一些调整,看看我是否可以使用你的方法来获得我正在寻找的东西。我会在发现后更新评论。
  • 对不起,忘记了……已经完成了。谢谢
猜你喜欢
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
  • 2019-08-23
  • 1970-01-01
  • 1970-01-01
  • 2019-05-11
  • 1970-01-01
  • 2017-12-15
相关资源
最近更新 更多