Bookmark and Share

Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: st: Re-assigning local macro values within loops after each iteration

From   Nick Cox <>
Subject   Re: st: Re-assigning local macro values within loops after each iteration
Date   Mon, 20 Aug 2012 21:42:32 +0100

Sorry, but this sounds like the same question, and so my answer is
essentially the same. A -forvalues- loop cannot be extended once it is
set going; it can only be exited.

A flavour of the code fragments here is that you are setting up a new
variable for each individual, which seems weird to me. I get the
impression that you are more used to programming in some other
language and are only part-way translating to Stataish thinking. In
Stata, a variable is also a vector, but Stata has many variable-scale
operations and functions. Also, in practice, it is quite difficult to
program moderate-sized problems in Stata unless you have successfully
programmed several smaller-sized problems; there are too many things
to learn at once. (I don't think, by the way, that Stata is a
difficult language; I would say the same of any other language.)

Yet another thing that may be causing difficulty is some confusion
over when to use -in-, the -if- command and the -if- qualifier.

A more positive piece of advice is from what I know of demographic
theory it is eminently suitable to matrix formulations, which suggests
that Mata not Stata would be a good vehicle for this.


On Mon, Aug 20, 2012 at 8:15 PM, Stephen Cranney
<> wrote:
> Is there any way that I can retain the forvalues i = 1/`N' {
> syntax while using the while loop to make it continue generating after
> first generation?  The `i' reference here is how I connect the child
> to not only the parent, so I would like to keep it if I could, but the
> parent's date-of-giving-birth to calculate the child's date-of-birth,
> etc. I have a hard time seeing how I can make these connections while
> relying on the while loop. Here's an example of the syntax I mean:
>         replace generationnumber=generationnumber[`i']+1 if newvar`i'==1
>         replace parentid= id[`i'] if newvar`i'==1
>         replace birthdate= date[`i'] if newvar`i'==1
>         replace birthmonth= month[`i'] if newvar`i'==1
>         replace birthyear= year[`i'] if newvar`i'==1
> In response to the second concern, since each data point is a unique
> month/year/id combination, doubling it basically replicates the
> individual parent's characteristics (which I then change with
> reference to the `i' value that I want to retain). The Xnewvar
> variable I create deals with the problem of replicating the
> replications, so in the end I have, for example, 1000 observations for
> person 1, and 1000 observations for each of her children.
> Thanks again,
> Stephen
> On Mon, Aug 20, 2012 at 12:36 PM, Nick Cox <> wrote:
>> The Catch-22 here is that telling us part of your problem and showing
>> us part of your code is not enough for anyone to get a complete
>> understanding of your problem, while telling us all of your problem
>> and showing us all of your code would not really help, as you would be
>> unlikely to get anyone to invest time in understanding it all.
>> That said, there is an important misunderstanding here. The effect of
>> local N = _N
>> forvalues i = 1/`N' {
>> is to set up a loop with a particular upper limit that is fixed when
>> the -forvalues- loop starts. Changing the number of observations after
>> the loop has begun makes no difference to that, unless you change the
>> number in such a way that the loop terminates for other reasons. In
>> effect, you are "compiling" the number of observations into your code
>> when the loop starts, so that's fixed code.
>> My suggestion is that you may find it easier to set this up as a -while- loop.
>> local notdone = 1
>> local N = _N
>> while `notdone' {
>> }
>> with code within the loop to change
>> local notdone = 0
>> as appropriate. That certainly permits the number of observations to change.
>> That said, I am curious about the line
>> expand 2, gen(newvar`i')
>> which doubles the number of observations, just because of one
>> childbirth. Sounds like something out of the Alien* films to me, but
>> nothing like human demography? Shouldn't that -expand- be limited to
>> expansion of certain observations?
>> Nick
>> On Mon, Aug 20, 2012 at 7:02 PM, Stephen Cranney
>> <> wrote:
>>> I'm running a loop that loops over observations and generates new
>>> observations with expand when one of the observations has a certain
>>> value for one of the variables. (It's a population simulation that is
>>> simulating a new person when each childbirth=1, each observation is a
>>> month/year combination for a specific id). I initially set the macro
>>> at N= _N, but I want to re-set the macro every time it loops, this way
>>> the simulation can run past the second generation. As it is, it saves
>>> the initial _N value and terminates when that value is reached, but I
>>> would like to re-assign the macro so that it equals the value of _N
>>> after each expansion, allowing it to run into multiple generations
>>> until it terminates because of other parameters I've imposed.
>>> I have tried to place the macro within the loop to see if it will
>>> re-do it, but it does not seem to be working. My syntax so far:
>>> local N = _N
>>> forvalues i = 1/`N' {
>>>         local N = _N
>>>         if childbirth[`i'] == 1 {
>>>         expand 2, gen(newvar`i')
>>>         egen Xnewvar= rowtotal (newvar*)
>>>         drop if Xnewvar>1
>>>         drop if Xnewvar== 0 & generationnum!= 1
>>>         drop Xnewvar
>>>         replace generationnum=generationnum[`i']+1 if newvar`i'==1
>>> ** A lot of code that differentiates the new child's demographic
>>> characteristics from the parent's
>>>     }
>>> }
*   For searches and help try:

© Copyright 1996–2018 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   Site index