编辑:我为同样的情况做了一个更简单的例子:
我试图
fn
从模型公式中删除与函数相对应的一项。f<-formula(y~x+fn(z=1)) update(f,.~.-fn(z=1)) #remove the last term y ~ x rm(a) f<-formula(y~x+fn(z=a)) update(f,.~.-fn(z=a)) #works y ~ x #even these work: f<-formula(y~x+fn(z=a));update(f,.~.-fn(z=a)) f<-formula(y~x+fn(a));update(f,.~.-fn(z=a)) f<-formula(y~x+fn(z=a));update(f,.~.-fn(a)) f<-formula(y~x+fn(z=NA)) update(f,.~.-fn(z=NA)) #does not work y ~ x + fn(z = NA) #Probably something to do with environments, as these do not work: update(formula(y~x+fn(z=a)),.~.-fn(z=a)) #works y ~ x > update(formula(y~x+fn(z)),.~.-fn(z=a)) #nope y ~ x + fn(z) > update(formula(y~x+fn(z=a)),.~.-fn(z)) #this neither y ~ x + fn(z = a)
所以
formula.update
(或terms.formula
)中发生了一些我不明白的事情。
旧位;更复杂的例子和一些挖掘里面
formula.update
我试图弄清楚如何更新
formula
对象,以便我可以删除一些与稍后将使用的函数相关的特殊变量。这是一个简单的例子:
f<-formula(y~x+fn(z=1)) vars<-terms(f, c("fn")) rmterm<-attr(vars, "variables")[[1 + attr(vars, "specials")$fn]] rmterm fn(z = 1) update(f, paste(".~.-", deparse(rmterm, width.cutoff = 500L, backtick = TRUE))) y ~ x
到目前为止,一切都按预期工作。但是,如果我
NA
用作该术语的参数,fn
则不会删除:f<-formula(y~x+fn(z=NA)) vars<-terms(f, c("fn")) rmterm<-attr(vars, "variables")[[1 + attr(vars, "specials")$fn]] rmterm fn(z = NA) update(f, paste(".~.-", deparse(rmterm, width.cutoff = 500L, backtick = TRUE))) y ~ x + fn(z = NA)
我想出了一种解决方案来避免这种情况,但是感觉很hacky并且很难概括,因为公式中可以有几个函数包含一个
NA
参数和一些非NA
参数:rmterm[[2]][[1]]<-1 f[[3]][[3]][[2]]<-1 f<-update(f,paste(".~.-",deparse(rmterm, width.cutoff = 500L, backtick = TRUE))) f y ~ x rmterm[[2]][[1]]<-NA #I need the NA back rmterm ## NA becomes NA_real, which probably doesn't matter fn(z = NA_real_)
所以我的问题是为什么不
update.formula
使用NA
's,以及解决这个问题的好方法是什么?
编辑:查看
update.formula
函数内部:update.formula function (old, new, ...) { tmp <- .Internal(update.formula(as.formula(old), as.formula(new))) out <- formula(terms.formula(tmp, simplify = TRUE)) return(out) }
输出
.Internal
:f<-formula(y~x+fn(z = NA)) vars<-terms(f, c("fn")) rmterm<-attr(vars, "variables")[[1 + attr(vars, "specials")$fn]] old<-f new<-paste(". ~ .-", deparse(rmterm, width.cutoff = 500L, backtick = TRUE)) tmp <- .Internal(update.formula(as.formula(old), as.formula(new))) tmp y ~ (x + fn(z = NA)) - fn(z = NA) attr(,".Environment") <environment: R_GlobalEnv>
看起来不错。然后输出
terms.formula
:terms.formula(tmp, simplify = TRUE) y ~ x + fn(z = NA) attr(,"variables") list(y, x, fn(z = NA), fn(z = NA)) attr(,"factors") x fn(z = NA) y 0 0 x 1 0 fn(z = NA) 0 1 fn(z = NA) 0 0 attr(,"term.labels") [1] "x" "fn(z = NA)" attr(,"order") [1] 1 1 attr(,"intercept") [1] 1 attr(,"response") [1] 1 attr(,".Environment") <environment: R_GlobalEnv>
这是不正确的。为了比较,这里是使用时相同的输出
fn(z=1)
:tmp y ~ (x + fn(z = 1)) - fn(z = 1) attr(,".Environment") <environment: R_GlobalEnv> terms.formula(tmp, simplify = TRUE) y ~ x attr(,"variables") list(y, x, fn(z = 1)) attr(,"factors") x y 0 x 1 fn(z = 1) 0 attr(,"term.labels") [1] "x" attr(,"order") [1] 1 attr(,"intercept") [1] 1 attr(,"response") [1] 1 attr(,".Environment") <environment: R_GlobalEnv>
所以看来问题出在内部
terms.formula
函数的某个地方。