turn on suggestions

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

Showing results for

Find a Community

Topic Options

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

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

04-07-2017 05:04 PM - edited 04-07-2017 05:09 PM

```
/* sample from a mixture distribution */
%let N = 5000;
data States(drop=i);
call streaminit(12345);
array prob [2] _temporary_ (0.7 0.3);
do i = 1 to &N;
type = rand("Table", of prob[*]);
if type=1 then Return = rand("Normal", 0, 3); /* state 1 */
else Return = rand("Normal", 5, 10); /* steta 2 */
output;
end;
run;
proc means data = States mean var std maxdec=5 missing n nmiss ; *Taking mean and std of return in state 1 and 2;
var return;
class type;
output out=Statesmu mean=mu var=var std=std;
title 'Mean, Variance and Standard Deviation of the return in 2 states';
run;
data work.States; *Getting A,B,C,D from the table;
set work.States;
Pi = constant("pi");
Res1 = Return + 0.06780;
Res2 = Return - 5.21819;
UncDen = (0.7/(sqrt(2*3.141592657)*2.98245))*(exp(((-0.5)*((Res1)/2.98245))**2)) + (0.3/(sqrt(2*3.141592657)*9.96359))*(exp(((-0.5)*((Res2)/9.96359))**2));
ConA = (1/(sqrt(2*3.141592657)*2.98245))*(exp(((-0.5)*((Res1)/2.98245))**2));
ConB = (1/(sqrt(2*3.141592657)*9.96359))*(exp(((-0.5)*((Res2)/9.96359))**2));
pi1 = 3400/5000;
pi2 = 1600/5000;
ConprobA = ConA*pi1;
ConprobB = ConB*pi2;
PrC = ConprobA/UncDen;
PrD = ConprobB/UncDen;
Run;
```

Hi, I have a basic question with matrix calculation.

If: I have 15 columns variables say 5000 by 15

Need: take only column 15 and inverse it, and then multiply with a 2 by 1 vector.

Can anyone give some hint how to do that?

I don't know how to take a column and treat it as a vector or combine two columns and treat it as a vector.

Example: As shown in the example, Iet's say I need to combine ConprobA and ConprobB as a vector and then multiply with a 2 by 1 vector.

Any suggestion would be appreciated. Thank you.

Accepted Solutions

Solution

04-11-2017
03:01 PM

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Xusheng

04-09-2017 06:10 AM

In the DATA step, double vertical bars (||) is the operator for string concatenation. So the following DATA step creates a CHARACTER variable z, which is the string-wise concatenation of x and y:

data a;

x=1.23; y=4.56; z = x || y;

put z;

run;

In contrast, the horizontal concatenation operator (||) in SAS/IML concatenates two vectors into a matrix that has two columns. So i n PROC IML the same statement results in a 1x2 vector:

proc iml;

x=1.23; y=4.56; z = x || y;

print z;

run;

All Replies

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Xusheng

04-07-2017 08:38 PM

