1
votes

I'm trying to loop over dates in Stata.

I have an issue as I believe that my string variable is recognized as a date type.

For instance,

forvalues day = 1/31 {

    if `day' < 10 {
        local file_date ="2017-07-0`day'" 
        di `file_date'
    }
    else {
        local file_date ="2017-07-`day'"
        di `file_date'
    }

    *insert operation here
}

is printing 2009, 2008, 2007, etc.

even though the results should be 2017-07-01, 2017-07-02, etc.

Does anyone have a clue why this is happening?

By the way,

forvalues day=1/31 {
    if `day' < 10 {
       local file_date ="2017070`day'" 
       di `file_date'
    }
    else {
       local file_date ="201707`day'"
       di `file_date'
    }

    *insert operation here
}

works fine, but I want the hyphens in the variable.

1

1 Answers

1
votes

Some minor confusions can be cleared out of the way first:

  1. There are no string variables here in Stata's sense, just local macros.

  2. Stata has no variable type that is a date type. Stata does have ways of handling dates, naturally, but no dedicated date types.

The key point is what happens when you type a command that includes references to local macros (or for that matter, global macros; none here, but the principle is the same).

  1. All macro references are replaced by the contents of the macros.

  2. Then Stata executes the command as it stands (to the best of its ability; clearly, it must be legal for that to work).

The first time around your loop, the local macro reference is interpreted, so the first di (display) command now reads

di 2017-07-01

You're inclined to see that as a date, but display cannot read your mind. it sees an expression to be evaluated; that's part of its job to act as a calculator and then to display the results. Thus it sees no hyphens, but minus signs (and leading zeros are always allowed in numbers just as 0.1 is always allowed as well as .1). So, it is evaluated as 2017 minus 7 minus 1 -- and why you see 2009 should now be clear.

The solution is simple: use " " to indicate to display that you think of the characters as a literal string to be displayed as it comes.

Here is how I would rewrite your code:

forvalues day = 1/31 {
    local Day : di %02.0f `day' 
    local file_date "2017-07-`Day'" 
    di "`file_date'"
    *insert operation here
}

See this paper for the cleaner way to loop 01, 02, ..., 09, 10, ... 31.