2
  • 編集:同じ状況のもう少し簡単な例を作成しました:

    fnモデル式から関数に対応する項を 1 つ削除しようとしています。

    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)   
    

    これを回避するための1つの解決策を思いつきましたが、非常にハックに感じられ、一般化するのは少し難しいです。式には1つの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、そしてこの問題を回避する良い方法は何でしょうか?


  • 編集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関数のどこかにあるようです。

4

0 に答える 0