如何在 R 中的用户定义函数中拟合线性模型;指定响应变量时出现错误非数字参数?

How can I fit a linear model inside a user defined function in R; error non-numeric argument when specifying response variable?

我试图通过在 R 中创建函数来完成重复性任务来整理一些脚本。我重复完成的一项任务是将线性模型拟合到一组数据并根据该线性模型拟合创建预测。我正在处理的数据是来自流的浓度和流量数据,流量始终是解释变量,但响应变量会发生变化,因此我想将其作为函数输入包含在内。但是,当我 运行 函数时,我收到“数学函数的非数字参数”错误。我试过带引号和不带引号,因为 lm() 调用不需要引号,但这会导致分类“找不到对象 'myobject'”。这是一个简单的例子。

更新

flows <- seq(0,7,0.01) 
  dat <- tibble(flow=sample(flows,30),
                parameter1_conc=rnorm(30,15,4),
                parameter2_conc=rnorm(30,50,8))
  
  regr_func <- function(modeldata,parameter,pred_maxflow,pred_flowint) {
    mod <- lm(as.formula(paste('log(', parameter, ') ~ log(', flow, ')')), data=modeldata)
    
    newflow <- data.frame(flow = seq(0, pred_maxflow, pred_flowint))

    preds <<- predict(mod, newdata = newflow,
                       interval = 'prediction')
  }
regr_func(modeldata = dat,
          parameter = 'parameter1_conc',
          pred_maxflow = 20,
          pred_flowint = 0.001)

原始示例错误


flows <- seq(0,7,0.01) 
  dat <- tibble(flow=sample(flows,30),
                parameter1_conc=rnorm(30,15,4),
                parameter1_conc=rnorm(30,50,8))
  
  regr_func <- function(modeldata,parameter,pred_maxflow,pred_flowint) {
    mod <- lm(log(parameter)~log(flow), data = modeldata)
    
    newflow <- data.frame(flow = seq(0, maxflow, flowint))

    preds <<- predict(mod, newdata = newflow,
                       interval = 'prediction')
  }
regr_func(modeldata = dat,
          parameter = 'parameter1_conc',
          pred_maxflow = 20,
          pred_flowint = 0.001)

这里有 3 个问题。最主要的是 lm 公式中的 log(parameter) 不会替换为 parameter 传入的变量。这意味着 lm 实际上是在您的数据中寻找一个名为 parameter 的列,该列不存在。您可以通过创建一个名称替换为的公式来解决此问题。尽管使用字符串执行此操作是执行此操作的最常用方法,但使用 substitute 更有效且更安全。这也允许您传递不带引号的列名。

第二个问题是参数 maxflowflowint 可能应该是 pred_maxflowpred_flowint 以匹配您的函数参数。

第三,使用 <<- 运算符写入调用框架中的变量是不好的做法。 R 用户希望函数不会有这样的副作用,并且知道将函数调用的输出存储到他们控制的变量中。只有在极少数情况下才应在函数内完成。

将所有这些放在一起,我们有:

regr_func <- function(modeldata, parameter, pred_maxflow, pred_flowint) {
    
    f <-  `[[<-`(x ~ log(flow), 2, substitute(log(parameter)))

    mod <- lm(f, data = modeldata)
    
    newflow <- data.frame(flow = seq(0, pred_maxflow, pred_flowint))

    predict(mod, newdata = newflow, interval = 'prediction')
  }

我们会这样调用函数:

preds <- regr_func(modeldata = dat,
          parameter = parameter1_conc,
          pred_maxflow = 20,
          pred_flowint = 0.001)

导致:

head(preds)
#>        fit      lwr      upr
#> 1      Inf      NaN      NaN
#> 2 3.365491 2.188942 4.542041
#> 3 3.312636 2.219223 4.406049
#> 4 3.281717 2.236294 4.327140
#> 5 3.259780 2.248073 4.271488
#> 6 3.242765 2.256998 4.228531

reprex package (v2.0.1)

于 2022-06-03 创建