0

I have a data table with experimental data which i want to non-linear fit. The Data consist in a table with the first column containing the x values, all the next columns contain y data from different measurements. there are 2 parameters which i guess by the fit method, called a and b. e.g.:

    x y1 y2 y3 y4
    2 60 100 129 189
    5 90 118 156 200
    10 114 145 178 225 (all data random, not real)

i managed to fit the x and y1 columns using nls (works like a charm, thanks to several articles found here:-)), extracting a subset of y values column by column. Now i want to recursively fit all y columns against x and save the respective values of a and b in another table.

Up to now i did this:

    x<-trx_data[,c(1)]
    y_383.2<-trx_data[,c(2)] #corresponds to y1
    df<-data.frame(x,y_383.2) #define a new data table with x and y1
    colnames(df)<-c("x","y")  #rename the columns
    start_values<-c(a=20,b=2) #set starting values
    #perform fitting
    m_HB<-nls(y~x+a*sqrt(b*x/a+1),
          data = df,
          start = start_values,
          algorithm="plinear")
    summary(m_HB)

now i want to create a data table looking like this:

    383.2  383.3 383.4 #column names, extracted from input table
    40     46    49    #parameter a
    7      13    9     #parameter b

is there an elegant solution for this? Thanks a lot in advance! Chris

MrFlick
  • 195,160
  • 17
  • 277
  • 295
ChrisO
  • 1
  • 2
  • 1
    You say "recursive" ... to me, that suggests that regressing `x ~ y3` relies on the outcome from the regression `x ~ y2`, which itself relies on `x ~ y1`. Is that right? Or are you trying to "iterate" over all of the `y*` values in a way similar to what you did on `y1`? – r2evans Aug 17 '23 at 13:14
  • @r2evans: thanks for the comment, indeed i try to iterate over the y* values. – ChrisO Aug 17 '23 at 14:14

1 Answers1

3

I think you want to iterate over the yi as dependent variables. nlme::nlsList is designed for this:

library(data.table)

DF <- fread("x y1 y2 y3 y4
2 60 100 129 189
5 90 118 156 200
10 114 145 178 225")

#reshape data
DF <- melt(DF, id.vars = "x", value.name = "y")

library(nlme)
start_values<-c(a=20,b=2)
fits <- nlsList(y~x+a*sqrt(b*x/a+1) | variable, data = DF, 
                start = start_values, pool = FALSE)
summary(fits)
#Call:
#  Model: y ~ x + a * sqrt(b * x/a + 1) | variable 
#   Data: DF 
#
#Coefficients:
#   a 
#    Estimate Std. Error    t value    Pr(>|t|)
#y1  41.13625 10.1776110   4.041838 0.154406790
#y2  86.18704  0.3414589 252.408273 0.002522169
#y3 117.42132  7.9259599  14.814775 0.042906863
#y4 178.05209  2.9667743  60.015382 0.010606629
#   b 
#    Estimate Std. Error   t value    Pr(>|t|)
#y1 23.307477  9.2938091  2.507850 0.241550461
#y2 12.499029  0.1625046 76.914935 0.008276467
#y3 12.902568  3.4640896  3.724664 0.166982283
#y4  7.963814  1.0728033  7.423369 0.085245708

t(coef(fits))
#        y1       y2        y3         y4
#a 41.13625 86.18704 117.42132 178.052091
#b 23.30748 12.49903  12.90257   7.963814

Note that I omit algorithm="plinear" because you don't specify any partial linearity (and the model is indeed not partially linear).

Roland
  • 127,288
  • 10
  • 191
  • 288
  • Roland, thanks a lot for your answer. Unfortunately, i got an error message while running nlsList: "Error in nlsList.formula(y ~ x + a * sqrt(b * x/a + 1), data = df, start = start_values, : 'data' must be a "groupedData" object if 'formula' does not include groups". Now i see my error: i ran the nlsList only on x and y1. I try now to fix it! Thanks! – ChrisO Aug 17 '23 at 14:22
  • Roland, many thanks! Your code works like a charm! You saved my day! – ChrisO Aug 17 '23 at 14:59