I'm filling the rows of an array, say W, with random weights that sum to 1.
So W[,+] is = a column vector of 1s.
I can do this somewhat manually but any "cool" IML tips are appreciated.
You could try something like this:
rows = 50;
cols = 10;
W = j(rows,cols,0.0);
call randgen(W,'Normal');
zz = W[,+];
W = diag(1/zz)*W;
You could try something like this:
rows = 50;
cols = 10;
W = j(rows,cols,0.0);
call randgen(W,'Normal');
zz = W[,+];
W = diag(1/zz)*W;
Clever, thank you.
Tricky follow up -- How to fill rows of an array with random POSITIVE weights that sum to 1?
My answer: Change 'Normal' to 'Uniform'.
All you need is a relatively small modification to the original code:
rows = 50;
cols = 10;
W = j(rows,cols,0.0);
call randgen(W,'Normal');
W = abs(W);
zz = W[,+];
W = diag(1/zz)*W;
It is inefficient to generate a large diagonal matrix and use matrix multiplication for this problem. Jusrt use elementwise multiplication and division:
W = W / W[,+];
I also would not use the standard normal distribution since the expected value of the sum is zero. Use "Uniform" or some other positive distribution.
Thanks, Rick & all
What I'm doing is doing a small simulation of stock portfolio weights with some turnover.
Here's the code that I came up with:
nrow = 50; ncol = 5; w = j(nrow,ncol,.); do i = 1 to nrow(w); if ( (i = 1) | (mod(i,10) = 0) ) then do; x = j(1,ncol,.); call randgen(x,'uni'); w[i,] = x / x[+]; end; else do; w[i,] = w[i-1,]; end; end; print ((1:nrow)`) w[f=5.2] (w[,+])[l="w[,+]"];
and here's some output with line breaks manually added when the weights change:
W w[,+] 1 0.32 0.16 0.05 0.34 0.13 1 2 0.32 0.16 0.05 0.34 0.13 1 3 0.32 0.16 0.05 0.34 0.13 1 4 0.32 0.16 0.05 0.34 0.13 1 5 0.32 0.16 0.05 0.34 0.13 1 6 0.32 0.16 0.05 0.34 0.13 1 7 0.32 0.16 0.05 0.34 0.13 1 8 0.32 0.16 0.05 0.34 0.13 1 9 0.32 0.16 0.05 0.34 0.13 1 10 0.34 0.20 0.10 0.18 0.18 1 11 0.34 0.20 0.10 0.18 0.18 1 12 0.34 0.20 0.10 0.18 0.18 1 13 0.34 0.20 0.10 0.18 0.18 1 14 0.34 0.20 0.10 0.18 0.18 1 15 0.34 0.20 0.10 0.18 0.18 1 16 0.34 0.20 0.10 0.18 0.18 1 17 0.34 0.20 0.10 0.18 0.18 1 18 0.34 0.20 0.10 0.18 0.18 1 19 0.34 0.20 0.10 0.18 0.18 1 20 0.04 0.33 0.33 0.23 0.07 1 21 0.04 0.33 0.33 0.23 0.07 1
You could also use the REPEAT and SHAPE function rather than the IF-THEN/ELSE logic:
proc iml;
call randseed(1,1);
N = 10; /* group size */
k = 5; /* this many different sets of weights */
nrow = N*k;
ncol = 5;
x = j(k, ncol);
call randgen(x,'uni');
x = x / x[,+];
w = repeat(x, 1, N); /* repeat N times */
w = shape(w, nrow, ncol); /* reshape */
print ((1:nrow)`) w[f=5.2] (w[,+])[l="w[,+]"];
SIMPLEX I guess.
http://blogs.sas.com/content/iml/2012/10/08/generate-uniform-data-in-a-simplex.html
proc iml;
x=j(50,10);
call randseed(12345678);
call randgen(x,'exp');
want=x/x[,+];
print want (want[,+]);
quit;
OUTPUT:
0.0648301 0.1079199 0.0228608 0.0681767 0.0458107 0.1065728 0.035765 0.2783503 0.1591276 0.1105859 1
0.4234449 0.024438 0.0264153 0.0053757 0.1316303 0.0977695 0.0967949 0.1554417 0.0352746 0.003415 1
0.1742008 0.0759239 0.0790483 0.0362075 0.3430713 0.0753865 0.0047603 0.1608051 0.0364158 0.0141804 1
0.1496225 0.2156779 0.0218255 0.0119062 0.0464079 0.0938399 0.0561757 0.0284336 0.2126586 0.1634523 1
0.0821396 0.0694797 0.0114859 0.1006526 0.0258224 0.1618293 0.2311992 0.0830032 0.0934525 0.1409357 1
0.1093307 0.2438623 0.0497669 0.1584296 0.071123 0.1400462 0.1286981 0.0390086 0.0250962 0.0346384 1
0.0451511 0.0064224 0.0948597 0.0111992 0.5084102 0.0019754 0.1812584 0.0505699 0.0485943 0.0515594 1
0.2035252 0.1788939 0.0294778 0.1373246 0.0646985 0.1397168 0.1028051 0.0405142 0.0251605 0.0778835 1
0.1220822 0.0350727 0.0461714 0.1443178 0.0068658 0.0418933 0.0410991 0.1023764 0.3349438 0.1251775 1
0.192122 0.0198897 0.0443545 0.4800069 0.038623 0.0503297 0.0209156 0.0113073 0.1381878 0.0042635 1
0.0313845 0.032611 0.4310741 0.0631909 0.1268576 0.0189176 0.0186431 0.1067634 0.0883492 0.0822086 1
0.04946 0.1710766 0.1096673 0.1645587 0.00912 0.0177279 0.0843549 0.0618942 0.0157517 0.3163887 1
0.0856845 0.091644 0.3719427 0.0193887 0.0370685 0.0996453 0.0806509 0.016613 0.120476 0.0768863 1
0.0686816 0.2127106 0.0546567 0.0243939 0.0522649 0.5152068 0.0140101 0.016338 0.0323669 0.0093705 1
0.0694356 0.0849727 0.0147498 0.0806223 0.4150253 0.0003022 0.1023573 0.0317083 0.1042205 0.096606 1
0.0993378 0.1399166 0.0798931 0.0586677 0.1379175 0.0682676 0.055003 0.065054 0.0463719 0.2495708 1
0.2213328 0.0285721 0.0132931 0.1124621 0.155769 0.0497151 0.123782 0.0916017 0.0832244 0.1202477 1
0.0468314 0.0838247 0.0552836 0.0994477 0.1789177 0.1194976 0.2082629 0.0390825 0.0796091 0.0892429 1
0.0521256 0.2763195 0.1143827 0.1916011 0.0366984 0.0073285 0.1699003 0.0242829 0.0166806 0.1106805 1
0.0468104 0.0706336 0.0565395 0.302155 0.1257473 0.1642419 0.0964451 0.0293752 0.1077106 0.0003415 1
0.0163002 0.1576576 0.0013836 0.0559424 0.2001715 0.0234375 0.1309152 0.1452492 0.0242355 0.2447073 1
0.0952232 0.2992329 0.0895257 0.0004979 0.1149403 0.0099626 0.2233921 0.0117509 0.0325163 0.1229581 1
0.0885059 0.0114501 0.1387571 0.1362204 0.1518603 0.1607144 0.1240111 0.0054885 0.0437803 0.1392118 1
0.2873259 0.198567 0.0610863 0.1149705 0.0490104 0.0072253 0.0295308 0.0278863 0.0784847 0.1459127 1
0.0408225 0.1391669 0.014964 0.2021518 0.0708116 0.0467588 0.122211 0.0357326 0.3242727 0.0031081 1
0.0817365 0.0758352 0.0144944 0.0470948 0.0449682 0.0448977 0.4455887 0.0578968 0.1363329 0.0511548 1
0.1017831 0.0109214 0.2529835 0.0371874 0.112752 0.2030563 0.12295 0.0099204 0.0733185 0.0751275 1
0.1345763 0.0941077 0.0111666 0.1838734 0.0745686 0.1568742 0.0172288 0.0960575 0.0462091 0.1853378 1
0.1215532 0.1796445 0.140381 0.0794795 0.1966997 0.0618683 0.0573633 0.0280515 0.045623 0.0893361 1
0.0886926 0.0826849 0.1180034 0.1195067 0.2298101 0.0561909 0.1726511 0.0473202 0.042588 0.0425519 1
0.0221349 0.2454024 0.0731778 0.0972758 0.1484495 0.1146809 0.0682833 0.1102719 0.0398125 0.0805109 1
0.0059513 0.1131108 0.0746576 0.155628 0.0269511 0.0028046 0.0602186 0.0816559 0.4280088 0.0510133 1
0.1434559 0.1105319 0.2193216 0.2992068 0.0090997 0.094333 0.004108 0.0381938 0.0160713 0.065678 1
0.2217303 0.0083789 0.0682749 0.0472224 0.0582704 0.214617 0.0951426 0.0690515 0.0918572 0.1254549 1
0.0257245 0.1350998 0.0482849 0.0368581 0.3251395 0.0444965 0.0016627 0.0538019 0.1295458 0.1993864 1
0.0552674 0.3809986 0.0230707 0.1292086 0.0607931 0.0350846 0.081587 0.0128453 0.2025788 0.0185658 1
0.1075428 0.2170157 0.0016591 0.1320372 0.0278715 0.0220208 0.0072232 0.006267 0.4508596 0.027503 1
0.0538039 0.0147589 0.1754015 0.3366715 0.0996219 0.0623733 0.0187091 0.1286895 0.0579247 0.0520459 1
0.2700347 0.0066957 0.0363263 0.1981466 0.0269642 0.1036702 0.1736521 0.143819 0.0106429 0.0300483 1
0.0846778 0.1937979 0.0152793 0.1125825 0.2342719 0.1340418 0.0110438 0.0352578 0.1585657 0.0204814 1
0.2608073 0.0834937 0.1996036 0.0268523 0.0296746 0.0969509 0.0336205 0.1788419 0.0648468 0.0253084 1
0.0216348 0.0723853 0.0353566 0.2231069 0.0489804 0.1151267 0.161347 0.1784846 0.0481179 0.0954597 1
0.0235029 0.1019599 0.0160237 0.1568932 0.0284969 0.451111 0.0073747 0.0224931 0.0128773 0.1792673 1
0.0786213 0.1134368 0.084441 0.1072957 0.1786074 0.0117017 0.0418253 0.1039958 0.2714284 0.0086467 1
0.1188689 0.1365063 0.0574021 0.1620486 0.00761 0.029641 0.0075762 0.4014064 0.0195824 0.0593581 1
0.1233485 0.2155991 0.093227 0.1223969 0.2207401 0.1033752 0.0009773 0.0698694 0.025668 0.0247985 1
0.0896171 0.1503852 0.094263 0.0512589 0.0111831 0.0241438 0.1117627 0.0350864 0.05815 0.3741497 1
0.003393 0.2015791 0.1296677 0.0225987 0.2003895 0.03059 0.0559043 0.1282544 0.1612973 0.0663259 1
0.0627416 0.3756903 0.0962819 0.0039439 0.099763 0.1087502 0.0080005 0.0010637 0.1721685 0.0715964 1
0.0189294 0.1640884 0.2147821 0.2193504 0.1107373 0.1594841 0.0456326 0.0120227 0.0533695 0.0016033 1
Don't miss out on SAS Innovate - Register now for the FREE Livestream!
Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.
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.