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()"
所以我的代码至少存在三个问题:
- 如何实现select()的序列,lm模型和命名?
- 我找不到在 select 添加新列后更新因子 (a,b,c,d) 的解决方案,除了再次将它们写下来
- 如何粘贴“真实代码”而不仅仅是文本来获取示例中的系数?
编辑:
感谢 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)
背景: 我有几个响应作为 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()"
所以我的代码至少存在三个问题:
- 如何实现select()的序列,lm模型和命名?
- 我找不到在 select 添加新列后更新因子 (a,b,c,d) 的解决方案,除了再次将它们写下来
- 如何粘贴“真实代码”而不仅仅是文本来获取示例中的系数?
编辑:
感谢 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)