SAS / IML:如何在RANDNORMAL中使用单个方差组件

时间:2014-09-18 21:21:55

标签: sas sas-iml

这是一个编程问题,但我先给你一些统计数据背景。该问题涉及混合效应位置比例模型(即,异构方差)的数据sim的一部分。我尝试使用IML中的RANDNORMAL函数模拟两个MVN方差组件。由于两个方差分量都是异构的,因此RANDNORMAL使用的差异会因人而异。因此,我需要IML来选择特定的行(例如,行1 =人1)并在移动到下一行之前使用RANDNORMAL函数,依此类推。

下面的示例代码适用于2个人。我使用DO来遍历每个人的特定方差分量(VC1和VC2)。我收到错误:"模块RANDNORMAL在退出之前的呼叫之前再次被调用。"我假设我在DO循环中需要某种BREAK或EXIT函数,但我没有尝试过工作。

PROC IML;
    ColNames = {"ID" "VC1" "VC2"};
    A = {1 2 3, 
         2 8 9};
    PRINT A[COLNAME=ColNames];
    /*Set men of each variance component to 0*/ 
    MeanVector = {0, 0};
    /*Loop through each person's data using THEIR OWN variances*/
    DO i = 1 TO 2;
        VC1 = A[i,2];
        VC2 = A[i,3];
        CovMatrix = {VC1 0, 
                     0   VC2};
        CALL RANDSEED(1);  
        U = RANDNORMAL(2, MeanVector, CovMatrix);
    END;
QUIT;

感谢任何帮助。哦,我正在使用SAS 9.4。

2 个答案:

答案 0 :(得分:1)

你想要移动一些东西,但大多数时候你不想重写U两次:你需要写第一行,然后是第二行,如果我明白了什么你正试图这样做。下面的效率也更高一些,因为我j()U和_cv矩阵而不是每次通过循环重新构建(这很慢)。

proc iml;

  a = {1 2 3,2 8 9};
  print(a);
  _mv = {0,0};
  U = J(2,2);
  _cv = J(2,2,0);
  CALL RANDSEED(1);   

  do i = 1 to 2;
    _cv[1,1] = a[i,2];
    _cv[2,2] = a[i,3];
    U[i,] = randnormal(1,_mv, _cv);
  end;
  print(u);
quit;

答案 1 :(得分:1)

你的错误是行

CovMatrix = {VC1 0, 0   VC2}; /* wrong */

这不是有效的SAS / IML语法。相反,使用@ Joe的方法或使用

 CovMatrix = (VC1 || 0) // (0 || VC2);

有关详细信息,请参阅文章"How to build matrices from expressions."

您可能也对本文介绍如何使用块对角矩阵执行此模拟感兴趣:"Constructing block matrices with applications to mixed models."