macro problem (may be !head expression)

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

macro problem (may be !head expression)

progster

I have several datasets that I want to ADD. Since the names are flexible I would like a macro that could append the dataset listed in the macro call. As I said the list (called nlist in the macro) is flexible.

the issue is that my macro append two times the first data (BBDD1).

I put some data for the sake of semplicity but real data are much more and with very long lists, so I guess that a macro would be the better choice.



data list list / id .
begin data
1
2
end data.

dataset name BBDD1.


data list list / id .
begin data
3
4
end data.

dataset name BBDD2.


data list list / id .
begin data
5
6
end data.

dataset name BBDD3.



define !add_macro(nlist=!enclose("(",")"))
!let !cnlist=!nlist
!let !nvar=!head(!cnlist)
!do !dvar !in (!nlist)



DATASET ACTIVATE !nvar.
ADD FILES /FILE=*
  /FILE=!quote(!dvar).
EXECUTE.


!doend
!enddefine.
 
*Macro call.
 
!add_macro  nlist(BBDD1 BBDD2 BBDD3).
Reply | Threaded
Open this post in threaded view
|

Re: macro problem (may be !head expression)

Andy W
See the !TAIL function, I'm guessing if you changed

!do !dvar !in (!nlist)

to

!do !dvar !in !TAIL(!nlist)

it will work
Andy W
apwheele@gmail.com
http://andrewpwheeler.wordpress.com/
Reply | Threaded
Open this post in threaded view
|

Re: macro problem (may be !head expression)

David Marso
Administrator
In reply to this post by progster

