Announcement

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

  • A loop question

    COUN VILL HOUS P1_3
    110111 1 1 3
    110111 1 1 3
    110111 3 2 3
    110111 7 4 3
    110114 1 1 3
    110114 2 2 3
    110114 2 3 3
    110114 3 4 3
    110114 6 5 3
    Code:
     foreach COUN in 110111 110114 {
       foreach VILL in 1 2 3 4 5 6 7 {
        egen new4 = count(P1_3) if (P1_3==3), by (HOUS)
    }
    }
    I want to count P1_3 under the same COUN, VILL, and HOUS, so I write a loop. But it doesn't show what I expected. It just counts P1_3 under the same HOUS.
    Can someone tell me why? Thanks a million.

  • #2
    There's no need for a loop here, as you can simply make your by() option include COUN and VILL. And, per the documentation, -egen. .. = count()- accepts an expression, not just a value, so you can directly count the number of times P1_3 ==3.
    Code:
    egen new4 = count(P1_3==3), by (HOUS COUN VILL)

    Comment


    • #3
      Mike is absolutely right. But here's an explanation of why Walter's code didn't work as expected.

      While Walter constructs a loop over COUN and another one over VILL, note that there is no reference to either COUN or VILL inside the loop. Had the command in the loop read -egen new4 = count(P1_3) if (P13==3) & COUN == 'COUN' & VILL == `VILL'-, that would have been closer to a solution. This would not actually have worked either, because the variable new4 would be created the first time through the loop, and therefore attempting to re-create it would fail at the second time through. So it would have to be a bit more complicated than shown. But logically, the problem here was failing to actually refer to the parameters of the loop inside the loop. I'm not going to go farther down this path because, as Mike so correctly notes, this shouldn't be done with loops anyway.

      Now, there is a slight flaw in Mike's code as well. Despite what it looks like, count(P1_3 == 3) does not count how many times P1_3 equals 3. The -egen- function -count()- counts how many observations have a non-missing value of its argument. But P1_3 == 3 is a logical expression, and its value is always non-missing: either 0 or 1. So count(P1_3==3) simply gives a count of the total number of observations in each HOUS COUN VILL group, irrespective of the value of P1_3. This may be a distinction without a difference, as the example data shown by Walter has P1_3 == 3 in every observation. But if the full data set does contain other values of P1_3, they will be counted as well, which, presumably, is not wanted. So I think what is actually needed here is:

      Code:
      egen new4 = total(P1_3==3), by(HOUS COUN VILL)

      Comment


      • #4
        Clyde is absolutely right, of course. Thanks for catching my mistake.

        Comment


        • #5
          thanks you so much!

          i had another question,under the table,i want to create a new var(call new1),it shows that the youngest chid (P1_3==3:child) is male call 1,if the youngest child is female call 0,also under the same COUN, VILL, and HOUS.

          here is my code
          Code:
          egen new1 = min (age) if (sex==1) , by (COUN VILL HOUS)
          but the result isn't not my expected. it's doesn't count under the same COUN, VILL, and HOUS
          it just show the min age for me in new1. but my expectation is if the youngest child is male, it will be 1,else is 0.
          COUN VILL HOUS P1_3 sex age new1
          110111 1 1 3 male 15 1
          110111 1 1 3 male 13 1
          110111 3 2 3 female 25 0
          110111 7 4 3 female 20 0
          110114 1 1 3 male 20 1
          110114 1 1 3 female 26 1
          110114 2 2 3 male 17 1
          110114 3 3 3 female 12 0
          110114 6 5 3 male 10 1
          Last edited by Walter Wang; 08 May 2017, 20:15.

          Comment


          • #6
            Well, what you seek is not entirely well-defined. What do you want if there are two children of the same age in the same household, one of each sex? Which child's sex counts? This situation can arise either through adoption or as a result of fraternal twins, or two children born < 12 months apart. If your data set is sizeable, I would expect that this potential problem will actually arise in your data.

            Comment


            • #7
              i totally agree your concern. but if there are two children of the same age in the same household, one of each sex, i want the result is 1. is that possible to write a code for this question?

              Comment


              • #8
                This will do it. I have generated the desired variable as new2, and demonstrated that it matches your new1.

                Code:
                * Example generated by -dataex-. To install: ssc install dataex
                clear
                input long coun byte(vill hous p1_3) str6 sex byte(age new1)
                110111 1 1 3 "male"   15 1
                110111 1 1 3 "male"   13 1
                110111 3 2 3 "female" 25 0
                110111 7 4 3 "female" 20 0
                110114 1 1 3 "male"   20 1
                110114 1 1 3 "female" 26 1
                110114 2 2 3 "male"   17 1
                110114 3 3 3 "female" 12 0
                110114 6 5 3 "male"   10 1
                end
                
                //    FIND AGE OF YOUNGEST CHILD
                by coun vill hous, sort: egen age_youngest_child = ///
                    min(cond(p1_3 == 3), age, .)
                    
                //    NUMERICALLY ENCODE SEX
                label define gender 1 "male" 0 "female"
                encode sex, gen(gender)
                
                //    FIND GENDER OF YOUNGEST CHILD IN HOUSEHOLD
                //    IF MORE THAN ONE YOUNGEST CHILD, CHOOSE A MALE
                //    IF THERE IS ONE
                by coun vill hous, sort: egen new2 = ///
                    max(cond(age == age_youngest_child, gender, .))
                
                assert new2 == new1
                Note: This code depends crucially on the gender variable being coded 1 for male and 0 for female.

                Comment


                • #9
                  it works! thank you so so much!!

                  Comment

                  Working...
                  X