[英]How to pass a formula as an argument to a function in r?
如何在R中將公式作為參數傳遞?
下面的代碼適用於前兩種情況,但是當我傳遞公式時,會出現錯誤: Error in model.frame.default(formula = formula, weights = weights, na.action = na.omit, : invalid type (closure) for variable '(weights)'
makeModel<-function(formula,weights) {
m <- lm(formula, na.action = na.omit, weights = weights)
return(m);
}
run<-function(t) {
f<-formula(t$y~t$x+t$r)
m <- lm(t$y~t$x+t$r, na.action = na.omit, weights = t$size)
m <- lm(f, na.action = na.omit, weights = t$size)
m <- makeModels(f,t$size)
}
l<-20
x<-seq(0,1,1/l)
y<-sqrt(x)
r=round(runif(n=length(x),min=0,max=.8))
n<-1:(l+1)
size=n/sum(n)
t<-data.frame(x,y,r,n,size)
run(t)
編輯1:此代碼:
makeModel<-function(formula,weights,t) {
print(class(weights))
m <- lm(formula, na.action = na.omit, weights = weights,data=t)
return(m);
}
run<-function(t) {
f<-formula(y~x+r)
f <- as.formula("t$y~t$x+t$r")
m <- lm(y~x+r, na.action = na.omit, weights = t$size,data=t)
m <- lm(f, na.action = na.omit, weights = t$size,data=t)
m <- makeModel(f,t$size,t)
}
生產:
model.frame.default中的錯誤(公式=公式,數據= t,權重=權重,:變量“(權重)”的無效類型(閉包)
編輯2:作品:
makeModel <- function(formula, data) {
# size is looked in data first, which is why this works
m <- lm(formula, na.action = na.omit, weights = size, data = data) # works
#m <- lm(formula, na.action = na.omit, weights = data$size, data = data) # fails!
return(m)
}
r很奇怪!
有誰知道為什么weights = data $ size行失敗?
編輯3:得到了:weights = data $ size起作用。
makeModel<-function(formula,w,data) {
print(class(weights))
m <- lm(formula, na.action = na.omit, weights = size, data = data) # works
m <- lm(formula, na.action = na.omit, weights = data$size, data = data) #works
m <- lm(formula, na.action = na.omit, weights = w,data=data) # fails
return(m);
}
run<-function(data) {
f<-formula(y~x+r)
#f <- as.formula("t$y~t$x+t$r")
m <- lm(y~x+r, na.action = na.omit, weights = data$size,data=data)
m <- lm(f, na.action = na.omit, weights = data$size,data=data)
m <- makeModel(f,data$size,data)
}
最后一個失敗,並顯示以下錯誤:eval(extras,data,env)中的錯誤:找不到對象“ w”
避免分配與轉置函數一致的名為t
的對象。 看回溯率
makeModel<-function(formula,weights) {
m <- lm(formula, na.action = na.omit, weights = weights)
return(m)
}
run<-function(x) {
f<-formula(x$y~x$x+x$r)
m <- lm(x$y~x$x+x$r, na.action = na.omit, weights = x$size)
m <- lm(f, na.action = na.omit, weights = x$size)
m <- makeModel(f,x$size)
}
l<-20
x<-seq(0,1,1/l)
y<-sqrt(x)
r=round(runif(n=length(x),min=0,max=.8))
n<-1:(l+1)
size=n/sum(n)
x<-data.frame(x,y,r,n,size)
run(x)
#R Error in model.frame.default(formula = formula, weights = weights, na.action = na.omit, :
#R invalid type (closure) for variable '(weights)'
traceback()
#R 7: model.frame.default(formula = formula, weights = weights, na.action = na.omit,
#R drop.unused.levels = TRUE)
#R 6: stats::model.frame(formula = formula, weights = weights, na.action = na.omit,
#R drop.unused.levels = TRUE)
#R 5: eval(mf, parent.frame())
#R 4: eval(mf, parent.frame())
#R 3: lm(formula, na.action = na.omit, weights = weights) at #3
#R 2: makeModel(f, x$size) at #5
#R 1: run(t)
現在, debug(model.frame.default)
顯示該行是由於這些行和這一行而出錯的地方。 原因是它調用
eval(list(weights = weights), environment(formula), environment(formula))
並且在run
環境(分配了公式的環境)中未分配weights
對象,因此它產生stats::weights
。 三種解決方案是
makeModel <- function(formula, weights) {
environment(formula) <- environment()
lm(formula, na.action = na.omit, weights = weights)
}
run<-function(x) {
f <- x$y ~ x$x + x$r
makeModel(f, x$size)
}
x1 <- run(x)
makeModel <- function(formula, weights) {
cl <- match.call()
cl[[1L]] <- quote(lm)
cl$na.action <- quote(na.omit)
eval(cl, parent.frame())
}
run<-function(x) {
f <- x$y ~ x$x + x$r
makeModel(f, x$size)
}
x2 <- run(x)
makeModel <- function(formula, weights, x) {
cl <- match.call()
cl[[1]] <- quote(lm)
cl$x <- NULL
cl[c("data", "formula", "na.action")] <-
list(quote(x), formula, quote(na.omit))
eval(cl)
}
run<-function(x) {
f <- y ~ x + r
makeModel(f, size, x)
}
x3 <- run(x)
stopifnot(all.equal(coef(x1), coef(x2)))
stopifnot(all.equal(coef(x1), coef(x3), check.attributes = FALSE))
例如,上面的第一個解決方案意味着
eval(list(weights = weights), environment(formula), environment(formula))
成功,因為在formula
環境中分配了一個weights
對象。 第二種解決方案在run
環境中使用weights = x$size
進行調用,從而成功。 如果您知道weights
參數始終是size
列,那么第三個問題就像RomanLuštrik的答案,盡管他的解決方案比我建議的第三個問題更為清晰。 這里的電話是
eval(list(weights = size), data, environment(formula))
因為size
是data
一列,所以它起作用。
請參閱?as.formula
示例。 您不應從變量名中顯式調用變量。 該公式應該是抽象的,並且lm
將知道您應該從data
提取哪些變量,您應該指定哪些變量。
makeModels <- function(formula, data) {
# size is looked in data first, which is why this works
m <- lm(formula, na.action = na.omit, weights = size, data = data)
return(m)
}
run <- function(t) {
f <- formula(y ~ x + r)
m1 <- lm(formula = f, na.action = na.omit, weights = size, data = t)
m2 <- makeModels(formula = f, data = t)
return(list(m1, m2))
}
l<-20
x<-seq(0,1,1/l)
y<-sqrt(x)
r=round(runif(n = length(x), min = 0, max = 0.8))
n<-1:(l+1)
size=n/sum(n)
t<-data.frame(x,y,r,n,size)
run(t)
[[1]]
Call:
lm(formula = f, data = t, weights = t$size, na.action = na.omit)
Coefficients:
(Intercept) x r
0.327154 0.706553 -0.008167
[[2]]
Call:
lm(formula = formula, data = data, weights = size, na.action = na.omit)
Coefficients:
(Intercept) x r
0.327154 0.706553 -0.008167
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.