BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Xusheng
Obsidian | Level 7
/* 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.

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ

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;

 

View solution in original post

6 REPLIES 6
rogerjdeangelis
Barite | Level 11
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
Xusheng
Obsidian | Level 7

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

Rick_SAS
SAS Super FREQ

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"

 

Xusheng
Obsidian | Level 7

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. 

 

Rick_SAS
SAS Super FREQ

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;

 

Xusheng
Obsidian | Level 7

Thank you Rick, that addressed my question.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

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.

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 6 replies
  • 3465 views
  • 1 like
  • 3 in conversation