我试图在SAS中复制Excel的目标搜索。 我想找到一个常数,当添加到初始数据时,数据的总体平均值等于目标。当涉及转换时,这会有点棘手。
所以我的三个数据点(var1)是0.78,0.8,0.85。目标是0.87。 我想找到x其中AVERAGE(1 /(1 + EXP( - (LN(var1 /(1 + var1))+ x)))= 0.87
这是我目前的代码,但是当它应该是0.4525(通过Excel找到)时,它得到x = 0.4803。
data aa;
input var1 target;
datalines;
0.78 0.87
0.8 0.87
0.85 0.87
;
run;
proc model data=aa outparms=parm;
target = 1/(1+EXP(-(log(var1/(1-var1)) + x)));
fit target;
run;
我认为这不起作用bc它并不包含所有3个数据点的平均值。我不知道该怎么做。理想情况下,我只能将proc模型节点中的第二行更改为:
target = Avg(1/(1+EXP(-(log(var1/(1-var1)) + x))));
但这不起作用。
答案 0 :(得分:0)
proc model
主要用于时间序列,并且在垂直使用汇总函数方面做得不好;但是,水平做它时效果很好。解决问题的一种方法是转移问题:
proc transpose data=aa out=aa_trans;
by target;
var var1;
run;
proc model data=aa_trans;
endo x;
exo COL1-COL3 target;
target = mean(1/(1+EXP(-(log(COL1/(1-COL1)) + x)))
, 1/(1+EXP(-(log(COL2/(1-COL2)) + x)))
, 1/(1+EXP(-(log(COL3/(1-COL3)) + x))) );
solve / out=solution solveprint ;
run;
我们得到 0.4531398172
的答案。可以通过直接插入值来检查:
data _null_;
set aa_trans;
x = 0.4531398172;
check = mean(1/(1+EXP(-(log(COL1/(1-COL1)) + x)))
, 1/(1+EXP(-(log(COL2/(1-COL2)) + x)))
, 1/(1+EXP(-(log(COL3/(1-COL3)) + x))) );
put '*********** ' check;
run;
此方法需要额外的宏编程来进行概括,如果您有许多观察转置,则可能在计算上非常昂贵。要对任何给定数量的列进行概括,可以使用以下宏程序:
%macro generateEquation;
%global eq;
%let eq = ;
proc sql noprint;
select count(*)
into :total
from aa
;
quit;
%do i = 1 %to &total.;
%let eq = %cmpres(&eq 1/(1+EXP(-(log(COL&i/(1-COL&i))+x))));
%end;
%let eq = mean(%sysfunc(tranwrd(&eq, %str( ), %str(,) ) ) );
%put &eq;
%mend;
%generateEquation;
proc model data=aa_trans;
endo x;
exo COL1-COL3 target;
target = &eq.;
solve / out=solution solveprint ;
run;
相反,您可能希望将此问题重新设置为没有目标函数的优化问题。 proc optmodel
,如果在您的网站上可用,则允许您执行此矩阵操作。生成的代码更加复杂和手动,但会为您提供更通用和计算上可行的结果。
您需要添加两个新变量并将目标分离到新数据集。
data aa;
input targetid obs var1;
datalines;
1 1 0.78
1 2 0.8
1 3 0.85
;
run;
data bb;
input targetid target;
datalines;
1 0.87
;
run;
proc optmodel;
set id;
set obs;
set <num,num> id_obs;
/* Constants */
number target{id};
number var1{id_obs};
read data bb into id=[targetid]
target;
read data aa into id_obs=[targetid obs]
var1;
/* Parameter of interest */
var x{id};
/* Force the solver to seek the required goal */
con avg {i in id}: target[i] = sum{<j,n> in id_obs: j=i} (1/(1+EXP(-(log(var1[j, n]/(1-var1[j, n])) + x[i]))) )
/ sum{<j,n> in id_obs: j=i} 1;
/* Check if it's the equation that we want */
expand;
/* Solve using the non-linear programming solver with no objective */
solve with nlp noobjective;
/* Output */
create data solution from [targetid] = {i in id}
x[i];
quit;
optmodel
会返回一个类似的答案: 0.4531395426
,相差0.0000002746个小数位。由于方法和最优公差的不同,答案并不相同;但是,解决方案会检出。
proc sql;
select Avg(1/(1+EXP(-(log(var1/(1-var1)) + 0.4531395426))))
from aa;
quit;