=========================================================================
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
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