2012-04-11 137 views
0

我正在尝试使用两个循环来计算。但我对循环元素不是很熟悉。使用双循环的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.30377 0.22097 
5 636.0273 0.01967 705.45965 0.16847 
; 
run; 

我试图计算的是每个“T”值,用于方程式的A,B和C需要的所有元素。然后我创建了varaibles 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; 

Forexample,V1将被计算与V同样[1,1] = 0,因为没有用于A 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))。 ((1 + exp( - 1))/((0.30162 + exp(1.7 * 0.2766 * 600-724.60233))) 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] 。

+0

你的意思是我回答我自己的问题并做绿色标记? – user634455 2012-04-11 16:11:30

+0

我对您的代码和数据进行了格式化...但是我无法按照您要计算的内容输出数据没有意义 – 2012-04-11 16:25:41

+0

输出数据将包含新变量v1-6和cs。我在输出数据中想要说的是,每个v都会有方程的值,然后cs将是v变量元素总和的总和。 – user634455 2012-04-11 17:03:43

回答

4

SAS语言不擅长做这些事情,基本上是矩阵计算。尽管您可以使用RETAIN语句进行计算,但DATA步骤通常一次只处理一个观察值。如果您有权访问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; 

请注意,我必须构建已知大小的数组,这是你必须知道多少有输入记录。

DATA步骤的前半部分构造了读入输入数据集中的值的数组。我们读取所有的记录,然后我们完成所有的计算,因为我们在matricies中拥有内存中的所有值。 有一些与RENAMES的摆弄,这样你就可以保留数组名称t,a,b,c等,但在输出数据集中仍然有名为a,b,c等的变量。

所以希望这可能会帮助你一点。要么是因为我误解了你正在做的事情而迷惑你!

+0

非常感谢汤姆的回答。结果与我在Excel中计算的结果相匹配。我的问题是,当我有更多行数据时,如何在代码的末尾重命名语句和输出值? – user634455 2012-04-12 14:50:25

+0

即使我不包括在我的输出数据的V1-V6值,如果它变得太长时间,我是否需要写代码的最后一部分(变量列表)? – user634455 2012-04-12 14:56:34

+0

我可以用它来重命名vv1-vv6 = v1-v6。但是这种相同的对流不适用于输出vv1-vv6 = v [i,1] -v [i,6];任何人有想法? – user634455 2012-04-12 16:39:31