/* You don't want to do it that way ;-) .
/* For a number of reasons
/* (one data pass per file for one -you can have 64? between each EXEC.).
/* The first two lines are not useful What is the objective with that?
/* If you were parsing the list you would need to replace the copy with it's !TAIL or build the list with recursion and ADD after it returns.  There is a long thread about recursion in macros.
http://spssx-discussion.1045642.n5.nabble.com/Recursion-with-Macro-td5723537.html
WOW:  I can't believe it has been 2.5 years since we had that interesting discussion ;-)

DEFINE !DMM_Add (nlist=!CMDEND )
ADD FILES  !DO !F !IN (!nlist) / FILE=!F !DOEND
!ENDDEFINE .
SET MPRINT ON.
!DMM_Add  nlist BBDD1 BBDD2 BBDD3 .

Generated syntax :
ADD FILES / FILE= BBDD1 / FILE= BBDD2 / FILE= BBDD3 .


progster wrote
I have several datasets that I want to ADD. Since the names are flexible I would like a macro that could append the dataset listed in the macro call. As I said the list (called nlist in the macro) is flexible.

the issue is that my macro append two times the first data (BBDD1).

I put some data for the sake of semplicity but real data are much more and with very long lists, so I guess that a macro would be the better choice.



data list list / id .
begin data
1
2
end data.

dataset name BBDD1.


data list list / id .
begin data
3
4
end data.

dataset name BBDD2.


data list list / id .
begin data
5
6
end data.

dataset name BBDD3.



define !add_macro(nlist=!enclose("(",")"))
!let !cnlist=!nlist
!let !nvar=!head(!cnlist)
!do !dvar !in (!nlist)



DATASET ACTIVATE !nvar.
ADD FILES /FILE=*
  /FILE=!quote(!dvar).
EXECUTE.


!doend
!enddefine.
 
*Macro call.
 
!add_macro  nlist(BBDD1 BBDD2 BBDD3).
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?"
Reply | Threaded
Open this post in threaded view
|

Re: macro problem (may be !head expression)

David Marso
Administrator
Implementation using Recursion:

DEFINE !DMMRecurseAdd ( !POS !CHAREND("/") / !POS !CMDEND)

!IF (!1 !NE !NULL ) !THEN
!DMMRecurseAdd !TAIL(!1) / !CONCAT(!2, "/ FILE =",!HEAD(!1)) .
!ELSE
ADD FILES !2 .
!IFEND
!ENDDEFINE .

!DMMRecurseAdd  BBDD1 BBDD2 BBDD3 / .

Generated syntax :
ADD FILES / FILE =BBDD1/ FILE =BBDD2/ FILE =BBDD3.



David Marso wrote
/* You don't want to do it that way ;-) .
/* For a number of reasons
/* (one data pass per file for one -you can have 64? between each EXEC.).
/* The first two lines are not useful What is the objective with that?
/* If you were parsing the list you would need to replace the copy with it's !TAIL or build the list with recursion and ADD after it returns.  There is a long thread about recursion in macros.
http://spssx-discussion.1045642.n5.nabble.com/Recursion-with-Macro-td5723537.html
WOW:  I can't believe it has been 2.5 years since we had that interesting discussion ;-)

DEFINE !DMM_Add (nlist=!CMDEND )
ADD FILES  !DO !F !IN (!nlist) / FILE=!F !DOEND
!ENDDEFINE .
SET MPRINT ON.
!DMM_Add  nlist BBDD1 BBDD2 BBDD3 .

Generated syntax :
ADD FILES / FILE= BBDD1 / FILE= BBDD2 / FILE= BBDD3 .


progster wrote
I have several datasets that I want to ADD. Since the names are flexible I would like a macro that could append the dataset listed in the macro call. As I said the list (called nlist in the macro) is flexible.

the issue is that my macro append two times the first data (BBDD1).

I put some data for the sake of semplicity but real data are much more and with very long lists, so I guess that a macro would be the better choice.



data list list / id .
begin data
1
2
end data.

dataset name BBDD1.


data list list / id .
begin data
3
4
end data.

dataset name BBDD2.


data list list / id .
begin data
5
6
end data.

dataset name BBDD3.



define !add_macro(nlist=!enclose("(",")"))
!let !cnlist=!nlist
!let !nvar=!head(!cnlist)
!do !dvar !in (!nlist)



DATASET ACTIVATE !nvar.
ADD FILES /FILE=*
  /FILE=!quote(!dvar).
EXECUTE.


!doend
!enddefine.
 
*Macro call.
 
!add_macro  nlist(BBDD1 BBDD2 BBDD3).
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?"
Reply | Threaded
Open this post in threaded view
|

Re: macro problem (may be !head expression)

David Marso
Administrator
In reply to this post by Andy W
Maybe but that macro is badly braimaged in other ways ;-)
--
Andy W wrote
See the !TAIL function, I'm guessing if you changed

!do !dvar !in (!nlist)

to

!do !dvar !in !TAIL(!nlist)

it will work
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?"
Reply | Threaded
Open this post in threaded view
|

Re: macro problem (may be !head expression)

Andy W
I wish your name started with an H - hyperbole David just doesn't sound as poetic as I would like it.
Andy W
apwheele@gmail.com
http://andrewpwheeler.wordpress.com/
Reply | Threaded
Open this post in threaded view
|

Re: macro problem (may be !head expression)

progster
In reply to this post by David Marso
Yes for my aim the proposed solutions are cool, and it's true: I did not need the first two lines
Reply | Threaded
Open this post in threaded view
|

Re: macro problem (may be !head expression)

Jon Peck
In reply to this post by progster
Here's a smart version of this functionalit where the list of files to merge can include specific named files but also file wildcards.  First we define a little Python function to resolve all the file names and construct the ADD FILES command, and then we invoke it using the SPSSINC PROGRAM extension command passing in the names.

begin program.
import spss, glob

def mergelist():        #1
    allfiles = []
    for item in sys.argv[1:]:    #2
        allfiles.extend(glob.glob(item))  #3
    cmd = ["ADD FILES /FILE=*"]
    if allfiles:
        cmd.extend(["""/FILE="%s" """ % f for f in allfiles if f])  #4
        print "Files to merge:\n%s" % "\n".join(allfiles)
        spss.Submit(cmd)        #5
end program.

* 6.
spssinc program mergelist "c:/temp/*.sav" "c:/cfsr/dev/splits/*14*.sav" "c:/data/cars.sav".

#1: mergelist is a function  that will be invoked by spssinc program.

#2: spssinc program passes its arguments using the sys.argv list that Python programs would normally use to read from the command line. The sys.argv contents are constructed by spssinc program. The first item in the list is the name of the program invoked, so we start with the list item after it (everything in Python is numbered from 0).

#3 glob.glob is a Python library function that expands wildcard expressions and returns a list of all the matches.  These are added at each loop iteration to the allfiles list.

#4 This extends cmd, which is a list, with FILE subcommands.  The %s is replaced on each iteration over the list of files in allfiles.  The result is a list where the first element is the ADD FILES /FILE=* and all the rest are FILE subcommands.  The "if" term screens out any empty items in the list, which would arise if no file matched a specification passed to glob.  Alternatively the code could be written to raise an error.

#5 Submit passes the command to the Statistics backend for execution.

#6 This line show the use of the mergelist function.  This example is silly and will fail as the sav files are not compatible, but it shows the usage with a mixture of completely explicit filespecs and ones with wildcards.  We assume that the total number of files to merge is within the 50-file limit of ADD FILES.  SPSSINC PROGRAM can be installed via the Utilities or Extensions menu if it isn't already present.



On Thu, Jun 16, 2016 at 6:38 AM, progster <[hidden email]> wrote:
I have several datasets that I want to ADD. Since the names are flexible I
would like a macro that could append the dataset listed in the macro call.
As I said the list (called nlist in the macro) is flexible.

the issue is that my macro append two times the first data (BBDD1).

I put some data for the sake of semplicity but real data are much more and
with very long lists, so I guess that a macro would be the better choice.



data list list / id .
begin data
1
2
end data.

dataset name BBDD1.


data list list / id .
begin data
3
4
end data.

dataset name BBDD2.


data list list / id .
begin data
5
6
end data.

dataset name BBDD3.



define !add_macro(nlist=!enclose("(",")"))
!let !cnlist=!nlist
!let !nvar=!head(!cnlist)
!do !dvar !in (!nlist)



DATASET ACTIVATE !nvar.
ADD FILES /FILE=*
  /FILE=!quote(!dvar).
EXECUTE.


!doend
!enddefine.

*Macro call.

!add_macro  nlist(BBDD1 BBDD2 BBDD3).




--
View this message in context: http://spssx-discussion.1045642.n5.nabble.com/macro-problem-may-be-head-expression-tp5732446.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



--
Jon K Peck
[hidden email]

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