Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Options

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

🔒 This topic is **solved** and **locked**.
Need further help from the community? Please
sign in and ask a **new** question.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Posted 07-02-2017 11:09 AM
(1395 views)

Hello All,

There are two matrices with missing values. I try to do the horizontal direct product (HDIR) in SAS, but I am receiving the following error: "ERROR: Matrix c has not been set to a value." It seems that most matrix operators and functions in SAS do not support missing values. Could you please help me figure this out? Any assistance that can be provided is much appreciated.

Here is an example:

proc iml;

a = {1 .,

2 4,

3 6};

b = {0 2,

. 1,

0 -1};

c = hdir(a, b);

print a b c;

Here is the Log:

1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;

59

60 proc iml;

NOTE: IML Ready

61 a = {1 .,

62 2 4,

63 3 6};

64 b = {0 2,

65 . 1,

66 0 -1};

67 c = hdir(a, b);

ERROR: (execution) Invalid argument or operand; contains missing values.

operation : HDIR at line 67 column 9

operands : a, b

a 3 rows 2 cols (numeric)

1 .

2 4

3 6

b 3 rows 2 cols (numeric)

0 2

. 1

0 -1

statement : ASSIGN at line 67 column 1

68 print a b c;

ERROR: Matrix c has not been set to a value.

statement : PRINT at line 68 column 1

69

70 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;

82

1 ACCEPTED SOLUTION

Accepted Solutions

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

As Paige said, use the definition to write your own function. You didn't say what you expect the result to be, but I assume you want to propagate the missing like this:

```
proc iml;
start HDir2(a, b);
c = j(nrow(a), ncol(a)*ncol(b), .);
do i = 1 to ncol(a);
startCol = (i-1)*ncol(b) + 1;
endCol = i*ncol(b);
c[ , startCol:endCol] = a[ ,i] # b;
end;
return c;
finish;
a = {1 .,
2 4,
3 6};
b = {0 2,
. 1,
0 -1};
c = HDir2(a, b);
print c;
```

9 REPLIES 9

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

You'd have to write your own Function in IML to do what you want.

--

Paige Miller

Paige Miller

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Although SAS/IML propagates missing values for elementwise operations, missing values do not propagate for vector and matrix operations. For a discussion and some workarounds, see "Matrix multiplication with missing values in SAS."

What is the application you are trying to compute? Are you creating a design matrix of interaction effects, or something else? Also, what answer do you EXPECT to get from your example?

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Thanks very much for your reply. I am doing my research on interaction effects. We have a large dataset with 17 interested predictors. All the predictor variables have missing values. I need to create a new data set with all the 2-way interaction effects. I think horizontal direct product (HDIR) in SAS can help me create those interaction effects. First, I have successfully read all the predictor variables into a matrix (denoted by matrix_L18_Q34) in SAS. Then I try to do use the code "interaction_matrix_L18_Q34 = hdir(matrix_L18_Q34, matrix_L18_Q34)". However, it shows that "ERROR: (execution) Matrix has not been set to a value."

Here is the log:

1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;

59

60 /* read all interested predictor variables (a to q) into matrix matrix_L18_Q34 */

61 proc iml;

NOTE: IML Ready

62 use L18_Q34;

63 read all var ("a":"q") into matrix_L18_Q34[colname=varNames];

64 print varNames;

65 print matrix_L18_Q34;

66

67

68 /*Horizontal Direct Product*/

NOTE: Exiting IML.

NOTE: PROCEDURE IML used (Total process time):

real time 2.64 seconds

user cpu time 2.61 seconds

system cpu time 0.00 seconds

memory 4135.40k

OS Memory 32168.00k

Timestamp 07/02/2017 07:29:14 PM

Step Count 24 Switch Count 50

Page Faults 0

Page Reclaims 847

Page Swaps 0

Voluntary Context Switches 157

Involuntary Context Switches 272

Block Input Operations 0

Block Output Operations 1440

69 proc iml;

NOTE: IML Ready

70 interaction_matrix_L18_Q34 = hdir(matrix_L18_Q34, matrix_L18_Q34);

ERROR: (execution) Matrix has not been set to a value.

operation : HDIR at line 70 column 34

operands : matrix_L18_Q34, matrix_L18_Q34

matrix_L18_Q34 0 row 0 col (type ?, size 0)

matrix_L18_Q34 0 row 0 col (type ?, size 0)

statement : ASSIGN at line 70 column 1

71 print interaction_matrix_L18_Q34;

ERROR: Matrix interaction_matrix_L18_Q34 has not been set to a value.

statement : PRINT at line 71 column 1

72

73 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;

85

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

I read "Matrix multiplication with missing values in SAS" before. However, it does not answer my questions on HDIR.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

As Paige said, use the definition to write your own function. You didn't say what you expect the result to be, but I assume you want to propagate the missing like this:

```
proc iml;
start HDir2(a, b);
c = j(nrow(a), ncol(a)*ncol(b), .);
do i = 1 to ncol(a);
startCol = (i-1)*ncol(b) + 1;
endCol = i*ncol(b);
c[ , startCol:endCol] = a[ ,i] # b;
end;
return c;
finish;
a = {1 .,
2 4,
3 6};
b = {0 2,
. 1,
0 -1};
c = HDir2(a, b);
print c;
```

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Thanks very much. You answer really helps.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

How about this one ?

```
proc iml;
a = {1 .,
2 4,
3 6};
b = {0 2,
. 1,
0 -1};
aa=a;
bb=b;
aa[loc(a=.)]=0;
bb[loc(b=.)]=0;
c = hdir(aa, bb);
a1=(a=.);
b1=(b=.);
a2=j(nrow(a),ncol(a));
b2=j(nrow(b),ncol(b));
a1b2=hdir(a1,b2);
a2b1=hdir(a2,b1);
c[loc(a1b2=1)]=.;
c[loc(a2b1=1)]=.;
print c;
quit;
```

SAS Output

c | |||
---|---|---|---|

0 | 2 | . | . |

. | 2 | . | 4 |

0 | -3 | 0 | -6 |

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Assuming the matrices you are working with are not large, it might be easier to calculate more than necessary and then throw away the unwanted parts.

```
proc iml;
a = {1 .,
2 4,
3 6};
b = {0 2,
. 1,
0 -1};
n = nrow( a );
c = (a @ b)[ do(1, n#n, n+1), ];
print a b c;
```

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Thanks very much. I like your ideas.

**Available on demand!**

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

Multiple Linear Regression in SAS

Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.

Find more tutorials on the SAS Users YouTube channel.