如何将以下 "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 一个漂亮的 x3
、x4
类型名称。
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 单元格引用替换变量。
我使用以下代码在 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 一个漂亮的 x3
、x4
类型名称。
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 单元格引用替换变量。