双循环SAS计算
我尝试使用两个循环进行计算。但我对循环元素不是很熟悉 以下是我的数据:双循环SAS计算,sas,Sas,我尝试使用两个循环进行计算。但我对循环元素不是很熟悉 以下是我的数据: data try; input rs t a b c; datalines; 0 600 1 600 0.02514 667.53437 0.1638 2 600 0.2766 724.60233 0.30162 3 610 0.01592 792.34628 0.21354 4 615.2869 0.03027 718
data try;
input rs t a b c;
datalines;
0 600
1 600 0.02514 667.53437 0.1638
2 600 0.2766 724.60233 0.30162
3 610 0.01592 792.34628 0.21354
4 615.2869 0.03027 718.30377 0.22097
5 636.0273 0.01967 705.45965 0.16847
;
run;
我试图计算的是,对于每个‘T’值,a、b和c的所有元素都需要用于方程。然后我创建变量v1-v6,将每个T1-T6的方程结果放入其中。然后,我创建CS来求v的所有元素的和
因此,我的结果数据集如下所示:
rs T a b c v1 v2 v3 v4 v5 v6 CS
0 600 sum of v1
1 600 0.02514 667.53437 0.1638 sum of v2
2 600 0.2766 724.60233 0.30162 sum of v3
3 610 0.01592 792.34628 0.21354 sum of v4
4 615.2869 0.03027 718.30377 0.22097 sum of v5
5 636.0273 0.01967 705.45965 0.16847 sum of v6
我在下面写了一段代码来实现这一点,但出现了错误。主要是我不知道如何正确使用I和j来链接变量的所有元素。有人能指出我认为不正确的地方吗?我知道myabe我不应该使用sum函数来累加变量的元素,但不确定使用哪个函数
data try3;
set try;
retain v1-v6;
retain t a b c;
array v(*) v1-v6;
array var(*) t a b c;
cs=0;
do i=1 to 6;
do j=1 to 6;
v[i,j]=(2.89*(a[j]**2*(1-c[j]))/
((c[j]+exp(1.7*a[j]*(t[i]-b[j])))*
((1+exp(-1.7*a[j]*(t[i]-b[j])))**2));
cs[i]=sum(of v[i,j]-v[i,j]);
end;
end;
run;
例如,v1的计算将类似于v[1,1]=0,因为没有b c的值 对于v[1,2]=(2.89*0.02514**2(1-0.1638))/((0.1638+exp(1.7*0.02514*600-667.53437))*((1+exp(-1.7*0.02514*(600-667.5347))**2)) v[1,3]=(2.89*0.2766**2(1-0.30162))/(0.30162+exp(1.7*0.2766*600-724.60233))*((1+exp(-1.7*0.2766*(600-724.60233))**2))
v[1,4]将使用a b c的下一行值,但t将与t[1]相同。直到最后一排。这就是v1。然后我需要求v1的所有元素的和,比如v1{1,1]+v1[1,2]+v1{1,3]..v1[1,6],得到cs[1,1].SAS语言不太擅长做这类事情,它们本质上是矩阵计算。数据步骤通常一次处理一个观察值,尽管您可以使用RETAIN语句进行计算。如果您可以访问PROC IML,您可能会得到比这更干净的结果(本机进行矩阵计算),但假设您没有访问IML的权限,您需要执行以下操作。我不能100%确定这是您所需要的,但我认为这是正确的:
data try;
infile cards missover;
input rs t a b c;
datalines;
0 600
1 600 0.02514 667.53437 0.1638
2 600 0.2766 724.60233 0.30162
3 610 0.01592 792.34628 0.21354
4 615.2869 0.03027 718.30377 0.22097
5 636.0273 0.01967 705.45965 0.16847
;
run;
data try4(rename=(aa=a bb=b cc=c css=cs tt=t vv1=v1 vv2=v2 vv3=v3 vv4=v4 vv5=v5 vv6=v6));
* Construct arrays into which we will read all of the records;
array t(6);
array a(6);
array b(6);
array c(6);
array v(6,6);
array cs(6);
* Read all six records;
do i=1 to 6;
set try(rename=(t=tt a=aa b=bb c=cc));
t[i] = tt;
a[i] = aa;
b[i] = bb;
c[i] = cc;
end;
* Now do the calculation, which involves values from each
row at each iteration;
do i=1 to 6;
cs[i]=0;
do j=1 to 6;
v[i,j]=(2.89*(a[j]**2*(1-c[j]))/
((c[j]+exp(1.7*a[j]*(t[i]-b[j])))*
((1+exp(-1.7*a[j]*(t[i]-b[j])))**2)));
cs[i]+v[i,j];
end;
* Then output the values for this iteration;
tt=t[i];
aa=a[i];
bb=b[i];
cc=c[i];
css=cs[i];
vv1=v[i,1];
vv2=v[i,2];
vv3=v[i,3];
vv4=v[i,4];
vv5=v[i,5];
vv6=v[i,6];
keep tt aa bb cc vv1-vv6 css;
output try4;
end;
注意,我必须构造已知大小的数组,也就是说,您必须知道有多少个输入记录
数据步骤的前半部分构造数组,从中读取输入数据集的值。我们读取所有记录,然后进行所有计算,因为所有值都在矩阵的内存中。
有一些修改重命名,这样您可以保留数组名t、a、b、c等,但在输出数据集中仍然有名为a、b、c等的变量
因此,希望这能对您有所帮助。要么这样,要么让您感到困惑,因为我误解了您的意图!SAS语言不太擅长做这类事情,本质上是矩阵计算。数据步骤通常一次处理一个观察值,尽管您可以使用他保留声明。如果您可以访问PROC IML(它以本机方式进行矩阵计算),您可能会得到比这更干净的结果,但假设您没有访问IML的权限,您需要执行以下操作。我不能100%确定这是您需要的,但我认为这是正确的:
data try;
infile cards missover;
input rs t a b c;
datalines;
0 600
1 600 0.02514 667.53437 0.1638
2 600 0.2766 724.60233 0.30162
3 610 0.01592 792.34628 0.21354
4 615.2869 0.03027 718.30377 0.22097
5 636.0273 0.01967 705.45965 0.16847
;
run;
data try4(rename=(aa=a bb=b cc=c css=cs tt=t vv1=v1 vv2=v2 vv3=v3 vv4=v4 vv5=v5 vv6=v6));
* Construct arrays into which we will read all of the records;
array t(6);
array a(6);
array b(6);
array c(6);
array v(6,6);
array cs(6);
* Read all six records;
do i=1 to 6;
set try(rename=(t=tt a=aa b=bb c=cc));
t[i] = tt;
a[i] = aa;
b[i] = bb;
c[i] = cc;
end;
* Now do the calculation, which involves values from each
row at each iteration;
do i=1 to 6;
cs[i]=0;
do j=1 to 6;
v[i,j]=(2.89*(a[j]**2*(1-c[j]))/
((c[j]+exp(1.7*a[j]*(t[i]-b[j])))*
((1+exp(-1.7*a[j]*(t[i]-b[j])))**2)));
cs[i]+v[i,j];
end;
* Then output the values for this iteration;
tt=t[i];
aa=a[i];
bb=b[i];
cc=c[i];
css=cs[i];
vv1=v[i,1];
vv2=v[i,2];
vv3=v[i,3];
vv4=v[i,4];
vv5=v[i,5];
vv6=v[i,6];
keep tt aa bb cc vv1-vv6 css;
output try4;
end;
注意,我必须构造已知大小的数组,也就是说,您必须知道有多少个输入记录
数据步骤的前半部分构造数组,从中读取输入数据集的值。我们读取所有记录,然后进行所有计算,因为所有值都在矩阵的内存中。
有一些修改重命名,这样您可以保留数组名t、a、b、c等,但在输出数据集中仍然有名为a、b、c等的变量
所以,希望这能对您有所帮助。要么这样,要么让您感到困惑,因为我误解了您的意图!您的意思是我回答了我自己的问题并做了绿色标记吗?我格式化了您的代码和数据…但我无法理解您试图计算的内容…您的输出数据没有意义输出数据将包含新变量v1-6和cs。我想在输出数据中说的是,每个v上都会有方程中的值,然后cs将是v变量元素和的和。看起来你试图将数据集想象成矩阵。SAS数据集一次处理一行。你将数组v定义为一维,但你正在尝试to访问它就像它是二维的。我怎样才能先在T上循环,然后在T循环中循环a、b、c变量?我看到SAS也可以为多维数据中的变量定义下标I、j。你的意思是我回答我自己的问题并做绿色标记吗?我格式化了你的代码和数据…但我无法理解你试图计算的内容…你的输出数据没有意义输出数据将包含新的变量v1-6和cs。我在输出数据中想说的是,每个v上都会有方程中的值,然后cs将是v变量元素和的总和。看起来你试图将数据集想象成矩阵。SAS数据集在一个r中处理一次是ow。你将数组v定义为一维,但你试图像二维一样访问它。我怎样才能先循环T,然后在T循环中循环a、b、c变量?我看到SAS也可以为多维数据中的变量定义下标I、j。非常感谢Tom的回答。结果与wh匹配我在excel中计算。我的问题是,当我有更多的数据行时,如何在代码末尾生成重命名语句和输出值?如果输出数据太长,即使我没有将v1-v6值包含在输出数据中,我是否需要编写代码的最后一部分(变量列表)?我本可以用它来重命名vv1-vv6=v1-v6。但同样的惯例不适用于输出vv1-vv6=v[I,1]-v[I,6];有人知道吗?我想如果它太长,我可以将vv1-vv6=v[1,1]删除为v6[1,6],只是不在keep语句中包含它们。所以我所有的查询都可以解决