使用R的lm(),公式对象应作为字符传递? [英] Using lm() of R, a formula object should be passed as character?

查看:198
本文介绍了使用R的lm(),公式对象应作为字符传递?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用lm()发现R的奇怪行为.

I found a strange behavior of R using lm().

基于cars对象,以下功能是在速度30时以局部线性回归绘制拟合的断裂距离.

Based on cars object, following function is to plot fitted breaking distance with a localized linear regression at speed 30.

func1 <- function(fm, spd){
  w <- dnorm(cars$speed - spd, sd=5)
  fit <- lm(formula = as.formula(fm), weights = w, data=cars)
  plot(fitted(fit))
}

func2 <- function(fm, spd){
  w <- dnorm(cars$speed - spd, sd=5)
  fit <- lm(formula = fm, weights = w, data=cars)
  plot(fitted(fit))
}

func1("dist ~ speed", 30)
func2(dist ~ speed, 30)

func1有效.但func2失败并显示以下消息:

func1 works. but func2 fails with following message:

Error in eval(expr, envir, enclos) : object 'w' not found

两个函数之间的唯一区别是func2接收公式类作为参数.

The only difference between two functions is that func2 receives formula class as argument.

使用这种样式的R的lm(),公式对象应该作为字符传递吗?

Using lm() of R in this style, a formula object should be passed as character?

我使用R-3.2.1,RStudio 0.99.467,Windows7对此进行了测试.

I tested this with R-3.2.1, RStudio 0.99.467, Windows7.

推荐答案

非常有趣的情况!这与R的环境特征密切相关. 简而言之,似乎我们不应该将外部定义的公式对象传递给函数.尽管可以通过一些方法进行调整,但是这种行为可能会让我们感到惊讶.

Very interesting case! This relates deeply to the environment feature of R. In short, it seems we should not pass a formula objects defined outside into a function. Although there are some ways to tweak around, the behavior may surprise us.

?formula说:

一个公式对象具有一个关联环境,并且此环境(而不是父环境)被模型使用进行评估所提供的数据参数中找不到的变量.

A formula object has an associated environment, and this environment (rather than the parent environment) is used by model.frame to evaluate variables that are not found in the supplied data argument.

在您的func1中,公式是在函数内部生成的,因此它与函数环境相关联(函数形成一个环境). 因此,当在data中找不到对象时,lm调用将在函数环境中查找它们.这就是在func1中找到w的方式.

In your func1, the formula is generated inside the function, hence it is associated with the function environment (function forms an environment). Hence, when objects are not found in data, the lm call looks for them in the function environment. That is how w is found in func1.

在第二个示例中,公式在函数外部或更确切地说在全局环境中定义.因此,如果在data中找不到,该公式将在全局对象中查找对象.由于全局中没有w,因此它将失败.更糟糕的是,如果全局中还有另一个w,则该w会被混淆并用作权重.

In the second example, the formula is defined outside the function, or more precisely, in the global environment. Hence the formula looks for objects in the global if not found in the data. Since there is no w in the global, it fails. What could be worse is that if you have another w in the global, this w would be confused and used as the weight.

这里是一个突出显示对象搜索顺序的示例. 数据仅具有y.因此,lm调用在其他位置查找x. 但是有两个x.全局定义的公式fm查找x = 1:10,而函数中定义的as.formula(ch)查找x = 10:1. environment告诉您公式与哪个环境关联.

Here is an example that highlights the order of object search. The data only has y. Hence lm call looks for x elsewhere. But there are two x. fm, formula defined in the global finds x = 1:10, while as.formula(ch), defined in the function, finds x = 10:1. environment tells you which environment the formula is associated with.

fun <- function(fm, ch) {
  x <- 10:1
  dat <- data.frame(y = 1:10)

  print(environment(fm))
  print(lm(fm, data = dat))
  cat("<--- refers to x in the global\n") 

  print(environment(as.formula(ch)))
  print(lm(as.formula(ch), data = dat))
  cat("<--- refers to x in the function\n\n")
}

x <- c(1:10)
fun(y ~ x, "y ~ x")

另请参见:环境-高级R .

这篇关于使用R的lm(),公式对象应作为字符传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