Hi,
I have a problem which requires to enumerate all the combinations from several variables. Details are as below: I have 10 variables, A1 to A10, and each of them has the value of 0 and 1, and I would like to list all the possible combinations of these 10 variables. For example, one possible combination is 1010101010, and another one is 0100000001. I do not know how to implement this in SPSS syntax, and how to arrange the data matrix. Thanks, |
A permutation problem. At 10! You'll have a file of about 3.63E6 records.
I posted a question with the subject line "converting letters into integer numbers" . I suggest that you look in the archives for the entire exchange. David Marso very generously wrote a piece of code that does what you want and I think the following piece of code is that piece. Perhaps he will comment. Gene Maguin David said: Here is a MUCH MORE EFFICIENT rewrite of the exhaustive list method. Don't know what I was thinking earlier ;-))) No need to run through twice nor any requirement for a second matrix. SET MXLOOPS=10000000. /* Exhaustive list */. MATRIX. COMPUTE x=9. COMPUTE p=T({1:x}). LOOP #=1 TO x-1. + COMPUTE p={KRONEKER(T({1:x}),MAKE(NROW(p),1,1)),KRONEKER(MAKE(x,1,1),p)}. + COMPUTE goodrow=1. + LOOP ##=1 TO NROW(p). + COMPUTE target=p(##,1). + LOOP ###=2 TO NCOL(p). + COMPUTE found=(p(##,###) EQ target). + END LOOP IF found. + DO IF (found EQ 0). + COMPUTE p(goodrow,:)=p(##,:). + COMPUTE goodrow=goodrow+1. + END IF. + END LOOP. + COMPUTE p=p(1:(goodrow-1),:). END LOOP. SAVE p / OUTFILE * . END MATRIX. -----Original Message----- From: SPSSX(r) Discussion [mailto:[hidden email]] On Behalf Of albert_sun Sent: Tuesday, September 16, 2014 8:06 PM To: [hidden email] Subject: How to enumerate all the combinations in SPSS Hi, I have a problem which requires to enumerate all the combinations from several variables. Details are as below: I have 10 variables, A1 to A10, and each of them has the value of 0 and 1, and I would like to list all the possible combinations of these 10 variables. For example, one possible combination is 1010101010, and another one is 0100000001. I do not know how to implement this in SPSS syntax, and how to arrange the data matrix. Thanks, -- View this message in context: http://spssx-discussion.1045642.n5.nabble.com/How-to-enumerate-all-the-combinations-in-SPSS-tp5727284.html Sent from the SPSSX Discussion mailing list archive at Nabble.com. ===================== To manage your subscription to SPSSX-L, send a message to [hidden email] (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD ===================== To manage your subscription to SPSSX-L, send a message to [hidden email] (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD |
In reply to this post by albert_sun
One way is to use the Python and the itertools product function:
**************************************************. BEGIN PROGRAM. import spss import itertools as it #making permutations YourSet = [0,1] YourLen = 10 x = list(it.product(YourSet,repeat=YourLen)) #exporting to an SPSS dataset spss.StartDataStep() datasetObj = spss.Dataset(name=None) for i in range(YourLen): datasetObj.varlist.append('X'+str(i+1),0) for j in x: datasetObj.cases.append(j) spss.EndDataStep() END PROGRAM. **************************************************. Note that to generate all possible permutations you can simply just do a set of nested loops. I.e. if you had only 3 variables you could do: LOOP X1 = 0 TO 1. LOOP X2 = 0 TO 1. LOOP X3 = 0 TO 1. To generate the 2^3=8 possible outcomes. Here is a macro that takes as parameters Set - the number of digits, and Len, the number of variables to fill in and does these nested loops for you. **************************************************. *Nested lists yourself in SPSS. DEFINE !Combinations (Set = !TOKENS(1) /Len = !TOKENS(1) ) INPUT PROGRAM. !LET !Str = " ". !LET !LisVar = "". !DO !I = 1 !TO !Len !LET !Ind = !CONCAT("#",!LENGTH(!Str)) LOOP !Ind = 1 TO !Set. !LET !Str = !CONCAT(!Str," ") !LET !LisVar = !CONCAT(!LisVar," ",!Ind) !DOEND VECTOR X(!Len). DO REPEAT L = !LisVar /X = X1 TO !CONCAT("X",!Len). COMPUTE X = L. END REPEAT. END CASE. !DO !I = 1 !TO !Len END LOOP. !DOEND END FILE. END INPUT PROGRAM. DATASET NAME Comb. EXECUTE. !ENDDEFINE. SET MPRINT ON. !Combinations Set = 2 Len = 10. SET MPRINT OFF. **************************************************. To change the values to 0 and 1 instead of 1 and 2 just subtract 1 from X1 through X10. This works devilishly fast even when generating over a million permutations (in which case itertools might fail, see a related thread, http://spssx-discussion.1045642.n5.nabble.com/converting-letters-to-integer-numbers-td5725888.html#a5725933). |
Thanks you so much. It is really helpful. Xiaoxun On Wed, Sep 17, 2014 at 1:06 PM, Andy W [via SPSSX Discussion] <[hidden email]> wrote: One way is to use the Python and the itertools product function: |
In reply to this post by albert_sun
It looks so that seek to produce the Cartesian product of 10 sets,
each set having two values 0 an 1 (the same for all the sets). There
have been a thread some time ago here about Cartesian product
computation, you can find it. Cartesian product is just all possible
combinations from K sets, taking 1 element from each set at a time.
17.09.2014 4:06, albert_sun пишет:
Hi, I have a problem which requires to enumerate all the combinations from several variables. Details are as below: I have 10 variables, A1 to A10, and each of them has the value of 0 and 1, and I would like to list all the possible combinations of these 10 variables. For example, one possible combination is 1010101010, and another one is 0100000001. I do not know how to implement this in SPSS syntax, and how to arrange the data matrix. Thanks, -- View this message in context: http://spssx-discussion.1045642.n5.nabble.com/How-to-enumerate-all-the-combinations-in-SPSS-tp5727284.html Sent from the SPSSX Discussion mailing list archive at Nabble.com. ===================== To manage your subscription to SPSSX-L, send a message to [hidden email] (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD ===================== To manage your subscription to SPSSX-L, send a message to [hidden email] (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD |
Administrator
|
MATRIX.
COMPUTE Y={0;1}. LOOP #=2 TO 10. COMPUTE Y={KRONEKER({1;1},Y),KRONEKER({0;1},MAKE(NROW(Y),1,1))}. END LOOP. SAVE Y /OUTFILE * /VARIABLES C01 TO C10. END MATRIX.
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me. --- "Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis." Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?" |
Administrator
|
In reply to this post by Andy W
Alternatively ;-)))
MATRIX. COMPUTE Y={0;1}. LOOP #=2 TO 10. COMPUTE Y={KRONEKER({1;1},Y),KRONEKER({0;1},MAKE(NROW(Y),1,1))}. END LOOP. SAVE Y /OUTFILE * /VARIABLES C01 TO C10. END MATRIX.
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me. --- "Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis." Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?" |
In reply to this post by Maguin, Eugene
A faster modification of the bottom code to get all possible
permutations:
SET MXLOOPS=10000000. /* Exhaustive list */. MATRIX. COMPUTE x=9. COMPUTE p=T({1:x}). LOOP #=1 TO x-1. + COMPUTE p={KRONEKER(T({1:x}),MAKE(NROW(p),1,1)),KRONEKER(MAKE(x,1,1),p)}. - comp flag= make(nrow(p),1,0). - loop i= 2 to ncol(p). - comp flag= flag+rsum(p(:,i:ncol(p))=p(:,1:(ncol(p)-i+1))). - end loop. - !indices(not flag%ind). /*A function collecting indices of nonzero values of a vector (see below) - comp p= p(ind,:). END LOOP. SAVE p / OUTFILE * . END MATRIX. define !indices(!pos= !token(1) /!pos= !charend('%') /!pos= !charend(')')) comp @vec= !2. comp @vec= @vec<>0. comp @nnz= msum(@vec). do if @nnz. -comp !3= make(1,@nnz,0). -comp @c= 0. -loop @i= 1 to nrow(@vec)*ncol(@vec). - do if @vec(@i). - comp @c= @c+1. - comp !3(@c)= @i. - end if. -end loop. -release @c,@i. else. -comp !3= 0. end if. release @vec,@nnz. !enddefine. Any ideas for further faster code enumerating permutations? Can a totaly different approach (i.e. not through Cartesian product with subsequent cropping) be faster in SPSS? (Be aware please that the code snippets we consider so far are only for vectoral positions (1,2,3...) of values we want to permute or for values which are all different). David said: Here is a MUCH MORE EFFICIENT rewrite of the exhaustive list method. Don't know what I was thinking earlier ;-))) No need to run through twice nor any requirement for a second matrix. SET MXLOOPS=10000000. /* Exhaustive list */. MATRIX. COMPUTE x=9. COMPUTE p=T({1:x}). LOOP #=1 TO x-1. + COMPUTE p={KRONEKER(T({1:x}),MAKE(NROW(p),1,1)),KRONEKER(MAKE(x,1,1),p)}. + COMPUTE goodrow=1. + LOOP ##=1 TO NROW(p). + COMPUTE target=p(##,1). + LOOP ###=2 TO NCOL(p). + COMPUTE found=(p(##,###) EQ target). + END LOOP IF found. + DO IF (found EQ 0). + COMPUTE p(goodrow,:)=p(##,:). + COMPUTE goodrow=goodrow+1. + END IF. + END LOOP. + COMPUTE p=p(1:(goodrow-1),:). END LOOP. SAVE p / OUTFILE * . END MATRIX. ===================== To manage your subscription to SPSSX-L, send a message to [hidden email] (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD |
Ha... and this is even more fast and easy.
SET MXLOOPS=10000000. /* Exhaustive list */. MATRIX. COMPUTE x=9. COMPUTE p=T({1:x}). LOOP #=1 TO x-1. + COMPUTE p={KRONEKER(T({1:x}),MAKE(NROW(p),1,1)),KRONEKER(MAKE(x,1,1),p)}. - comp flag= rsum(kroneker(p(:,1),make(1,ncol(p)-1,1))=p(:,2:ncol(p))). - !indices(not flag%ind). - comp p= p(ind,:). END LOOP. SAVE p / OUTFILE * . END MATRIX. 18.09.2014 12:08, Kirill Orlov пишет:
A faster modification of the bottom code to get all possible permutations: ===================== To manage your subscription to SPSSX-L, send a message to [hidden email] (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD |
And here comes the updataed MATRIX function to collect all indices
(positions) of nonzero elements of a vector.
Despite that the piece may look heavy - for such a simple task! - it is yet well optimized for speed. define !indices(!pos= !token(1) /!pos= !charend('%') /!pos= !charend(')')) comp @vec= !2. comp @vec= @vec<>0. comp @nnz= msum(@vec). do if @nnz. -comp !3= make(1,@nnz,0). -do if @nnz/(nrow(@vec)*ncol(@vec))>.8. - comp !3= {!3,0}. - comp @c= 1. - loop @i= 1 to nrow(@vec)*ncol(@vec). - comp !3(@c)= @i. - comp @c= @c+@vec(@i). - end loop. - comp !3= !3(1:@nnz). -else. - comp @c= 0. - loop @i= 1 to nrow(@vec)*ncol(@vec). - do if @vec(@i). - comp @c= @c+1. - comp !3(@c)= @i. - end if. - end loop. -end if. -release @c,@i. else. -comp !3= 0. end if. release @vec,@nnz. !enddefine. -------- Исходное сообщение --------
Ha... and this is even more fast and easy. SET MXLOOPS=10000000. /* Exhaustive list */. MATRIX. COMPUTE x=9. COMPUTE p=T({1:x}). LOOP #=1 TO x-1. + COMPUTE p={KRONEKER(T({1:x}),MAKE(NROW(p),1,1)),KRONEKER(MAKE(x,1,1),p)}. - comp flag= rsum(kroneker(p(:,1),make(1,ncol(p)-1,1))=p(:,2:ncol(p))). - !indices(not flag%ind). - comp p= p(ind,:). END LOOP. SAVE p / OUTFILE * . END MATRIX. 18.09.2014 12:08, Kirill Orlov пишет:
A faster modification of the bottom code to get all possible permutations: ===================== To manage your subscription to SPSSX-L, send a message to [hidden email] (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD |
This post was updated on .
Or this one, seems to be even more finalized.
define !indices(!pos= !token(1) /!pos= !charend('%') /!pos= !charend(')')) comp @vec= !2. comp @vec= @vec<>0. comp @n= nrow(@vec)*ncol(@vec). comp @nnz= msum(@vec). do if not @nnz. -comp !3= 0. else if @nnz=@n. -comp !3= {1:@n}. else if @nnz/@n>.8. -comp !3= make(1,@nnz+1,0). -comp @c= 1. -loop @i= 1 to @n. - comp !3(@c)= @i. - comp @c= @c+@vec(@i). -end loop. -comp !3= !3(1:@nnz). -release @c,@i. else. -comp !3= make(1,@nnz,0). -comp @c= 0. -loop @i= 1 to @n. - do if @vec(@i). - comp @c= @c+1. - comp !3(@c)= @i. - end if. -end loop. -release @c,@i. end if. release @vec,@n,@nnz. !enddefine. -------- ???????? ????????? -------- ????: Re: How to enumerate all the combinations in SPSS ????: Fri, 19 Sep 2014 16:24:00 +0400 ??: Kirill Orlov <kior@comtv.ru> ????: SPSSX-List <SPSSX-L@LISTSERV.UGA.EDU> And here comes the updataed MATRIX function to collect all indices (positions) of nonzero elements of a vector. Despite that the piece may look heavy - for such a simple task! - it is yet well*optimized for speed*. define !indices(!pos= !token(1) /!pos= !charend('%') /!pos= !charend(')')) comp @vec= !2. comp @vec= @vec<>0. comp @nnz= msum(@vec). do if @nnz. -comp !3= make(1,@nnz,0). -do if @nnz/(nrow(@vec)*ncol(@vec))>.8. - comp !3= {!3,0}. - comp @c= 1. - loop @i= 1 to nrow(@vec)*ncol(@vec). - comp !3(@c)= @i. - comp @c= @c+@vec(@i). - end loop. - comp !3= !3(1:@nnz). -else. - comp @c= 0. - loop @i= 1 to nrow(@vec)*ncol(@vec). - do if @vec(@i). - comp @c= @c+1. - comp !3(@c)= @i. - end if. - end loop. -end if. -release @c,@i. else. -comp !3= 0. end if. release @vec,@nnz. !enddefine. ===================== To manage your subscription to SPSSX-L, send a message to LISTSERV@LISTSERV.UGA.EDU (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD |
In reply to this post by Maguin, Eugene
I thought that the OP asked for all combinations of 10 dichotmous (zero one) variables.
2**10 = 1024
Art Kendall
Social Research Consultants |
That's what it looked like to me, too.
=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD
For that, you just need to count from 0 to 1023, and express as the binary number. Divide by two and truncate and pick up the remainder, 10 times. -- Rich Ulrich > Date: Sat, 20 Sep 2014 05:04:45 -0700 > From: [hidden email] > Subject: Re: How to enumerate all the combinations in SPSS > To: [hidden email] > > I thought that the OP asked for all combinations of 10 dichotmous (zero one) > variables. > 2**10 = 1024 > > |
Administrator
|
In reply to this post by Art Kendall
My 7 line MATRIX solution I posted Wed 17th does precisely that.
-----------
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me. --- "Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis." Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?" |
In reply to this post by albert_sun
With Python:
with open("outfile.txt", "w") as f: f.writelines([bin(i).zfill(10).replace('0b', '') for i in range(1024)] ------------------------------ On Sat, Sep 20, 2014 7:41 PM CEST David Marso wrote: >My 7 line MATRIX solution I posted Wed 17th does precisely that. >----------- > >Art Kendall wrote >> I thought that the OP asked for all combinations of 10 dichotmous (zero >> one) variables. >> 2**10 = 1024 > > > > > >----- >Please reply to the list and not to my personal email. >Those desiring my consulting or training services please feel free to email me. >--- >"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis." >Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?" >-- >View this message in context: http://spssx-discussion.1045642.n5.nabble.com/How-to-enumerate-all-the-combinations-in-SPSS-tp5727284p5727331.html >Sent from the SPSSX Discussion mailing list archive at Nabble.com. > >===================== >To manage your subscription to SPSSX-L, send a message to >[hidden email] (not to SPSSX-L), with no body text except the >command. To leave the list, send the command >SIGNOFF SPSSX-L >For a list of commands to manage subscriptions, send the command >INFO REFCARD ===================== To manage your subscription to SPSSX-L, send a message to [hidden email] (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD |
In reply to this post by Art Kendall
Yes, she/he did. I didn't analyze the question before replying and put up a completely wrong response. Gene Maguin
-----Original Message----- From: SPSSX(r) Discussion [mailto:[hidden email]] On Behalf Of Art Kendall Sent: Saturday, September 20, 2014 8:05 AM To: [hidden email] Subject: Re: How to enumerate all the combinations in SPSS I thought that the OP asked for all combinations of 10 dichotmous (zero one) variables. 2**10 = 1024 ----- Art Kendall Social Research Consultants -- View this message in context: http://spssx-discussion.1045642.n5.nabble.com/How-to-enumerate-all-the-combinations-in-SPSS-tp5727284p5727328.html Sent from the SPSSX Discussion mailing list archive at Nabble.com. ===================== To manage your subscription to SPSSX-L, send a message to [hidden email] (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD ===================== To manage your subscription to SPSSX-L, send a message to [hidden email] (not to SPSSX-L), with no body text except the command. To leave the list, send the command SIGNOFF SPSSX-L For a list of commands to manage subscriptions, send the command INFO REFCARD |
Free forum by Nabble | Edit this page |