如何在stata中跨层次数据(家庭 - 个人)编写循环?

时间:2015-01-10 10:49:51

标签: stata data-manipulation

我现在正在制作家庭调查数据集,并且我想根据他们与户主的关系给某些成员额外的身份证。更具体地说,我需要确定户主和他/她的配偶的成年子女,如果已婚,并分配他们的子家庭ID"。

变量是:hhid - 家庭ID; pid - 个人身份证明; relhead - 与头脑的关系。

关于relhead1表示头部,6表示儿童,7表示儿媳。下面是一些示例数据,包括最后一列所需的结果。我假设只要6跟随7,它们就构成了一对,属于同一个子家庭。

         hhid   pid  relhead         sub_hhid(desired)
          50     1    1                  1
          50     2    3                  1
          50     3    6                  2
          50     4    6                  3
          50     5    7                  3
        -----------------------------------------------
          67     1    1                  1
          67     3    6                  2
          67     4    7                  2

以下是一些想法:

在一个家庭中可能有已婚和未婚的成年子女,家庭结构有点复杂,所以我想在一个家庭中写一些循环。

基本的想法是在外圈我们识别待在家里的孩子,然后检查是否有配偶出现,如果有,那么我们给这对夫妇一个指标,如果没有,我们继续和给出一个stay_chil其他指标。在遍历家庭中所有可能的成员之后,我们获得了一系列家庭内部ID。为了便于进一步分析,我需要某种外部ID变量来分隔子系列。

* Define N as the total number of household, n as number of individual household size
* sty_chil is indicator for adult child who living with parents(head) 
* sty_chil_sp is adult child's spouse
* "hid" and "ind_id" are local macros
forvalue hid=1/N {
  forvalue ind_id= 1/n {
       if sty_chil[`ind_id']==1 {
          check if sty_chil_sp[`ind_id+1']==1 {
          if yes then assign sub_hhid to this couples *a 6-7 pairs,identifid as couple
                                  } 
                      else                    { * single 6 identifid as single child
           assign sub_hhid to this child
                               }
          else         {         *Other relationships rather than 6, move forward
               ++ind_id           the members within a household
                       }
                   ++hid         *move forward across  households
                    }  

内置的stata by,sort:功能非常强大但在这里我想对待属于某些标准的家庭成员并留下其他不受影响的东西,所以if-else类型的循环对我来说更自然(甚至by:可能达到我的目标,当情况变得不那么简单时,它总是太委婉,我们无法用尽所有可能的家庭模式模式。)

一个直接的问题是我不知道如何在房屋ID和个人ID之间编写循环,因为我曾经使用by命令获取家庭规模(外部循环的增量)(I&# 39;我不确定在这种情况下它是1或家庭成员的数量),而且我不确定是否混合了by和if循环是一个很好的编程习惯,我赞成写a"完整循环"在这种情况下。 请给我一些线索如何实现我的目标并为我提供(说明)伪代码。

一个额外的问题是我找不到包含by命令内容的ado文件,它是否存在?

1 个答案:

答案 0 :(得分:2)

我将从用于创建匹配的假设是否合理的问题中抽象出来。相反,让它成为使用显式循环达到而不使用所需结果的示例。一些逻辑和使用下标(请参阅help subscripting)可以帮助您实现目标。

clear
set more off

*----- example data -----

input ///
hhid   pid  relhead  sub_hhid
50     1    1          1
50     3    6          2
50     4    6          3
50     5    7          3
67     1    1          1
67     3    6          2
67     4    7          2
67     5    6          3
end

list, sepby(hhid)

*----- what you want -----

bysort hhid (pid): gen hhid2 = sum( !(relhead == 7 & relhead[_n-1] == 6) )

list, sepby(hhid)

正如您所看到的,一行代码可以帮助您实现目标。原因如下:

  1. sum()给出了运行总和。作为条件的sum()的参数可以是True或False。 !表示逻辑(请参阅help operators)。

  2. 如果关系是女儿/女婿并且之前的关系是女儿/儿子的情况,则条件评估为True并且取值为1,将运行总和增加1.如果它的计算结果为False,意味着该关系是女儿/女婿而前一个关系是女儿/儿子,那么它取值为0并且运行总和不会增加。这给出了你寻求的结果。

  3. 您使用by:前缀执行此操作,因为您想要独立检查每个原始家庭,可以这么说。

  4. 对于每个原始家庭的第一次观察,条件总是评估为True。这是因为没有"之前的"观察(关系),Stata认为relhead缺失(。,一个非常大的数字)因此,不等于6.这使得每个子组的第一次观察的运行总和从0到1等等。

  5. 结论:了解如何使用by:并利用Stata提供的功能。不要逆流而行;不在这里。

    修改

    请注意,您应该从头开始提供代表示例,而不是逐步更改示例数据集。不这样做可以提供最初确定,完全不合适的答案。

    对于修改后的示例,请添加:

    replace hhid2 = 1 if !inlist(relhead,6,7)
    

    这将简单地将任何不是6或7的人分配给同一家庭。假设头部总是hhid2 == 1。如果头部可以有hhid2 != 1,那么

    bysort hhid (relhead): replace hhid2 = hhid2[1] if !inlist(relhead,6,7)
    

    应该有用。

    您可以点击:

    bysort hhid (pid): replace hhid2 = hhid2[_n-1] + 1 if hhid2 != hhid2[_n-1] & _n > 1
    

    但是因为它们是ID,所以它并不是必需的。

    最后,使用:

    gen hhid3 = string(hhid) + "_" + string(hhid2)
    

    使用50_150_250_3等格式创建ID

    就像我之前说过的,如果你的数据表现出更多的复杂性,你应该提出一个相关的例子。