Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 如何用with函数调用eval?_R_Environment Variables_Non Standard Evaluation - Fatal编程技术网

R 如何用with函数调用eval?

R 如何用with函数调用eval?,r,environment-variables,non-standard-evaluation,R,Environment Variables,Non Standard Evaluation,有了一个lm对象,我需要根据它的变量(表示为字符向量)创建一个函数。我尝试使用eval和expr的组合来创建f函数,该函数将进一步用于obj和nlm后者的优化 library(tidyverse) df <- drop_na(airquality) model <- lm(Ozone~. - Temp, data = df, x=TRUE, y=TRUE) base_vars <- all.vars(formula(model)[-2]) k <- length(base

有了一个
lm
对象,我需要根据它的变量(表示为字符向量)创建一个函数。我尝试使用
eval
expr
的组合来创建
f
函数,该函数将进一步用于
obj
nlm
后者的优化

library(tidyverse)
df <- drop_na(airquality)
model <- lm(Ozone~. - Temp, data = df, x=TRUE, y=TRUE)
base_vars <- all.vars(formula(model)[-2])
k <- length(base_vars)

f <- function(base_df, x, y, parms) {
  with(base_df, parms[1] + 
         eval(expr(paste(paste(paste0('parms[', 2:(k+1), ']'), base_vars, sep = '*'), collapse = '+'))) + 
         log(parms[k+2] * (x - parms[k+3] ^ 2)))
}
obj <- function(parms, y, x) mean((residuals(model) - f(df, x, y, parms))^2) 
fit <- with(data, nlm(obj, c(0, 0, 0, 0, 0, 0, 0), y = e, x = x))
我相信
eval
环境和
with
函数所隐含的环境之间可能存在冲突,但我不知道为什么。我如何为可变模型创建自定义函数
f

f(型号$x,df$Temp,型号$y,c(0,0,0,0,0,0,0))的预期输出为:

with(base_df, parms[1]+parms[2]*Solar.R+parms[3]*Wind+parms[4]*Temp+parms[5]*Month+
              parms[6]*Day+log(parms[7] * (Temp - parms[8] ^ 2)))
但对于不同的模型,它可能类似于:

with(base_df, 
     parms[1]+parms[2]*var1+parms[3]*var2+log(parms[4]*(var3-parms[5]^2)))

因此,每次调用的变量和参数数量都不同。

R支持在该语言上进行计算,但这不应该是您的第一选择。如果您这样做,它就永远不应该涉及代码的文本处理。这里没有需要在语言上进行计算的情况。我不知道您认为您的尝试会如何工作,但我不知道
expr
函数,我拒绝安装软件包tidyverse及其巨大的依赖关系树

此外,您通常应避免在交互式使用之外使用
。但是这里的问题不是

以下是我将如何做到这一点:

df <- airquality[complete.cases(airquality),]
model <- lm(Ozone~. - Temp, data = df)

f <- function(base_df, x, parms) {

  m <- model.matrix(model, data = base_df)
  k <- ncol(m)
  stopifnot(length(parms) == (k + 2L))
  #I use exp(parms[k+1]) to ensure a positive value within the log
  m %*% parms[seq_len(k)] + log(exp(parms[k + 1L]) * (x - parms[k + 2L] ^ 2))

}

obj <- function(parms, y, x, base_df) mean((residuals(model) - f(base_df, x, parms))^2) 

#some x:
x <- rpois(nrow(df), 10)

fit <- nlm(obj, c(0, 0, 0, 0, 0, 0, 0), x = x, base_df = df)
#works

df我认为@Roland给出了一个很好的答案,涵盖了你的实际问题。我根据问题标题孤立了我认为你特别提出的问题,没有评论这是否是一个好主意。在这个用例中可能没有

但是您所寻找的很可能是
eval\u tidy()
来自
rlang
。我留下了
::
函数表示法,这样就可以清楚地知道这里使用的是什么包

注意,我修复了代码中的一些错误。由于日志的原因,我还在
parms
中使用全1而不是零进行测试

库(rlang)
图书馆(tidyr)
#删除了y,因为它是一个未使用的参数

你能用文字描述一下你想要这个
f
函数做什么吗?也许有一个比处理
eval
更好的方法,我完全不知道你的函数应该返回那里。公式对象?公式应该是什么样子?f函数应该创建一个具有线性部分(使用
model
变量)和非线性部分
log(a*(x-B))
的函数。需要该功能来促进
obj
功能,该功能应在
nlm
优化中使用。(我已经相应地编辑了代码)我还是不明白。你能写下线性部分的公式吗?我想我可以提供一个简单的解决方案,但您的复杂代码尝试并没有提供明确的要求。我已经更新了预期的输出。请看上面的帖子。
expr()
来自rlang,它没有依赖项,它类似于
quote()
,只是它支持准引号。
df <- airquality[complete.cases(airquality),]
model <- lm(Ozone~. - Temp, data = df)

f <- function(base_df, x, parms) {

  m <- model.matrix(model, data = base_df)
  k <- ncol(m)
  stopifnot(length(parms) == (k + 2L))
  #I use exp(parms[k+1]) to ensure a positive value within the log
  m %*% parms[seq_len(k)] + log(exp(parms[k + 1L]) * (x - parms[k + 2L] ^ 2))

}

obj <- function(parms, y, x, base_df) mean((residuals(model) - f(base_df, x, parms))^2) 

#some x:
x <- rpois(nrow(df), 10)

fit <- nlm(obj, c(0, 0, 0, 0, 0, 0, 0), x = x, base_df = df)
#works