从SAS到R的PROC NLIN

时间:2014-09-10 10:27:52

标签: r sas proc nls nonlinear-functions

我目前已经分配了一项工作,我需要将SAS代码转换为R.我已经能够成功完成80%的工作,现在我被困在使用PROC NLIN的部分。从我读到的,PROC NLIN用于拟合非线性模型,我不确定代码是否实际上是这样做的,因此,坚持如何在R中执行它。代码如下 -

proc nlin data=ds1 outest=estout;
 parms ET= 0 f= 10.68;
  E= f- R*(1-ET*M); 
  L   = E*E;
  model.like = sqrt(E*E);
  by Name ; 
run;

样本数据如下 -

Name    M           R
Anna    0.5456231   4.118197
Anna    0.5359164   4.240243
Anna    0.541881    3.943975
Anna    0.5436047   3.822222
Anna    0.5522962   3.58813
Anna    0.5561487   3.513195
Anna    0.5423374   3.666507
Anna    0.525836    3.715371
Anna    0.5209941   3.805572
Anna    0.5304675   3.750689
Anna    0.5232541   3.788292

当我在SAS帮助中浏览PROC NLIN上的页面时,参数'MODEL'用于指定方程,但此处的代码没有模型方程。 Model.like是指定似然函数(第4316页 - https://support.sas.com/documentation/cdl/en/statugnlin/61811/PDF/default/statugnlin.pdf)那么这段代码在做什么?我完全糊涂了。我最初觉得这可以使用nls()在R中完成,我尝试了以下内容 -

fit = nls(E~ f - R*(1-eta*M),sample, start=list(eta=0,phi=10.86)
      ,trace=T)

但我很快意识到这是错误的,因为即使在5000次迭代后模型也没有收敛。这是因为我的数据集中没有列'E'。那么,SAS是如何做到的呢? 任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:4)

首先让我们弄清楚SAS代码在做什么。可以欺骗PROC NLIN进行各种最小化问题,但设置有时会违反直觉。您需要根据其他变量和一些参数($ f(x,\ beta $))定义因变量($ y $)和预测值,并将最小化$ \ sum_i [y_i - f(x_i,\ beta)] ^ 2 $。

定义$ y $和$ f $的关键是

model.like = sqrt(E*E)

相当于

model like = sqrt(E*E)

所以这意味着$ \ sum [like - \ sqrt {E \ cdotE}] ^ 2 $将被最小化。基于您链接的示例,我假设变量like之前已定义,并且已设置为常量0.这意味着$ \ sum [0- \ sqrt {E \ cdotE}] ^ 2 = \ sum E ^ 2 $正在最小化。

E被定义为f- R*(1-ET*M),因此实际上$ \ sum [f-R *(1-ET * M)] ^ 2 $被最小化,其中f和{ {1}}是未知参数。我不确定这是什么意思,但那是发生了什么。

将其重写为R确实可以使用ET,我们可以使用相同的技巧:预测零。

nls

带输出

sample <- read.table(textConnection(
"Name    M           R
 Anna    0.5456231   4.118197
 Anna    0.5359164   4.240243
 Anna    0.541881    3.943975
 Anna    0.5436047   3.822222
 Anna    0.5522962   3.58813
 Anna    0.5561487   3.513195
 Anna    0.5423374   3.666507
 Anna    0.525836    3.715371
 Anna    0.5209941   3.805572
 Anna    0.5304675   3.750689
 Anna    0.5232541   3.788292"), header=TRUE)

nls(0 ~ f - R*(1-eta*M), data=sample, start=list(eta=0,f=10.86), trace=T)

请注意,SAS代码运行546.5988 : 0.00 10.86 0.06273518 : 1.7259120 0.2731282 Nonlinear regression model model: 0 ~ f - R * (1 - eta * M) data: sample eta f 1.7259 0.2731 residual sum-of-squares: 0.06274 Number of iterations to convergence: 1 Achieved convergence tolerance: 4.345e-07 ,因此您必须确保R代码也适合每个名称的不同模型。

答案 1 :(得分:0)

整齐的方法

library(tidyverse)
library(broom)

sample <- read.table(textConnection(
  "Name    M           R
  Anna    0.5456231   4.118197
  Anna    0.5359164   4.240243
  Anna    0.541881    3.943975
  Anna    0.5436047   3.822222
  Anna    0.5522962   3.58813
  Anna    0.5561487   3.513195
  Anna    0.5423374   3.666507
  Anna    0.525836    3.715371
  Anna    0.5209941   3.805572
  Anna    0.5304675   3.750689
  Anna    0.5232541   3.788292"), header=TRUE)


x <- sample %>%
  group_by(Name) %>%
  nest() %>%
  mutate(
    model = data %>% map(~nls(0 ~ f - R*(1-eta*M), data= . , start=list(eta=0,f=10.86), trace=T)),
    coef = map(model, tidy),
    quali = map(model, glance),
    resid = map(model, augment)
  )

unnest(select(x, coef))
# A tibble: 2 x 6
    Name  term  estimate std.error statistic      p.value
  <fctr> <chr>     <dbl>     <dbl>     <dbl>        <dbl>
1   Anna   eta 1.7259120 0.2260999 7.6334045 3.213398e-05
2   Anna     f 0.2731282 0.4645288 0.5879683 5.710103e-01

unnest(select(x, quali))
# A tibble: 1 x 8
       sigma isConv       finTol   logLik       AIC       BIC   deviance df.residual
       <dbl>  <lgl>        <dbl>    <dbl>     <dbl>     <dbl>      <dbl>       <int>
1 0.08348998   TRUE 4.345363e-07 12.80868 -19.61736 -18.42368 0.06273518           9