LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous (more recent) messageNext (less recent) messagePrevious (more recent) in topicNext (less recent) in topicPrevious (more recent) by same authorNext (less recent) by same authorPrevious page (July 2006)Back to main SPSSX-L pageJoin or leave SPSSX-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
=========================================================================
Date:         Wed, 5 Jul 2006 16:51:07 -0400
Reply-To:     Richard Ristow <wrristow@mindspring.com>
Sender:       "SPSSX(r) Discussion" <SPSSX-L@LISTSERV.UGA.EDU>
From:         Richard Ristow <wrristow@mindspring.com>
Subject:      Re: Generating all posibble binary patterns for m variables
Comments: To: Marta García-Granero <biostatistics@terra.es>
In-Reply-To:  <4513781718.20060705124653@terra.es>
Content-Type: text/plain; charset=iso-8859-1; format=flowed;
              x-avg-checked=avg-ok-5A8A680F

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


Back to: Top of message | Previous page | Main SPSSX-L page