Hi list
I'm stuck in the middle of an "impossible?" problem. I need to create datasets with the following characteristics: If nvars=3: x1 x2 x3 0 0 0 1 0 0 0 1 0 0 0 1 1 1 0 1 0 1 0 1 1 1 1 1 Total number of patterns:8 If nvars=4: x1 x2 x3 x4 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1 1 0 0 1 0 1 0 1 0 0 1 0 1 1 0 0 1 0 1 0 0 1 1 1 1 1 0 1 1 0 1 1 0 1 1 1 1 1 1 Total number of patters:16 If nvars=5: x1 x2 x3 x4 x5 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 1 0 1 0 0 1 0 0 1 0 1 0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 1 0 0 1 0 0 1 1 0 0 0 1 0 1 0 0 0 1 1 1 1 1 0 0 1 1 0 1 0 1 1 0 0 1 1 0 1 1 0 1 0 1 0 1 1 0 0 1 1 0 1 1 1 0 0 1 1 0 1 0 1 0 1 1 0 0 1 1 1 1 1 1 1 1 Total number of patters:32 General rule: the patterns are all the posible combinations of 0/1 values (total possible patterns: 2^nvars). I would ideally need a MACRO to compute them for up to 15 variables. Years ago I did it with a BASIC program (for eight variables), but I had the advantage of being able to extract bits from a byte, and the code was very easy: computing with a loop numbers form 1 to 256, and extracting eight variables with the value of every bit that formed the byte. I don't know how to handle it with SPSS :( No need to hurry, tomorrow I'm leaving for 12 days (trying again the also impossible task of getting a tan, I happen to have a very low phototype). Regards Marta |
Marta wrote:
> I'm stuck in the middle of an "impossible?" problem. I need to create > datasets with the following characteristics: > > If nvars=3: > x1 x2 x3 > 0 0 0 > 1 0 0 > 0 1 0 > 0 0 1 > 1 1 0 > 1 0 1 > 0 1 1 > 1 1 1 > Total number of patterns:8 > > General rule: the patterns are all the posible combinations of 0/1 > values (total possible patterns: 2^nvars). Hey Marta & list, glad to be able to help you back :-) You can enter the number of variables at http://gjyp.nl/personal/marta.php. It works for 15 variables; when I tried 28, it took a looooong time :-) It does exactly what you did in Basic (but in PHP) :-) (or should I have done this is SPSS?) HTH, Gjalt-Jorn ____________________________________________________________________________ Gjalt-Jorn Ygram Peters ## Phd. Student ## Visit: Department of Experimental Psychology Room 3.004 Faculty of Psychology Universiteitssingel 5 University of Maastricht 6229 ES Maastricht The Netherlands ## Contact: P.O. Box 616 ## Private: 6200 MD Maastricht Alexander Battalaan 68d The Netherlands 6221 CE Maastricht The Netherlands Phone: +31 43 388 4508 Fax: +31 43 388 4211 Phone: +31 (0) 62 120 0009 Mail: [hidden email] Mail: [hidden email] Msn: [hidden email] Web: http://interventionmapping.nl Web: http://www.gjyp.nl |
Hola Gjalt-Jorn,
PGP> Hey Marta & list, PGP> glad to be able to help you back :-) PGP> You can enter the number of variables at PGP> http://gjyp.nl/personal/marta.php. It works for 15 variables; PGP> when I tried 28, it took a looooong time :-) PGP> It does exactly what you did in Basic (but in PHP) :-) PGP> (or should I have done this is SPSS?) I needed it in SPSS, because it's part of a MACRO 8for a more complex task) that will call it. I've tried to see the PHP code, but I can't. Anyway, I can always copy-paste the solution your code provides and turn it into SPSS auxiliary files (from 3 to 20) and ask the macro to read the one needed according to the number of variables. Regards Marta |
Marta:
I think I've got it! INPUT PROGRAM. LOOP I=0 TO (2**15)-1. END CASE. END LOOP. END FILE. END INPUT PROGRAM. EXECUTE. FORMATS I(N5). NUMERIC V0 to V14 (F3) coc0 TO coc15(f5). STRING VV0 to VV14(a1). VECTOR V=V0 TO V14 /coc=coc0 TO coc15 /VV=VV0 to VV14. LOOP X=15 TO 1 BY -1. - DO IF i<2**x AND i>=2**(x-1). - COMPUTE coc(x+1)=i. - LOOP Y=X to 1 by -1. - COMPUTE COC(y)=trunc(COC(y+1)/2). - COMPUTE v(y) = mod(coc(y+1),2). - COMPUTE vV(y) = STRING(mod(coc(y+1),2),F1). - END LOOP. - end if. END LOOP. IF I=0 V0=0. IF I=0 Vv0='0'. execute. STRING BIN(a15). compute bin= lpad(rtrim(CONCAT(VV0 to VV14)),15,"0"). EXECUTE. numeric x1 to x15 (F3). VECTOR XX=X1 to X15. LOOP X=1 TO 15. compute XX(X)=NUMBER(SUBSTR(BIN,x,1),F1). END LOOP. execute. Surely this syntax will need some debugging in otder to optimize it. But you will get the variables you need! Happy holidays! Frederic. %%%%%%%%%%%%%%%%%%%%%%% Frederic Villamayor Unitat de Bioestadística Àrea de Desenvolupament Preclínic CIDF Ferrer Grupo Juan de Sada, 32 08028 - Barcelona Espanya E-mail: [hidden email] Tel: +34 935093236 Fax: +34 934112764 WWW: www.ferrergrupo.com %%%%%%%%%%%%%%%%%%%%%%% "Sanity is not statistical" 1984 (George Orwell) |
In reply to this post by Marta García-Granero
Hi, Marta!
At 06:46 AM 7/5/2006, Marta García-Granero wrote: >I'm stuck in the middle of an "impossible?" >problem. I need to create datasets with the following characteristics: > >If nvars=3: >x1 x2 x3 >0 0 0 >1 0 0 >0 1 0 >0 0 1 >1 1 0 >1 0 1 >0 1 1 >1 1 1 >Total number of patterns:8 etc. >No need to hurry, tomorrow I'm leaving for 12 >days (trying again the also impossible task of >getting a tan, I happen to have a very low phototype). Have a great break! (And now, I will mother-hen-like add, conventional wisdom on this side of the Atlantic is, don't do it. The thinking is, the UV does long-term skin damage. They advise us to use quite aggressive sun-screen lotions - not that I always do it.) But, back to your generating problem: We've done that before using nested loops in INPUT PROGRAM; I think you and I posted variations on such a solution, a while back. The trouble is that nested-loop logic is cumbersome, even by nvars=3. It's easy to unbalance the LOOP/ END LOOP statements; at best, hard to read the code to make sure they are balanced. (I wrote carefully indented code, which was a pain to do, and still hard to read.) And it's very hard to make nested-loop logic extensible to any 'nvars' - you sort of could with macro logic, I guess, and probably could with Python. I suppose that extensibility is the worst problem. Frederic Villamayor Forcada's solution will probably do it (I haven't analyzed it). Here's a variation. You wrote, >Years ago I did it with a BASIC program (for >eight variables), but I had the advantage of >being able to extract bits from a byte, and the >code was very easy: computing with a loop >numbers form 1 to 256, and extracting eight >variables with the value of every bit that formed the byte. In other words, you used a binary counter, and made the bits your variable values. You can do the same thing in SPSS. This is a macro solution, because it changes two quantities that can only be specified in code: the number of variables, and the length of a vector. Of course, in Python... Probably, Python code could skip the INPUT PROGRAM altogether. (You could generalize this to generate all combinations of 3-valued variables, etc.; replace the 'binary counter' by a ternary counter. You could, even generalize to generating all combinations of variables with differing numbers of values, by creating a multiple-base number system - days/hours/minutes is a multiple-base system, as is the former English pounds/shillings/pence.) Anyway, SPSS draft output: .......................... DEFINE !AllComb(Nvars=!Default(3) !TOKENS(1)) . /**/ ECHO !QUOTE(!CONCAT(' Count ',!Nvars,' variables')). . NEW FILE. . INPUT PROGRAM. . NUMERIC Case (COMMA8). . LEAVE Case. . VECTOR X( !Nvars ,F2). . !LET !Last_X = !CONCAT('X',!Nvars) . LEAVE X1 TO !Last_X . . RECODE X1 TO !Last_X (ELSE = 0). *. . NUMERIC #LIMIT (F7) /#DIGIT #INDEX (F4) /#CARRY (F2). . COMPUTE #LIMIT = 2** !Nvars . . /*-- PRINT / ' Write ' #LIMIT(F7) ' cases'. * Write the first case - all zeroes . . COMPUTE Case = 1. . END CASE. * Write all other cases . . LOOP Case = 2 TO #LIMIT. . /*-- PRINT / ' Case ' Case(F7). . COMPUTE #CARRY = 1. . LOOP #DIGIT = 1 TO !Nvars . . COMPUTE #INDEX = !Nvars - #DIGIT + 1. . /*-- PRINT / ' Digit ' #DIGIT(F7) ' index ' #INDEX (F7). . DO IF X(#INDEX) = 1. . COMPUTE X(#INDEX) = 0. . COMPUTE #CARRY = 1. . ELSE. . COMPUTE X(#INDEX) = 1. . COMPUTE #CARRY = 0. . END IF. . END LOOP IF #CARRY EQ 0. . /*-- PRINT / ' Case ' Case(F7) ': ' /*-- X1 TO !Last_X . END CASE. . END LOOP. . END FILE. . END INPUT PROGRAM. !ENDDEFINE. *. *. PRESERVE. SET MPRINT ON. *. 1462 M> *. !AllComb . 1463 M> 1464 M> . 1465 M> . ECHO ' Count 3 variables'. Count 3 variables 1466 M> NEW FILE. 1467 M> INPUT PROGRAM. 1468 M> NUMERIC Case (COMMA8). 1469 M> LEAVE Case. 1470 M> VECTOR X( 3 ,F2). 1471 M> . LEAVE X1 TO X3. 1472 M> RECODE X1 TO X3 (ELSE = 0). 1473 M> NUMERIC #LIMIT (F7) /#DIGIT #INDEX (F4) /#CARRY (F2). 1474 M> COMPUTE #LIMIT = 2** 3. 1475 M> COMPUTE Case = 1. 1476 M> END CASE. 1477 M> LOOP Case = 2 TO #LIMIT. 1478 M> COMPUTE #CARRY = 1. 1479 M> LOOP #DIGIT = 1 TO 3. 1480 M> COMPUTE #INDEX = 3 - #DIGIT + 1. 1481 M> DO IF X(#INDEX) = 1. 1482 M> COMPUTE X(#INDEX) = 0. 1483 M> COMPUTE #CARRY = 1. 1484 M> ELSE. 1485 M> COMPUTE X(#INDEX) = 1. 1486 M> COMPUTE #CARRY = 0. 1487 M> END IF. 1488 M> END LOOP IF #CARRY EQ 0. 1489 M> END CASE. 1490 M> END LOOP. 1491 M> END FILE. 1492 M> END INPUT PROGRAM 1493 M> . *. 1494 M> *. RESTORE. 1495 M> RESTORE. LIST. List |-------------------------|------------------------| |Output Created |05-JUL-2006 16:48:13 | |-------------------------|------------------------| Case X1 X2 X3 1 0 0 0 2 0 0 1 3 0 1 0 4 0 1 1 5 1 0 0 6 1 0 1 7 1 1 0 8 1 1 1 Number of cases read: 8 Number of cases listed: 8 *. *. PRESERVE. SET MPRINT ON. *. 1501 M> *. !AllComb NVars=4 . 1502 M> 1503 M> . 1504 M> . ECHO ' Count 4 variables'. Count 4 variables 1505 M> NEW FILE. 1506 M> INPUT PROGRAM. 1507 M> NUMERIC Case (COMMA8). 1508 M> LEAVE Case. 1509 M> VECTOR X( 4 ,F2). 1510 M> . LEAVE X1 TO X4. 1511 M> RECODE X1 TO X4 (ELSE = 0). 1512 M> NUMERIC #LIMIT (F7) /#DIGIT #INDEX (F4) /#CARRY (F2). 1513 M> COMPUTE #LIMIT = 2** 4. 1514 M> COMPUTE Case = 1. 1515 M> END CASE. 1516 M> LOOP Case = 2 TO #LIMIT. 1517 M> COMPUTE #CARRY = 1. 1518 M> LOOP #DIGIT = 1 TO 4. 1519 M> COMPUTE #INDEX = 4 - #DIGIT + 1. 1520 M> DO IF X(#INDEX) = 1. 1521 M> COMPUTE X(#INDEX) = 0. 1522 M> COMPUTE #CARRY = 1. 1523 M> ELSE. 1524 M> COMPUTE X(#INDEX) = 1. 1525 M> COMPUTE #CARRY = 0. 1526 M> END IF. 1527 M> END LOOP IF #CARRY EQ 0. 1528 M> END CASE. 1529 M> END LOOP. 1530 M> END FILE. 1531 M> END INPUT PROGRAM 1532 M> . 1533 M> *. 1534 M> *. RESTORE. 1535 M> RESTORE. LIST. List |-------------------------|------------------------| |Output Created |05-JUL-2006 16:48:14 | |-------------------------|------------------------| Case X1 X2 X3 X4 1 0 0 0 0 2 0 0 0 1 3 0 0 1 0 4 0 0 1 1 5 0 1 0 0 6 0 1 0 1 7 0 1 1 0 8 0 1 1 1 9 1 0 0 0 10 1 0 0 1 11 1 0 1 0 12 1 0 1 1 13 1 1 0 0 14 1 1 0 1 15 1 1 1 0 16 1 1 1 1 Number of cases read: 16 Number of cases listed: 16 |
Dear all
Thanks to all who helped. I needed the patterns for a MATRIX program, and the problem with the growing number of nested loops made me think that I couldn't do that task within MATRIX. But... it looks like my brain thinks better when holidays are close! This is what I finally got yesterday evening (when I should have been preparing my luggage, BTW): MATRIX. * Change this value if other number of variables is needed *. COMPUTE nvars=4. /* Example for x1 to x4 binary patterns *. COMPUTE subset={0;1}. /* Nucleus of the dataset (only for x1) *. COMPUTE n=NROW(subset). LOOP i=2 TO nvars. /* Iteratively unfold for x2... to nvars *. - COMPUTE subset={MAKE(n,1,0),subset;MAKE(n,1,1),subset}. - COMPUTE n=NROW(subset). END LOOP. PRINT subset /FORMAT='F2.0' /TITLE='All binary patterns for requested number of variables'. END MATRIX. I haven't added the final lines that would export the variables to the dataset, but that's easy if you want it. This code uses only one loop, not several nested. It's very fast, even for 10 or more variables. Cute, isn't it? >>No need to hurry, tomorrow I'm leaving for 12 >>days (trying again the also impossible task of >>getting a tan, I happen to have a very low phototype). RR> Have a great break! (And now, I will RR> mother-hen-like add, conventional wisdom on this RR> side of the Atlantic is, don't do it. The RR> thinking is, the UV does long-term skin damage. RR> They advise us to use quite aggressive sun-screen RR> lotions - not that I always do it.) That's why it is an impossible task: I always avoid the sun around midday and use solar filter with protective factor over 40! Warmest regards for everybody, Marta |
Free forum by Nabble | Edit this page |