Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Forvalues loop: Replacing value of local macro if local macro takes specific value

    Dear all,

    I have a variable 'bday' showing the birthday of the individual in the Stata date code. I have another variable inc'yyyy''mm' showing the income status of individuals in year 'yyyy' and month 'mm'. For example, the income status of december 2016 is inc201612 and the income status of february 2016 is inc20162.

    When the 'inc' variable takes the value '1' I need the 'inc' variabel for the given month and year to take the value 2, if the individual in that given month and year is between 18 and 29 years old.

    I try to this writing:

    Code:
    forval j = 2014/2021{
    forval k = 1/12 {
    local l = `j' - 29
    local h = `j'- 18
    local g = `k' + 1
    replace inc`j'`k' = 2 if mør`j'`k' == 1 ///
    & inrange(bday, td(1/`g'/`l', td(1/`k'/`h')
    }
    }
    This works well for the first 11 months of 2014 but then return the error code:

    Code:
    td(1/13/1985) invalid
    ...since my `g' always takes month `k' and adds 1, i.e., also in december. So I need to replace `g' with 1 whenever `g'==13 (or when `k'==12). How do I do this inside the forval-loop?
    Last edited by Emil Alnor; 01 Mar 2022, 04:37. Reason: spelling

  • #2
    You were given the following advice when you asked a very similar question about this data at

    https://www.statalist.org/forums/for...specific-value

    On the evidence here this awkward problem arises because you are holding data in wide layout when long layout is strongly preferable. Not just this problem but anything similar will be painful to formulate and solve. Also, at every step you are creating a bundle of new variables when there is need only for one, referring to the previous month.

    I strongly advise reshape long to make your immediate Stata future much more comfortable.
    This remains the best advice.

    The experienced users here generally agree that, with few exceptions, Stata makes it much more straightforward to accomplish complex analyses using a long layout of your data rather than a wide layout of the same data. You should try to achieve what you need with the data organized as it currently is, and seek the help of Statalist in doing so. The sort of problems you will encounter trying to use your reshaped data will almost certainly be solved by reshaping the data. It is much easier, for example, to compare the second observation to the first, the third to the second, and so on, than it is to compare the second variable to the first, the third to the second, etc.

    If you don't understand how to accomplish the required code, then, as you are advised to do in the Statalist FAQ linked to from the top of the page, as well as from the Advice on Posting link on the page you used to create your post, and present example data that we can work with to develop and demonstrate the necessary code.
    Last edited by William Lisowski; 01 Mar 2022, 11:16.

    Comment


    • #3
      Replace -& inrange(bday, td(1/`g'/`l', td(1/`k'/`h')- with:
      Code:
      & inrange(age(bday, mdy(`k', 1, `j')), 18, 29)
      By the way, I believe you have misreported either your code or the error message you are getting. With the code shown, I believe Stata will break with an error about the unbalanced parentheses in the -inrange- expression before it will even get to recognizing that td(1/13/1985) is invalid. In fact, in the code as shown, td(1/13/1985) never even occurs because the closing parenthesis is not in the code.
      Added: Crossed with #2, which gives excellent advice.
      Last edited by Clyde Schechter; 01 Mar 2022, 11:23.

      Comment


      • #4
        Originally posted by William Lisowski View Post
        You were given the following advice when you asked a very similar question about this data at

        https://www.statalist.org/forums/for...specific-value



        This remains the best advice.

        The experienced users here generally agree that, with few exceptions, Stata makes it much more straightforward to accomplish complex analyses using a long layout of your data rather than a wide layout of the same data. You should try to achieve what you need with the data organized as it currently is, and seek the help of Statalist in doing so. The sort of problems you will encounter trying to use your reshaped data will almost certainly be solved by reshaping the data. It is much easier, for example, to compare the second observation to the first, the third to the second, and so on, than it is to compare the second variable to the first, the third to the second, etc.

        If you don't understand how to accomplish the required code, then, as you are advised to do in the Statalist FAQ linked to from the top of the page, as well as from the Advice on Posting link on the page you used to create your post, and present example data that we can work with to develop and demonstrate the necessary code.
        I did indeed asked a very similar question in a different post, and was given the advise you mention. This was indeed, the best advice and I used it to solve the problem, which I raised in that post. I am sure you are correct that the long format is the best for solving complex analyses. My problem is, that I don't know how to reshape all of my data into the long format, the problem being that I have two variables showing the month and one variable showing the week.

        I tried searching for a solution for this and thought about writing a post about how to do it, but concluded that - given my data - it would be faster to solve the problems that I could with the months variables in the long format, and then write the final coding manually (a lot of lines) to put on the criteria that the week variable should indicate. This was, given my deadline, the required solution then. But if you have any reference to a guide on how to combine weekly and monthly data, I would be happy to know it, so I can look it up, the next time I face a similar problem.

        Comment


        • #5
          Originally posted by Clyde Schechter View Post
          Replace -& inrange(bday, td(1/`g'/`l', td(1/`k'/`h')- with:
          Code:
          & inrange(age(bday, mdy(`k', 1, `j')), 18, 29)
          By the way, I believe you have misreported either your code or the error message you are getting. With the code shown, I believe Stata will break with an error about the unbalanced parentheses in the -inrange- expression before it will even get to recognizing that td(1/13/1985) is invalid. In fact, in the code as shown, td(1/13/1985) never even occurs because the closing parenthesis is not in the code.
          Added: Crossed with #2, which gives excellent advice.
          Thanks Clyde for providing a much simpler solution to my problem, than I thought of originally.

          For the intrinsic value of learning Stata, I am still curious as to whether it is possible to generally "replace the value of local macro if local macro takes specific value" when looping, so I would much appreciate if you or someone else could inform me on this.

          Comment


          • #6
            Sure. Here's a toy example:
            Code:
            sysuse auto, clear
            
            local my_local 0
            
            levelsof rep78, local(reps)
            
            foreach r of local reps {
                if `r' == 4 {
                    local my_local 1
                }
                display "r = `r' & my_local = `my_local'"
            }
            I think the key thing here is to recognize that this is not done with an -if- clause at the end of a -local my_local...- command. It is done with an if command that precedes and brackets a -local- command.

            More generally, the -if- command is different from the -if- clause, and it is important to know when each is appropriate to use. An -if- clause is used to restrict the operation ofa command to a subset of the data. An -if- command is used to restrict execution of a command or block of commands to occur only under certain conditions; those conditions may reflect anything expressible in code about the state of the data, the program, the computer, the operating system, etc., and does not define subsets of the data for application. [And, in case you are wondering, yes, you can have a command with an -if- clause inside a block of commands that is guarded by an -if- command. In that case, the command is not executed at all unless the condition in the -if- command is met. But when that is met, the command applies only to the subset of the data defined in the -if- clause.

            For more information about -if- clauses, see -help if-.
            For more information about -if- commands, see -help ifcmd-.

            Comment

            Working...
            X