EDIT: I'm going to EDIT this post to streamline my question to hopefully make it clearer. -- CalebPicker
I'm trying to use apply()
or a for...loop
to optimize a custom function on each row, and for each completed optimization, I want the output parameters to bind to the corresponding row. For example, if I have 10 rows in my dataframe called df_conf
, then I want optim()
to run 10 times and bind the 10 sets of outputs next to the corresponding row.
I want to apply the optim()
function to row 1, spit out par1:par3
and bind it to this data frame, then move onto row 2 and do the same thing for all rows.
df5<-data.frame(H1=c(1,5),H2=c(4,7),H3=c(12,17),H4=c(21,32),H5=c(25,41),H6=c(52,64),
F1=c(2,8),F2=c(9,10),F3=c(18,21),F4=c(21,32),F5=c(31,49),F6=c(59,68))
# Create optim() function to minimize sse for a line for one subject
lm_sse5<-function(dat,par,i){
b0<-par[1]
b1<-par[2]
# Convert wide to long inside of function
lm_df5<-data.frame(x=c(dat[["H1"]],dat[["H2"]],dat[["H3"]],dat[["H4"]],dat[["H5"]],dat[["H6"]]), y=c(dat[["F1"]], dat[["F2"]], dat[["F3"]], dat[["F4"]], dat[["F5"]], dat[["F6"]]))`
yhat<-b0 + b1*lm_df5[["x"]]
sse<- sum((yhat-lm_df5[["y"]])**2)
sse_sqrt<-sqrt(sse)
# How to get sse and sse_sqrt into dataframe?
# This seemed to work but seems tedious. This replaces the dataframe with a new value for each iteration
# but because it's being overwritten each time, I end up with the last value in the output dataframe.
output<<-data.frame("sse"="","sse_sqrt"="")
output[["sse"]]<<-sse
output[["sse_sqrt"]]<<-sse_sqrt
print(paste0("sse is: ",sse))
print(paste0("sse_sqrt is: ", sse_sqrt))
return(sse)
}
# Define parameter start values
param_start<-c(b0=0,b1=0)
# Run minimization function on return value in function, which is sse
# try to use apply function
# I could not get this to work
# result5a<-apply(1:nrow(df5),1,function(x){
# optim(param_start,
# fn=lm_sse5,
# dat=df5[x,])
# }
# )
# # The for loop works but this does not save the values appropriately
for(x in 1:nrow(df5)){
result5b<-optim(param_start,
fn=lm_sse5,
dat=df5[x,],
i=x)
}
# append results to original dataframe
# This works but is very manual
df5$b0<-result$par["b0"]
df5$b1<-result$par["b1"]
df5$sse<-output$sse
df5$sse_sqrt<-output$sse_sqrt