Passing the value of a variable in the dataset to a macro argument: how to?

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

Passing the value of a variable in the dataset to a macro argument: how to?

Sundance Kid
Hello All,

Please help. I'm completely stuck now. I want to recode a number of contiguous variables using a macro. Beforehand I do not know how many variables I will have to recode. But there is a calculated variable in my datafile that has the same value for every case and this value is the the number of variables that I will need to recode. What I have written so far will help you understand what I mean.



DEFINE macro1 (arg1 = !TOKENS(1))

RECODE Percent.0 to !CONCAT('Percent.',!arg1)   (100=99).
EXECUTE.

!ENDDEFINE.


macro1 arg1 = 5


So all my variables will be of the form Percent.0, Percent.1 etc. (they are indexed from a restructure). So as you can see when I call this macro with arg1 = 5 it recodes all the variables Percent.0, Percent.1, Percent.2, percent.3, Percent.4 Percent.5. But I could have Percent.6 , Percent.7 etc after the restructure.

So where I am up to now is I have a variable in my dataset (lets call it diff_max) that has the same value in it i.e for all cases the value is the same number. This number will tell me how many variables I need to recode. As you can see above I have manually entered arg1 = 5. But what I want to know is how can I tell SPSS to take the value in the variable diff_max as the argument to the macro (so that I don't have to manually change arg1).

So the logic/psudedocode of what I have in mind is as follows.


DEFINE macro1 (arg1 = !TOKENS(1))

RECODE Percent.0 to !CONCAT('Percent.',!arg1)   (100=99).
EXECUTE.

!ENDDEFINE.


macro1 arg1 = MAX(diff_max)

or

macro1 arg1 = the value in diff_max




So in summary I want to pass the value in diff_max to arg1.


Reply | Threaded
Open this post in threaded view
|

Re: Passing the value of a variable in the dataset to a macro argument: how to?

Art Kendall
Why not do the recode before the restructure?
Art Kendall
Social Research Consultants
On 9/17/2013 3:48 PM, Sundance Kid [via SPSSX Discussion] wrote:
Hello All,

Please help. I'm completely stuck now. I want to recode a number of contiguous variables using a macro. Beforehand I do not know how many variables I will have to recode. But there is a calculated variable in my datafile that has the same value for every case and this value is the the number of variables that I will need to recode. What I have written so far will help you understand what I mean.



DEFINE macro1 (arg1 = !TOKENS(1))

RECODE Percent.0 to !CONCAT('Percent.',!arg1)   (100=99).
EXECUTE.

!ENDDEFINE.


macro1 arg1 = 5


So all my variables will be of the form Percent.0, Percent.1 etc. (they are indexed from a restructure). So as you can see when I call this macro with arg1 = 5 it recodes all the variables Percent.0, Percent.1, Percent.2, percent.3, Percent.4 Percent.5. But I could have Percent.6 , Percent.7 etc after the restructure.

So where I am up to now is I have a variable in my dataset (lets call it diff_max) that has the same value in it i.e for all cases the value is the same number. This number will tell me how many variables I need to recode. As you can see above I have manually entered arg1 = 5. But what I want to know is how can I tell SPSS to take the value in the variable diff_max as the argument to the macro (so that I don't have to manually change arg1).

So the logic/psudedocode of what I have in mind is as follows.


DEFINE macro1 (arg1 = !TOKENS(1))

RECODE Percent.0 to !CONCAT('Percent.',!arg1)   (100=99).
EXECUTE.

!ENDDEFINE.


macro1 arg1 = MAX(diff_max)

or

macro1 arg1 = the value in diff_max




So in summary I want to pass the value in diff_max to arg1.





To start a new topic under SPSSX Discussion, email [hidden email]
To unsubscribe from SPSSX Discussion, click here.
NAML

Art Kendall
Social Research Consultants
Reply | Threaded
Open this post in threaded view
|

Re: Passing the value of a variable in the dataset to a macro argument: how to?

Sundance Kid
Before restructure the variable percent has percentage values in it - no missing values. After the restructure the percent.0, percent.1 etc variables contain some values but also now hold missing values. The restructure is indexed by another variable and it is this variable that gives the .0, .1, .2 etc variable name ending. After restructure it is missing values that I want to turn to zero. So in fact my syntax should say (MISSING =0). I wrote 100 =99 above just as I was testing out the concept. So the missing values don't exist before the restructure. Hence I can't recode before restructure. If there was another way to tell SPSS to make missing=0 upon the restructure that might work.
Reply | Threaded
Open this post in threaded view
|

Re: Passing the value of a variable in the dataset to a macro argument: how to?

Art Kendall
I don't have time to test this but try something like this if you know the maximum number of percentages say 10.
compute havevalid = nvalid(percent.0 to percent.9).
vector percent = percent.0 to percent.10
loop #i = 1 to 10 If #i gt havevalid.
compute percent(#i) = 0.
end loop.


If this is a one time run looking at the variable view should tell you the max number of percent variables.

Art Kendall
Social Research Consultants
On 9/17/2013 6:43 PM, Sundance Kid [via SPSSX Discussion] wrote:
Before restructure the variable percent has percentage values in it - no missing values. After the restructure the percent.0, percent.1 etc variables contain some values but also now hold missing values. The restructure is indexed by another variable and it is this variable that gives the .0, .1, .2 etc variable name ending. After restructure it is missing values that I want to turn to zero. So in fact my syntax should say (MISSING =0). I wrote 100 =99 above just as I was testing out the concept. So the missing values don't exist before the restructure. Hence I can't recode before restructure. If there was another way to tell SPSS to make missing=0 upon the restructure that might work.



To start a new topic under SPSSX Discussion, email [hidden email]
To unsubscribe from SPSSX Discussion, click here.
NAML

Art Kendall
Social Research Consultants
Reply | Threaded
Open this post in threaded view
|

Re: Passing the value of a variable in the dataset to a macro argument: how to?

Jon K Peck
In reply to this post by Sundance Kid
Macros are expanded into syntax before any data are read, so they cannot take data into account in the expansion.  However, if you have installed the Python Essentials, this task is very easy to do.  The program below assumes that the count is in a variable named ccount.  It reads the value in the first case and runs a recode substituting that value into the TO expression.


data list list /percent.0 to percent.9 ccount (11F8.0).
begin data
1 2 3 100 99 6 7 8 9 10 5
end data.
dataset name percents.
list.

begin program.
import spss, spssdata
count = spssdata.Spssdata("ccount").fetchone()
spss.Submit("""RECODE percent.0 to percent.%s (100=99)""" % int(count[0]))
end program.



Jon Peck (no "h") aka Kim
Senior Software Engineer, IBM
[hidden email]
phone: 720-342-5621




From:        Sundance Kid <[hidden email]>
To:        [hidden email],
Date:        09/17/2013 01:50 PM
Subject:        [SPSSX-L] Passing the value of a variable in the dataset to a              macro              argument: how to?
Sent by:        "SPSSX(r) Discussion" <[hidden email]>




Hello All,

Please help. I'm completely stuck now. I want to recode a number of
contiguous variables using a macro. Beforehand I do not know how many
variables I will have to recode. But there is a calculated variable in my
datafile that has the same value for every case and this value is the the
number of variables that I will need to recode. What I have written so far
will help you understand what I mean.



DEFINE macro1 (arg1 = !TOKENS(1))

RECODE Percent.0 to !CONCAT('Percent.',!arg1)   (100=99).
EXECUTE.

!ENDDEFINE.


macro1 arg1 = 5


So all my variables will be of the form Percent.0, Percent.1 etc. (they are
indexed from a restructure). So as you can see when I call this macro with
arg1 = 5 it recodes all the variables Percent.0, Percent.1, Percent.2,
percent.3, Percent.4 Percent.5. But I could have Percent.6 , Percent.7 etc
after the restructure.

So where I am up to now is I have a variable in my dataset (lets call it
*diff_max*) that has the same value in it i.e for all cases the value is the
same number. This number will tell me how many variables I need to recode.
As you can see above I have manually entered arg1 = 5. But what I want to
know is how can I tell SPSS to take the value in the variable diff_max as
the argument to the macro (so that I don't have to manually change arg1).

So the logic/psudedocode of what I have in mind is as follows.


DEFINE macro1 (arg1 = !TOKENS(1))

RECODE Percent.0 to !CONCAT('Percent.',!arg1)   (100=99).
EXECUTE.

!ENDDEFINE.


macro1 arg1 = *MAX(diff_max)*

or

macro1 arg1 = the value in diff_max




So in summary I want to pass the value in diff_max to arg1.






--
View this message in context:
http://spssx-discussion.1045642.n5.nabble.com/Passing-the-value-of-a-variable-in-the-dataset-to-a-macro-argument-how-to-tp5722070.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


Reply | Threaded
Open this post in threaded view
|

Re: Passing the value of a variable in the dataset to a macro argument: how to?

Kirill Orlov
In reply to this post by Sundance Kid
Passing a value to a macro is done by using WRITE and then INSERT (or INCLUDE) commands.
This looks a bit awkward but is normal, given that macro facility is very old feature.
(SPSS *must* some day improve macros radically and not only teach macros to do simple arithmetics but also make it able to catch up a data value on the fly right during the macro expansion.)

Below are two examples of how to pass a value (which is a number of counted variables) to a macro.

data list free /v1 v2 v3 v4 v5.
begin data
1 2 3 4 5
end data.


*Variant 1.
*Count the number of variables and WRITE out the whole
*command which make use of that value.
*INSERT the command.
*This variant can be put inside a single macro body.
define !macro()
count nvars= v1 to v5 (lo thru hi miss).
string nvars2 (a8).
comp nvars2= ltrim(string(nvars,f8)).
do if $casenum=1.
-write outfile= 'c:\temp\filename.sps'
    /'recode v1 to v' nvars2(a8) '(else=10).'.
end if.
exec.
insert file= 'c:\temp\filename.sps'.
exec.
erase file 'c:\temp\filename.sps'.
!enddefine.

!macro.


*Variant 2.
*Count the number of variables and WRITE that value
*as a macro (the macro will be just that value).
*INSERT this macro definition (register it in SPSS memory).
*Substitute this macro's call into the subsequent syntax where needed
*(this subsequent syntax can be a regular syntax or a part of some macro's body).
count nvars= v1 to v5 (lo thru hi miss).
do if $casenum=1.
-write outfile= 'c:\temp\filename.sps'
    /'define !value()' nvars(f8) ' !enddefine.'.
end if.
exec.

insert file= 'c:\temp\filename.sps'.

recode v1 to v!value (else=10).
exec.
erase file 'c:\temp\filename.sps'.

*Or the last three commands as a macro:.
define !macro()
recode v1 to !conc('v',!value) (else=10).
exec.
erase file 'c:\temp\filename.sps'.
!enddefine.

!macro.


17.09.2013 23:48, Sundance Kid пишет:
Hello All,

Please help. I'm completely stuck now. I want to recode a number of
contiguous variables using a macro. Beforehand I do not know how many
variables I will have to recode. But there is a calculated variable in my
datafile that has the same value for every case and this value is the the
number of variables that I will need to recode. What I have written so far
will help you understand what I mean.



DEFINE macro1 (arg1 = !TOKENS(1))

RECODE Percent.0 to !CONCAT('Percent.',!arg1)   (100=99).
EXECUTE.

!ENDDEFINE.


macro1 arg1 = 5


So all my variables will be of the form Percent.0, Percent.1 etc. (they are
indexed from a restructure). So as you can see when I call this macro with
arg1 = 5 it recodes all the variables Percent.0, Percent.1, Percent.2,
percent.3, Percent.4 Percent.5. But I could have Percent.6 , Percent.7 etc
after the restructure.

So where I am up to now is I have a variable in my dataset (lets call it
*diff_max*) that has the same value in it i.e for all cases the value is the
same number. This number will tell me how many variables I need to recode.
As you can see above I have manually entered arg1 = 5. But what I want to
know is how can I tell SPSS to take the value in the variable diff_max as
the argument to the macro (so that I don't have to manually change arg1).

So the logic/psudedocode of what I have in mind is as follows.


DEFINE macro1 (arg1 = !TOKENS(1))

RECODE Percent.0 to !CONCAT('Percent.',!arg1)   (100=99).
EXECUTE.

!ENDDEFINE.


macro1 arg1 = *MAX(diff_max)*

or

macro1 arg1 = the value in diff_max




So in summary I want to pass the value in diff_max to arg1.

Reply | Threaded
Open this post in threaded view
|

Re: Passing the value of a variable in the dataset to a macro argument: how to?

Albert-Jan Roskam
In reply to this post by Jon K Peck
That's very concise. So using a context manager is not mandatory here? (apparently not)
 
Regards,
Albert-Jan


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a
fresh water system, and public health, what have the Romans ever done for us?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 


From: Jon K Peck <[hidden email]>
To: [hidden email]
Sent: Wednesday, September 18, 2013 4:15 PM
Subject: Re: [SPSSX-L] Passing the value of a variable in the dataset to a macro argument: how to?

Macros are expanded into syntax before any data are read, so they cannot take data into account in the expansion.  However, if you have installed the Python Essentials, this task is very easy to do.  The program below assumes that the count is in a variable named ccount.  It reads the value in the first case and runs a recode substituting that value into the TO expression.


data list list /percent.0 to percent.9 ccount (11F8.0).
begin data
1 2 3 100 99 6 7 8 9 10 5
end data.
dataset name percents.
list.

begin program.
import spss, spssdata
count = spssdata.Spssdata("ccount").fetchone()
spss.Submit("""RECODE percent.0 to percent.%s (100=99)""" % int(count[0]))
end program.



Jon Peck (no "h") aka Kim
Senior Software Engineer, IBM
[hidden email]
phone: 720-342-5621




From:        Sundance Kid <[hidden email]>
To:        [hidden email],
Date:        09/17/2013 01:50 PM
Subject:        [SPSSX-L] Passing the value of a variable in the dataset to a              macro              argument: how to?
Sent by:        "SPSSX(r) Discussion" <[hidden email]>




Hello All,

Please help. I'm completely stuck now. I want to recode a number of
contiguous variables using a macro. Beforehand I do not know how many
variables I will have to recode. But there is a calculated variable in my
datafile that has the same value for every case and this value is the the
number of variables that I will need to recode. What I have written so far
will help you understand what I mean.



DEFINE macro1 (arg1 = !TOKENS(1))

RECODE Percent.0 to !CONCAT('Percent.',!arg1)   (100=99).
EXECUTE.

!ENDDEFINE.


macro1 arg1 = 5


So all my variables will be of the form Percent.0, Percent.1 etc. (they are
indexed from a restructure). So as you can see when I call this macro with
arg1 = 5 it recodes all the variables Percent.0, Percent.1, Percent.2,
percent.3, Percent.4 Percent.5. But I could have Percent.6 , Percent.7 etc
after the restructure.

So where I am up to now is I have a variable in my dataset (lets call it
*diff_max*) that has the same value in it i.e for all cases the value is the
same number. This number will tell me how many variables I need to recode.
As you can see above I have manually entered arg1 = 5. But what I want to
know is how can I tell SPSS to take the value in the variable diff_max as
the argument to the macro (so that I don't have to manually change arg1).

So the logic/psudedocode of what I have in mind is as follows.


DEFINE macro1 (arg1 = !TOKENS(1))

RECODE Percent.0 to !CONCAT('Percent.',!arg1)   (100=99).
EXECUTE.

!ENDDEFINE.


macro1 arg1 = *MAX(diff_max)*

or

macro1 arg1 = the value in diff_max




So in summary I want to pass the value in diff_max to arg1.






--
View this message in context:
http://spssx-discussion.1045642.n5.nabble.com/Passing-the-value-of-a-variable-in-the-dataset-to-a-macro-argument-how-to-tp5722070.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




Reply | Threaded
Open this post in threaded view
|

Re: Passing the value of a variable in the dataset to a macro argument: how to?

Richard Ristow
In reply to this post by Sundance Kid
At 03:48 PM 9/17/2013, Sundance Kid wrote:

>I want to recode a number of contiguous variables using a macro.
>Beforehand I do not know how many variables I will have to recode.
>But there is a calculated variable in my datafile that has the same
>value for every case and this value is the number of variables that
>I will need to recode.

How about

COMPUTE #Count = 0.
DO REPEAT Pct=Percent.0 TO Percent.99.
.  COMPUTE #Count = #Count + 1.
.  DO IF   #Count LE HoweverManyYouWant.
.     RECODE Pct (100=99).
.  END IF.
END REPEAT.

=====================
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
Reply | Threaded
Open this post in threaded view
|

Re: Passing the value of a variable in the dataset to a macro argument: how to?

Sundance Kid
In reply to this post by Kirill Orlov
Thank you a million Kirill Orlov. I used the second variant which worked just fine.