我目前已经分配了一项工作,我需要将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是如何做到的呢? 任何帮助表示赞赏!
答案 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