Writing data from a matrix to a SAS data set

16

In a previous post, I showed how to read data from a SAS data set into SAS/IML matrices or vectors. This article shows the converse: how to use the CREATE, APPEND, and CLOSE statements to create a SAS data set from data stored in a matrix or in vectors.

Creating a SAS Data Set from SAS/IML Vectors

You can use the CREATE and APPEND statements to write a SAS data set from SAS/IML vectors. The following statements create three different SAS/IML vectors. The data in those vectors are then written to a data set called MyData in the Work library:

proc iml;
/** create SAS data set from vectors **/
y = {1,0,3,2,0,3}; /** 6 x 1 vector **/
z = {8,7,6,5,6};   /** 5 x 1 vector **/
c = {A A A B B B}; /** 1 x 6 character vector **/
 
create MyData var {y z c}; /** create data set **/
append;       /** write data in vectors **/
close MyData; /** close the data set **/

The CREATE statement opens Work.MyData for writing. The program creates the numerical vectors y and z, and the character vector c. The APPEND statement writes the values of the vectors listed on the VAR clause of the CREATE statement. The numeric vectors create numeric variables; the character vector creates a character variable, which in this case has length 1. The names of the variables in the data set are y, z, and c, which are the same names as the SAS/IML vectors.

The CLOSE statement closes the data set. It is a good programming practice to close data sets when you are finished writing the data.

Notice that it does not matter if a vector is a row vector or a column vector: each element of a vector is written to an observation in the data set. If the vectors do not contain the same number of elements, then the variables that result from the shorter vectors are padded with missing values. For example, the last observation for the z variable contains a missing value, as shown by the following call to PROC PRINT:

proc print data=MyData; run;

Creating a SAS Data Set from a SAS/IML Matrix

Use the FROM clause on the CREATE and APPEND statements to create a data set from a matrix. You can specify names for the data set variables by using the COLNAME= option to the FROM clause, as shown in the following example:

proc iml;
/** create SAS data set from a matrix **/
x = {1 2 3,
     4 5 6,
     7 8 9,
     3 2 1 }; /** 4 x 3 matrix **/
create MyData2 from x[colname={"q" "r" "s"}];
append from x;
close MyData2;

For this example, the names of the variables in the data set are q, r, and s. If you do not explicitly specify names for the data set variables, the variables are named COL1, COL2, and so forth.

proc print data=MyData2; run;

For more details on reading and writing data in the SAS/IML language, see Chapter 3 of Statistical Programming with SAS/IML Software.

Share

About Author

Rick Wicklin

Distinguished Researcher in Computational Statistics

Rick Wicklin, PhD, is a distinguished researcher in computational statistics at SAS and is a principal developer of PROC IML and SAS/IML Studio. His areas of expertise include computational statistics, simulation, statistical graphics, and modern methods in statistical data analysis. Rick is author of the books Statistical Programming with SAS/IML Software and Simulating Data with SAS.

16 Comments

  1. Hi Rick,

    Would you be able to give us an example of how you would use the create and append if a do loop
    where the data set name is different for each.

    For example:

    proc iml;
    /** create SAS data set from a matrix **/

    Do i = 1 to 5;

    x = {1 2 3, 4 5 6, 7 8 9, 3 2 1 }; /** 4 x 3 matrix **/
    p = x*i;

    create MyData_&i from x[colname={"q" "r" "s"}];
    append from p;
    close MyData_&i;

    So the resulting data sets would be:

    MyData_1
    MyData_2
    MyData_3
    MyData_4
    MyData_5

    Thanks,

    Scott

  2. Worked like a charm. Thanks Rick. Here's what I did in case others need it.

    Proc iml;
    PCOR = {1.00 0.40 0.40,
    0.40 1.00 0.40,
    0.40 0.40 1.00};

    dsNames = {A B C}; /* specify names of data sets */
    do i = 1 to ncol(dsNames);
    pvar = diag(vecdiag(pcor))*i;
    create(dsNames[i]) from pvar; /* create work.A, then work.B, and so on */
    append from pvar;
    close (dsNames[i]);
    end;

  3. Colwel

    I run above program but there are some errors pls guide me

    571 Proc iml;
    NOTE: IML Ready
    572 PCOR = {1.00 0.40 0.40,
    573 0.40 1.00 0.40,
    574 0.40 0.40 1.00};
    575 dsNames={A B C};
    575! /* specify names of data sets */
    576 do i = 1 to 5;
    577 pvar = diag(vecdiag(pcor))*i;
    578 create (dsNames[i]) from pvar;
    -
    22
    76
    ERROR 22-322: Expecting a name.

    ERROR 76-322: Syntax error, statement will be ignored.

    579 append from pvar;
    580 close (dsNames[i]);
    -
    22
    200
    ERROR 22-322: Syntax error, expecting one of the following: a name, ;.

    ERROR 200-322: The symbol is not recognized and will be ignored.

    581 end;

      • thanks for replying

        But my problem is related to earlier discussion on this page and I am running following program as mentioned by colwel

        But facing some error and not getting out put
        my sas version is 9.02

        kindly guide me
        thanks

          • I am using SAS 9.3 but still following program is not running

            Proc iml;
            PCOR = {1.00 0.40 0.40,
            0.40 1.00 0.40,
            0.40 0.40 1.00};
            dsNames = {A B C}; /* specify names of data sets */
            do i = 1 to ncol(dsNames);
            pvar = diag(vecdiag(pcor))*i;
            create(dsNames[i]) from pvar; /* create work.A, then work.B, and so on */
            append from pvar;
            close (dsNames[i]);
            end;

            Error:
            5078 create(dsNames[i]) from pvar;
            -
            22
            76
            ERROR 22-322: Expecting a name.

  4. Pingback: Generate uniform data in a simplex - The DO Loop

  5. Does IML allow for matrices to have different counts by row? That is, something like this:

    X = {1 2 3,
    2 4,
    3 4 5};
    Thanks in advance.
    Dave

    • Rick Wicklin

      No. SAS/IML follows the rules of linear algebra, which requires a rectangular array of numbers. You can use a zero cell or a missing value to indicate which column is omitted for the 2nd row of your example.

  6. Pingback: Write to a SAS data set from inside a SAS/IML loop - The DO Loop

  7. Pingback: Write numeric and character matrices to a data set from SAS/IML - The DO Loop

Leave A Reply

Back to Top