【问题标题】:Way to extract data from lm-object before function is applied?在应用函数之前从 lm-object 中提取数据的方法?
【发布时间】:2014-05-20 05:56:49
【问题描述】:

让我直接深入一个例子来说明我的问题:

 rm(list=ls())
 n <- 100
 df <- data.frame(y=rnorm(n), x1=rnorm(n), x2=rnorm(n) )
 fm <- lm(y ~ x1 + poly(x2, 2), data=df)

现在,我想看看以前使用的数据。这几乎可以通过使用

 temp.data <- fm$model

但是,x2 将被拆分为 poly(x2,2),它本身就是一个数据框,因为它包含 x2x2^2 的值。请注意,这里似乎包含x2,但由于多项式使用正交分量,temp.data$x2df$x2 不同。如果您在以下内容之后直观地比较变量,也可以看到这一点:new.dat &lt;- cbind(df, fm$model)

现在,一些问题:

首先,也是最重要的,有没有办法以原始形式从 lm 对象中检索 x2。或者更一般地说,如果某个函数f 已应用于 lm 公式中的某个变量,是否可以从 lm 对象中提取基础变量(无需进行特定于案例的数学运算)?请注意,我知道我可以通过其他方式检索数据,但我想知道我是否可以从 lm-object 本身中提取它。

其次,更笼统地说,既然我没有明确要求model.matrix(fm),为什么我会得到被操纵的数据?这背后的基本哲学是什么?有人知道吗?

第三,head(new.dat) 命令告诉我x2 已被分成两个部分。然而,当我输入View(new.dat) 时,我看到的只有一列。这让我感到困惑和难以置信。如何将两列表示为一列,为什么headView 之间存在差异?如果有人能解释一下,我将非常感激!

如果这些问题太基本,请道歉。在这种情况下,我将不胜感激任何指向相关手册的说明。

提前致谢!

