目前,我被分配了一项工作,需要将SAS代码翻译成R。我已经成功地完成了其中80%的工作,现在我被困在使用PROC NLIN的部分。根据我所读到的,PROC NLIN被用来拟合非线性模型,andI不确定代码是否真的在这样做,因此,在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是怎么做到的呢?任何帮助都是非常感谢的!
发布于 2014-09-10 07:31:21
首先,让我们了解一下SAS代码正在做什么。PROC NLIN
可以被骗到做各种最小化的问题,但设置有时是违反直觉的。您需要定义一个因变量($y$)和一个基于其他变量和一些参数($f(x,\beta$)的预测值,并且它将最小化$\sum_i y_i - f(x_i,\beta)^2$。
定义$y$和$f$的关键路线是
model.like = sqrt(E*E)
这相当于
model like = sqrt(E*E)
因此,这意味着$\sum类的- \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
和ET
是未知参数。我不知道这意味着什么,但事情就是这样。
将其重写为R确实可以使用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)
带输出
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
请注意,SAS代码是运行by Name
的,因此您必须确保R代码也适合每个名称的不同模型。
发布于 2017-07-03 15:47:56
潮汐法
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
https://stackoverflow.com/questions/25763070
复制