在应用函数之前从lm-object提取数据的方法?

时间:2014-04-07 19:53:07

标签: r lm

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

 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,但由于polynomal使用正交分量,temp.data$x2df$x2不同。如果您在以下之后直观地比较变量,也可以看到这一点:new.dat <- cbind(df, fm$model)

现在,提出一些问题:

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

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

第三,命令head(new.dat)向我显示x2已分为两部分。但是,当我键入View(new.dat)时,我看到的只有一列。这让我感到困惑和令人难以置信。如何将两个列表示为一个,为什么headView之间存在差异?如果有人能解释,我会感激不尽!

如果这些问题太基础,请道歉。在这种情况下,我将非常感谢任何指向相关手册的指示。

提前致谢!

2 个答案:

答案 0 :(得分:5)

好问题,但这很难。 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的环境中工作,而 if lm则使用data参数,您可以使用eval(getCall(fm)$data)来获取原始数据。如果事物被传入和传出函数,或者有人在环境中的独立对象上使用lm,那么你可能会运气不好。如果遇到麻烦,可以尝试

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

但事情开始变得越来越难。

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

答案 1 :(得分:3)

问题是,你需要它多么糟糕。如果你看一下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 $模型中的数据框。只要   实际变量f存储在fm $模型中,而在此   使用poly的情况下,存储了一些转换。这让我很困惑。

我认为你在这里遗漏了一些东西,而且聚合物和模型的行为都是一样的。

> 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 $模型有因子(b)而不是b,而fm $ model $ factor确实是一个因子,而不是原始的整数变量。 (警告是因为名称实际上是factor(b)而我使用factor来避免输入像fm $ model $'factor(b)'那样难看的东西(用反引号替换单引号)。