【问题标题】:Forvalues within if statementif 语句中的值
【发布时间】:2014-02-20 10:52:54
【问题描述】:

我一直在寻找这个特定问题的答案,但找不到任何答案。我有两组变量将数据集中的人分别与他们的母亲和父亲联系起来。我的目标是将人们与他们的兄弟姐妹联系起来。我的数据集如下所示:

person_id mom_id father id  child_1_mom child_2_mom child_1_dad child_2_dad

我只对保留具有相同父亲和母亲的孩子感兴趣,这意味着如果 child_*_mom 个人 ID 之一与 @ 987654323@ 身份证。我一直在尝试不同的东西,但我最好的猜测是类似这段代码,只是为了说明我在做什么。

forvalues i=1(1)17 {;
    replace child_`i'_mom="" if
        (forvalues j=1(1)17 {;
        (child_`i'_mom!=child_`j'_dad) &
        };
        (child_`i'_mom!=child_18_dad));
    };

如您所见,这有点创意,但我想出了最好的。我有 17 个母亲的孩子变量和 18 个父亲的孩子变量(我的数据集中有些有 18 个孩子)。我不想手动执行此操作的原因是我总共要执行上述操作 20 年,并且我计划稍后为妈妈和爸爸宏化子变量的数量。

然后我的问题是:有没有办法在循环中的if 语句中执行forvalues 循环?或者有没有更聪明的方法来解决这个问题?


进一步解释:

好的,所以我将尝试进一步详细说明这个问题。

原来数据集是这样的

person_id mother_id father_id

然后我对数据进行了排序,首先根据mother_id,并创建了一个变量,使得数据看起来像这样

person_id mother_id mother_n
     11      1         1  
     12      1         2
     13      2         1
     14      2         2
     15      2         3

等等。这已经为母亲和父亲做了。然后我重塑两个数据集,这样

mother_id child_1 child_2 child_3
     1       11      12      .
     2       13      14      15

从这个结果数据集(对于父亲和母亲),我将这些数据集合并到原始数据集中,这样

   person_id mother_id mother_n child_1_m child_2_m child_3_m child_1_f child_2_f
     11      1         1          11         12      .          ?          ?
     12      1         2          11         12      .          ?          ?
     13      2         1          13         14      15         ?          ?
     14      2         2          13         14      15         ?          ?
     15      2         3          13         14      15         ?          ?

因此,我对母亲的孩子和父亲的孩子都有变量。接下来我想让每个变量观察都丢失,其中child_ID 不在child_*_m 变量组和child_*_f 变量组中。

所以我的想法是我想制作一个自动化程序,在一个循环中执行此操作,而无需在整个程序中手动多次“替换 if ...”,因为我必须这样做多年,具有不同的最大子节点数。

希望这可以澄清。

【问题讨论】:

  • for* 在if 限定符内循环:无法完成。我不知道为什么这些数据采用这种形式。我可以想象人员标识符、母亲标识符、父亲标识符,并且可以看到父标识符可能丢失。为什么会有这么多变量?
  • 这来自丹麦的数据,包括该国在给定年份的每个人。最初,原始数据包括丹麦的每个人,并带有他们母亲和父亲的标识符。我们需要将人们的教育水平与他们的兄弟姐妹(父母相同)进行比较。所以我正在制作一个数据集,通过他们的父母标识符将给定人(母亲或父亲)的每个孩子与丹麦的每个人合并,所以是的。目前看起来有点奇怪,但我只是在制作数据 - 而不是分析它,呵呵。

标签: loops if-statement stata


【解决方案1】:

我会这样做:

gen byte mark = 1
forvalues i = 1/17 {
    replace mark = mark * inlist(child_`i'_mom, mom_id   , .) * ///
                          inlist(child_`i'_dad, father_id, .)
}  

这将创建一个二进制变量,当所有兄弟姐妹具有相同的父亲和母亲时为 1,否则为 0。在您随后的分析中,您可以将if mark == 1 条件添加到您的命令中,以确保您使用所需的子样本。

这只是旨在帮助您入门的初步代码。你应该考虑的一件事是我让缺失值没问题,因为不是每个人都有 17 个兄弟姐妹,但是当其中一个兄弟姐妹的父亲未知时怎么办?在根据您的情况调整此代码之前,您可能需要研究类似的事情。

【讨论】:

  • 非常感谢你的这个建议,我会研究它,虽然我一般想避免标记。也谢谢你的提醒:)。
  • 我更喜欢标记,因为它可以使数据保持完整,但您始终可以在开始分析之前输入keep if mark == 1。请记住不要保存您的数据...
【解决方案2】:

我会尝试(温和地)推动您进一步解释您的数据结构和变量定义。

如果每个观察对象都是一个人 (perid),他已经与他的母亲 (momid) 和父亲 (fathid) 相关联,那么将兄弟姐妹分组只是 sorting 的问题。下面是一个例子:

clear all
set more off

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

set obs 20

scalar a = 1
scalar b = 5

set seed 395

gen perid = _n
gen momid = floor((b-a+1)*runiform() + a)
gen fathid = floor((b-a+1)*runiform() + a)

list

*---------- group siblings -------------

isid momid fathid perid, sort

list, sepby(momid fathid)

我错过了什么或误解了什么?您如何改进您的帖子?

【讨论】:

  • 忽略这个,字符不够:)
  • 我在原帖中添加了进一步的解释。
  • 好的,我已经尝试了您的代码,非常感谢您尝试解决我的问题。然而,这并不是我想要的。我已经获得了数据集的描述,并且事先决定它必须看起来像我添加到原始帖子中的那个。
【解决方案3】:

所以我现在理解你的问题如下:

当母亲只从一个父亲变成孩子,而父亲只从一个母亲变成孩子时,你想保留人。

我会坚持使用原始形式的数据集。据我所知,这是一份有母亲身份证和父亲身份证的孩子名单。如果所有有同一个母亲的孩子也有同一个父亲,那么我们知道第一个条件是正确的。这是示例中的第一行。如果所有具有相同父亲的孩子也有相同的母亲,我们知道第二个条件是正确的。这是示例中的第二行。将这些布尔变量相乘意味着这两个条件都必须为真。

bys mother_id (father_id): gen byte one_husband = father_id[1] == father_id[_N]
bys father_id (mother_id): gen byte one_wife    = mother_id[1] == mother_id[_N]
gen byte touse = one_husband * one_wife

这个解决方案当然假设丹麦登记处的母亲或父亲都没有丹麦以外的孩子......

之后,您可以以任何您喜欢的方式使用touse 变量。通常,我更愿意在后续分析中将其用作if 条件的一部分,但您可以keep touse == 1 的观察结果。当touse == 0 时,您似乎想通过用缺失值替换某些变量来强加此选择。该解决方案最不吸引人(即我强烈建议您不要这样做),因为您更改数据的方式决不能保证您的选择还需要在未来的分析中应用;它太间接,太含蓄而不能成为好的风格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多