Statistical programming, matrix languages, and more

Convert a column to a vector

Accepted Solution Solved
Reply
Contributor
Posts: 48
Accepted Solution

Convert a column to a vector

[ Edited ]
/* 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
SAS Super FREQ
Posts: 3,420

Re: Convert a column to a vector

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


All Replies
Valued Guide
Posts: 505

Re: Convert a column to a vector

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
Contributor
Posts: 48

Re: Convert a column to a vector

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

SAS Super FREQ
Posts: 3,420

Re: Convert a column to a vector

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"

 

Contributor
Posts: 48

Re: Convert a column to a vector

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
SAS Super FREQ
Posts: 3,420

Re: Convert a column to a vector

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;

 

Contributor
Posts: 48

Re: Convert a column to a vector

Thank you Rick, that addressed my question.

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 6 replies
  • 283 views
  • 0 likes
  • 3 in conversation