【问题讨论】:

    标签: r lm


    【解决方案1】:

    好问题,但这很难。 fm$model 是一个怪异的数据框,用户难以构建的类型,但 R 有时会在内部生成。查看str(fm$model) 的前几行,它向您展示了它是一个数据框,它的第三个组件是维度为 (100,2) 的 poly 类的对象——即类似于矩阵的东西:

    ## 'data.frame':    100 obs. of  3 variables:
    ##  $ y          : num  -0.5952 -1.9561 1.8467 -0.2782 -0.0278 ...
    ##  $ x1         : num  0.423 -1.539 -0.694 0.254 -0.13 ...
    ##  $ poly(x2, 2): poly [1:100, 1:2] 0.0606 -0.0872 0.0799 -0.1068 -0.0395 ...
    

    如果您仍然在最初调用 lm 的环境中工作,如果使用 data 调用 lm参数,您可以使用eval(getCall(fm)$data) 获取原始数据。如果事情正在传入和传出函数,或者如果有人在环境中的独立对象上使用了lm,那么你可能不走运。遇到麻烦可以试试

    eval(getCall(fm)$data,environment(formula(fm))
    

    但事情很快就开始变得更难了。

    我不完全理解存储处理后的模型框架而不是原始数据的逻辑,但我认为这与线性模型的 terms 对象的构造有关——存储中的每个元素模型框架对应于terms 对象的一个​​元素。我真的不明白因子之间的区别——由model.matrix 后处理成一组虚拟变量列——和转换后的数据(例如log(x))或特殊对象(如多项式或样条基)之间的区别......

    【讨论】:

      【解决方案2】:

      问题是,你有多需要它。如果您查看fm$model$poly 的结构,那么最后您会看到如下内容:

      attr(,"coefs")
      attr(,"coefs")$alpha
      [1] 0.06738858 0.10887048
      
      attr(,"coefs")$norm2
      [1]   1.00000 100.00000  93.96666 155.01387
      

      我想这些系数可用于从 poly 中恢复您的原始数据。请参阅poly 函数的源代码(page(poly) 或在控制台中输入poly)......看起来计算多项式可能是可逆的。但为什么要费心去做呢?我可以想到两个原因:(1)您丢失了原始数据和唯一的方法 恢复它就是这样; (2) 您想了解 R 如何计算正交多项式。

      其次,更笼统地说,因为我没有明确要求 model.matrix(fm),为什么我得到被操纵的数据?什么是 这背后的基本理念是什么?有人知道吗?

      您的意思是,为什么要使用lm 对象保存数据?以防万一,我想。您可以轻松将其关闭:

      fm <- lm(y ~ x1 + poly(x2, 2), data=df, model=FALSE)
      

      或者为什么数据会被“操纵”?即,为什么poly(x2,2) 与数据一起保存,而不是原始的x2。我的理解是你自己要求的。 poly(x2,x) 部分首先被评估然后传递给lm,因此lm 甚至没有原始x2

      编辑 - 以更方便的方式回答下面的评论

      例如,对一些额外的因子变量使用因子(f)确实 不会被翻译成存储在 fm$model 中的数据框。仅有的 实际变量 f 存储在 fm$model 中,而在这个 poly 的情况下,存储了一些转换。这让我很困惑。

      我认为你在这里遗漏了一些东西,poly 和 model 的行为是相同的。

      > df <- data.frame(a=1:5, b=2:6, c=rnorm(5))
      > fm <- lm(c~ a + factor(b), df)
      > fm$model
                 c a factor(b)
      1  0.5397541 1         2
      2  0.9108087 2         3
      3  0.1819442 3         4
      4 -0.9293893 4         5
      5  0.1404305 5         6
      > fm$model$factor
      [1] 2 3 4 5 6
      Levels: 2 3 4 5 6
      Warning message:
      In `$.data.frame`(fm$model, factor) : Name partially matched in data frame
      

      可以看到 fm$model 有 factor(b) 而不是 b,而且 fm$model$factor 确实是一个因子,而不是原来的整数变量。 (警告是因为名称实际上是 factor(b),我使用 factor 来避免输入像 fm$model$'factor(b)' 这样丑陋的东西(用反引号替换单引号)。

      【讨论】:

      • 动机是我正在尝试编写一个小函数,该函数将 lm 对象作为参数并进行一些计算。使用已经存储在 lm-object 中的数据似乎更节省内存,坦率地说,更优雅,这就是我尝试这个的原因。 R在这里的行为让我感到困惑。例如,将factor(f) 用于某些附加因子变量不会转换为存储在fm$model 中的数据框。只有实际变量f 存储在fm$model 中,而在这种情况下poly 存储了一些转换。这让我很困惑。
      • 抱歉回复晚了。当有人编辑他或她的答案时,我没有收到通知,所以我错过了......无论如何,点了!我只是看到原始数据在那里(以因子级别的形式),我确实没有注意到数据结构本身发生了变化。所以,每当一个函数应用于回归中的变量时,fm$model 存储应用函数后的数据,所以原始数据很难以自动方式检索,我猜......无论如何,谢谢你的回答!这确实很有帮助。
      • 剩下的一点仍然令人费解的是head(new.dat)View(new.dat) 显示不同的东西。如果您知道那里可能会发生什么...
      • 看看str(new.dat)——你会发现这不是一个简单的数据框,因为它的一个“列”实际上是一个二维对象(poly类但实际上是一个矩阵一些额外的属性)。看来 RStudio 只是不擅长显示此类数据, head() 是对的, View() 是错误的。比较 df1 &lt;- data.frame(a=1:5, b=matrix(1:10, ncol=2))df2 &lt;- data.frame(a=1:5, b=I(matrix(1:10, ncol=2)))strViewhead -- View(df2) 特别奇怪和误导。
      • 啊,所以它是 RStudio 的东西。谢谢,我没有想到。我认为一些内部的 R 事情正在发生......
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 2016-07-04
      • 1970-01-01
      • 1970-01-01
      • 2020-10-29
      • 2011-05-29
      相关资源
      最近更新 更多