R:来自 DOE 因素的一系列 lm 模型的简短有效代码

R: short and effective code for a sequence of lm models from DOE factors

背景: 我有几个响应作为 DOE 的输出,我想对每个响应进行建模。首先当然是成功的尝试是简单地为每个模型编写一个长代码。

formula<- y~a+b+c+d+a:b+a:c+a:d+b:c+b:d+c:d+I(a^2)+I(b^2)+I(c^2)+I(d^2)

Response_Data <- dataframe%>%
  dplyr::select(2:5,6)
a <- Response_Data$X1
b <- Response_Data$X2
c <- Response_Data$X3
d <- Response_Data$X4
y <- Response_Data[[5]]
Response_1_Model <- lm(formula,Response_Data)

Response_Data <- dataframe%>%
  dplyr::select(2:5,7)
a <- Response_Data$X1
b <- Response_Data$X2
c <- Response_Data$X3
d <- Response_Data$X4
y <- Response_Data[[5]]
Response_2_Model <- lm(formula,Response_Data)

Response_Data <- dataframe%>%
  dplyr::select(2:5,8)
a <- Response_Data$X1
b <- Response_Data$X2
c <- Response_Data$X3
d <- Response_Data$X4
y <- Response_Data[[5]]
Response_3_Model <- lm(formula,Response_Data)

and so on, and so on

然后我想将所有系数都放在一个数据帧中并这样做:

Coefficients<-data.frame(Response_1_Model%>%coef(),Response_2_Model%>%coef(),Response_3_Model%>%coef(),Response_4_Model%>%coef(),Response_5_Model%>%coef(),Response_6_Model%>%coef(),Response_7_Model%>%coef(),Response_8_Model%>%coef(),Response_9_Model%>%coef(),Response_10_Model%>%coef(),Response_11_Model%>%coef(),Response_12_Model%>%coef(),Response_13_Model%>%coef(),Response_14_Model%>%coef(),Response_15_Model%>%coef(),Response_16_Model%>%coef(),Response_17_Model%>%coef(),Response_18_Model%>%coef(),Response_19_Model%>%coef(),Response_20_Model%>%coef(),Response_21_Model%>%coef(),Response_22_Model%>%coef(),Response_23_Model%>%coef(),Response_24_Model%>%coef(),Response_25_Model%>%coef(),Response_26_Model%>%coef(),Response_27_Model%>%coef())%>%mutate(across(is.numeric, round, digits=3))

colnames(Coefficients)<-c(names(RT_Datentabelle[6:32]))

我知道,这太可怕了,但我无法使用 paste0() 做到这一点。 我尝试如下:

Response_Models<-paste0("Response_",1:27,"_Model%>%coef()",collapse = ",")

输出是:

[1] "Response_1_Model%>%coef(),Response_2_Model%>%coef(),Response_3_Model%>%coef(),Response_4_Model%>%coef(),Response_5_Model%>%coef(),Response_6_Model%>%coef(),Response_7_Model%>%coef(),Response_8_Model%>%coef(),Response_9_Model%>%coef(),Response_10_Model%>%coef(),Response_11_Model%>%coef(),Response_12_Model%>%coef(),Response_13_Model%>%coef(),Response_14_Model%>%coef(),Response_15_Model%>%coef(),Response_16_Model%>%coef(),Response_17_Model%>%coef(),Response_18_Model%>%coef(),Response_19_Model%>%coef(),Response_20_Model%>%coef(),Response_21_Model%>%coef(),Response_22_Model%>%coef(),Response_23_Model%>%coef(),Response_24_Model%>%coef(),Response_25_Model%>%coef(),Response_26_Model%>%coef(),Response_27_Model%>%coef()"

所以我的代码至少存在三个问题:

编辑:

感谢 Miss.Alpha 的评论,我尝试了 nest() 和 map() 方法,它从一个整洁的数据框开始工作得很好。

df_tidy<-df%>%
  pivot_longer(cols = Y1:Y27,names_to = "Y", values_to = "value")
df_nest_lm<-df_tidy%>%
  nest(data= -Y)%>%
  mutate(fit= map(data,~lm(.x$value~.x$X1+.x$X2+.x$X3+.x$X4+.x$X1:.x$X2+.x$X1:.x$X3+.x$X1:.x$X4+.x$X2:.x$X3+.x$X2:.x$X4+.x$X3:.x$X4+I(.x$X1^2)+I(.x$X2^2)+I(.x$X3^2)+I(.x$X4^2),data= .x)),
  tidied = map(fit, tidy)
  ) %>% 
  unnest(tidied)

我当然想去掉丑陋的公式,但是我不能这样粘贴:

a <- '.x$X1'
b <- '.x$X2'
c <- '.x$X3'
d <- '.x$X4'
y <- '.x$value'

f<- as.formula(paste(y, paste(a,b,c,d,
                                    paste0(a,":",c(b,c,d),collapse = "+"),
                                    paste0(b,":",c(c,d),collapse = "+"),
                                    paste0(c,":",d),
                                    paste0("I(",c(a,b,c,d),"^2)",sep="",collapse = "+"),
                                      sep = "+"),
                                    sep = "~"))
df_nest_lm<-df_tidy%>%
  nest(data= -Y)%>%
  mutate(fit= map(data,~lm(formula=f,data= .x)),
  tidied = map(fit, tidy)
  ) %>% 
  unnest(tidied)

我总是得到错误:

错误:mutate()fit 有问题。我 fit = map(data, ~lm(formula = f, data = .x))。 x 未找到对象“.x”

有没有人能解释为什么公式与上面相同但它不起作用?

这是一种方式:

# Define formula
formula<- y~a+b+c+d+a:b+a:c+a:d+b:c+b:d+c:d+I(a^2)+I(b^2)+I(c^2)+I(d^2)
# Define a function that takes the x:th variable
my_reg <- function(x, formula, dataframe){
Response_Data <- dataframe%>%
  dplyr::select(2:5,x)
a <- Response_Data$X1
b <- Response_Data$X2
c <- Response_Data$X3
d <- Response_Data$X4
y <- Response_Data[[5]]
lm(formula,Response_Data)
}
# Make one model for each x:th variable
map(6:8, my_reg, formula, dataframe)