如何将以下 "poly" 输出转换为可在 Excel 中使用的函数?

How do I convert the following "poly" output to a function useable in Excel?

我使用以下代码在 R 中进行了线性回归:

model <- lm(z~poly(x3,x4, degree=2,raw=TRUE), MyData)

输出是这样的:

(Intercept)
0.1742518
poly(x3, x4, degree = 2, raw = TRUE)2.0
-1.130082
poly(x3, x4, degree = 2, raw = TRUE)1.1
-17.35482
...

有什么方法可以自动将上面的代码转换成这样吗?

z ~ 0.1742518-1.130082*x3^2-17.35482*x3*x4

请记住,虽然我们这里有两个变量 (x3,x4),但可能会有更多变量,而且多项式生成的项数可能非常大,使得手动创建此类公式非常乏味。

对于上面带有 2 个变量的示例,解决方案可能是:

x3 <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
x4 <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
y <- x3*3 + 3* x3 * x4
model <- lm(y ~ poly(x3, x4, degree=2, raw=TRUE))

paste( "z ~",unname(model$coefficients)[1], "-", unname(model$coefficients)[2], 
       "* x3 ^ 2 -", unname(model$coefficients)[3], "* x3 * x4" )
##"z ~ -1.91152113238255e-12 - 5.4307136268434e-14 * x3 ^ 2 - 1.04899226410413e-14 * x3 * x4"

但是,如果您想以更通用的方式使用它(处理公式的不同数量的参数等),那么您可以处理 model:

中的各种组件
str(model)
List of 12
 $ coefficients : Named num [1:6] -1.91e-12 5.43e-14 1.05e-14 3.00 3.00 ...
  ..- attr(*, "names")= chr [1:6] "(Intercept)" "poly(trt, ctl, degree = 2, raw = TRUE)1.0" "poly(trt, ctl, degree = 2, raw = TRUE
...

以上只是部分输出,但您可以找到列表的成员,其中包含公式本身和在那里使用的所有变量,然后编写循环遍历每个变量的函数并添加就像上面的例子一样。

您要求的是灵活性,而我已经在此处提供了。主要的挑战是处理 poly 产生的系数名称,使它们对一个人来说更漂亮。请注意,我在此处提供的解决方案假设 您模型中的每个 项都包含在 poly 中,截距除外。

MyData = data.frame(x3=runif(100),x4=runif(100))
MyData$z = 0.17 -1.13*MyData$x3^2-17.35*MyData$x3*MyData$x4+rnorm(100)

model <- lm(z~poly(x3,x4, degree=2,raw=TRUE), MyData)
summary(model)$coef

你的问题没有包含可重现的样本,所以我创建了一个。下面的函数旨在处理多边形系数名称和 return 一个漂亮的 x3x4 类型名称。

processPolyNames = function(coef){
  members = strsplit(mgsub::mgsub(coef,c("poly\(",", degre.*"),c("","")),", ")[[1]]
  degree = as.numeric(strsplit(strsplit(coef,")")[[1]][2],"\.")[[1]])
  coef_out = ""
  for(d in seq_along(degree)){
    if(degree[d] == 0) next
    if(degree[d] == 1){
      if(coef_out == ""){
        coef_out = members[d]
      } else {
        coef_out = paste0(coef_out,"*",members[d])
      }
    } else {
      if(coef_out == ""){
        coef_out = paste0(members[d],"^",degree[d])
      } else {
        coef_out = paste0(coef_out,"*",members[d],"^",degree[d])
      }
    }
  }
  return(coef_out)
}

现在我们提取模型的系数 - 如果您只想包含显着影响,则可以过滤 coefs。然后我 lapply 我写给丑陋的名字的函数以获得漂亮的名字。

coefs = summary(model)$coef[,1]
prettyNames = lapply(names(coefs)[-1],processPolyNames)
unlist(prettyNames)
#> [1] "x3"    "x3^2"  "x4"    "x3*x4" "x4^2"

现在我们需要制作一个漂亮的模型。这只是一个for循环。从截距开始,我们然后构建模型(将系数四舍五入到 7 位有效数字。

prettyModel = ""
for(i in seq_along(coefs)){
  if(i == 1){
    prettyModel = paste0(prettyModel,round(coefs[i],7))
  } else {
    prettyModel = paste0(prettyModel,ifelse(coefs[i] >= 0,"+",""),round(coefs[i],7),"*",prettyNames[[i-1]])
  }
}

prettyModel
#> [1] "0.1169037+1.8662887*x3-3.0333651*x3^2-1.3031079*x4-17.1641031*x3*x4+1.5259313*x4^2"

然后可以 mgsub 使用该模型根据需要用 Excel 单元格引用替换变量。