代码之家  ›  专栏  ›  技术社区  ›  Ray Tayek

如何将公式作为参数传递给r中的函数?

  •  2
  • Ray Tayek  · 技术社区  · 6 年前

    下面的代码适用于前两种情况,但当我传入公式时,会得到一个错误: 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,权重=权重,: 变量“(weights)”的类型(闭包)无效

    编辑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:Got:weights=data$size to work。

    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)    
    }
    

    2 回复  |  直到 6 年前
        1
  •  0
  •   Roman LuÅ¡trik    6 年前

    ?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  
    
        2
  •  0
  •   Benjamin Christoffersen    6 年前

    避免指定名为 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) this line 是哪里出了问题 these line this line

    eval(list(weights = weights), environment(formula), environment(formula))
    

    而且没有 weights 在中指定的对象 run 环境(分配公式的环境),因此 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))
    

    作为一个例子,上面的第一个解决方案意味着

    因为有一个 重量 在环境中指定的对象 formula 环境 weights = x$size 从而成功。第三个是 Roman LuÅ¡trik's answer 争论总是最重要的 size

    eval(list(weights = size), data, environment(formula))
    

    从那以后就开始工作了 大小 是中的列 data .