```
SAS/IML Software and Matrix Computations
see
https://goo.gl/w8IrLt
https://communities.sas.com/t5/SAS-IML-Software-and-Matrix/Convert-a-column-to-a-vector/m-p/348302
"I don't know how to take a column and treat it as a vector or combine two columns and treat it as a vector.
Example: As shown in the example, Iet's say I need to combine ConprobA and ConprobB as
a vector and then multiply with a 2 by 1 vector."
You can use IML directly for this problem, probably simpler.
This R solution can be converted to IML easily or
you can use the IML interface to R.
The free version of WPS does not limit the size of the SAS dataset
created by 'proc r'.
HAVE1
=====
Up to 40 obs WORK.STATES total obs=10
Obs CONPROBA CONPROBB
1 0.09303 0.013450
2 0.09269 0.013473
3 0.28243 0.018018
4 0.14858 0.016055
5 0.10607 0.013096
and
HAVE2
=====
obs sum2col
1 1
2 1
WANT
Obs CONPROBA CONPROBB SUM2COL RES
1 0.09303 0.013450 X 1 0.1064845
2 0.09269 0.013473 1 0.1061672
3 0.28243 0.018018 0.3004481
4 0.14858 0.016055 0.1646374
5 0.10607 0.013096 0.1191660
WORKING CODE
===========
res<-crossprod(t(have1), have2);
* _ _ _
_ __ ___ __ _| | _____ __| | __ _| |_ __ _
| '_ ` _ \ / _` | |/ / _ \_____ / _` |/ _` | __/ _` |
| | | | | | (_| | < __/_____| (_| | (_| | || (_| |
|_| |_| |_|\__,_|_|\_\___| \__,_|\__,_|\__\__,_|
;
libname sd1 "d:/sd1";
options validvarname=upcase;
/* sample from a mixture distribution */
%let N = 5000;
data States(drop=i);
call streaminit(12345);
array prob [2] _temporary_ (0.7 0.3);
do i = 1 to &N;
type = rand("Table", of prob[*]);
if type=1 then Return = rand("Normal", 0, 3); /* state 1 */
else Return = rand("Normal", 5, 10); /* steta 2 */
output;
end;
run;
proc means data = States mean var std maxdec=5 missing n nmiss ;
*Taking mean and std of return in state 1 and 2;
var return;
class type;
output out=Statesmu mean=mu var=var std=std;
title 'Mean, Variance and Standard Deviation of the return in 2 states';
run;
data sd1.have1(keep=CONPROBA CONPROBB);
*Getting A,B,C,D from the table;
set work.States(obs=10);
Pi = constant("pi");
Res1 = Return + 0.06780;
Res2 = Return - 5.21819;
UncDen = (0.7/(sqrt(2*3.141592657)*2.98245))*(exp(((-0.5)*((Res1)/2.98245))**2)) +
(0.3/(sqrt(2*3.141592657)*9.96359))*(exp(((-0.5)*((Res2)/9.96359))**2));
ConA = (1/(sqrt(2*3.141592657)*2.98245))*(exp(((-0.5)*((Res1)/2.98245))**2));
ConB = (1/(sqrt(2*3.141592657)*9.96359))*(exp(((-0.5)*((Res2)/9.96359))**2));
pi1 = 3400/5000;
pi2 = 1600/5000;
ConprobA = ConA*pi1;
ConprobB = ConB*pi2;
PrC = ConprobA/UncDen;
PrD = ConprobB/UncDen;
Run;
data sd1.have2;
sum2col=1;
output;
sum2col=1;
output;
run;quit;
* _ _ _
___ ___ | |_ _| |_(_) ___ _ __
/ __|/ _ \| | | | | __| |/ _ \| '_ \
\__ \ (_) | | |_| | |_| | (_) | | | |
|___/\___/|_|\__,_|\__|_|\___/|_| |_|
;
%utl_submit_wps64('
libname sd1 "d:/sd1";
options set=R_HOME "C:/Program Files/R/R-3.3.2";
libname wrk "%sysfunc(pathname(work))";
proc r;
submit;
source("c:/Program Files/R/R-3.3.2/etc/Rprofile.site",echo=T);
library(haven);
have1<-as.matrix(read_sas("d:/sd1/have1.sas7bdat"));
have2<-as.matrix(read_sas("d:/sd1/have2.sas7bdat"));
res<-crossprod(t(have1), have2);
endsubmit;
import r=res data=wrk.reswps;
run;quit;
');
proc print data=reswps;
run;quit;
Obs V1
1 0.10648
2 0.10617
3 0.30045
4 0.16464
5 0.11917
6 0.10472
7 0.10631
8 0.12975
9 0.11549
10 1.45924
```

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to rogerjdeangelis

04-08-2017 01:04 PM

thank you, I need study your reply later to make them work in my sas.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Xusheng

04-08-2017 07:17 AM

There are many ways to multiply in the SAS/IML matrix.

I don't understand some of your requests. What do you mean by "take only column 15 and inverse it"? (by the way, your example only has 14 columns...)

Also, when you say you want to multiply a column vector by a 2x1 vector, what do you mean? If v is a 2x1 vector, do you want the product x*v` or something else? Please provide an example with numbers for N=5.

The only lines in the DATA step that look similar to your request are the statements

ConprobA = ConA*pi1;

ConprobB = ConB*pi2;

Here are some IML statements that might give you some feeling for how to extract columns and multiply columns together:

```
proc iml;
use States;
read all var _NUM_ into X[colname=varNames];
close States;
print varNames;
/* general exaples of extracting columns */
A = X[ ,14]; /* get column 14 */
B = X[ ,13:14]; /* get columns 13-14 */
Y = X[ , {"ConprobA" "ConprobB"}]; /* get the 2 columns */
p = {0.68, 0.32}; /* 2 x 1 vector */
LinComb = Y * v; /* form linear combination of columns of Y */
print (LinComb[1:5,]); /* print only 5 rows */
Con = Y # v`; /* elementwise multiplication */
print (Con[1:5,])[colname={"ConA" "ConB"}];
```

If you are looking for a good overview of basic matrix multiplication and manipulations in SAS/IML, I recommend "Getting Started with the SAS/IML Language"

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Rick_SAS

04-08-2017 01:23 PM

Thank you for replying and sorry for the confusion.

I combined column 13 and 14 yesterday and got the conlumn 15 like that:

P = ConprobA || ConprobB;

Here is the sample of 5 for what I mean:

```
Obs CONPROBA CONPROBB n
1 0.09303 0.013450 0.093030.013450
2 0.09269 0.013473 0.092690.013473
3 0.28243 0.018018 0.282430.018018
4 0.14858 0.016055 0.148580.016055
5 0.10607 0.013096 0.106070.013096
```

So if ConprobA and ConprobB is the column 13 and 14, the column 15 would be n.

What I mean by take only column 15 is I want to treat column n as a vector. And I want to inverse it.

Then multiply with 2x1 vector I mean the column 15 multiply with a 2x1 vector.

But my way doesn't work yesterday.

I will read the link that you provide.

Solution

04-11-2017
03:01 PM

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Xusheng

04-09-2017 06:10 AM

In the DATA step, double vertical bars (||) is the operator for string concatenation. So the following DATA step creates a CHARACTER variable z, which is the string-wise concatenation of x and y:

data a;

x=1.23; y=4.56; z = x || y;

put z;

run;

In contrast, the horizontal concatenation operator (||) in SAS/IML concatenates two vectors into a matrix that has two columns. So i n PROC IML the same statement results in a 1x2 vector:

proc iml;

x=1.23; y=4.56; z = x || y;

print z;

run;

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Rick_SAS

04-11-2017 03:01 PM

Thank you Rick, that addressed my question.