我有一个调查数据集,其中包含每个家庭中的家庭ID和个人ID:个人1代表他/她自己的受访者。一些变量代表每个人与受访者的关系(例如,2为配偶,3为父母等),数据结构如下
???
现在我要做的是检测var1
中某些值的出现,如果出现,var1
和var2
的值是否满足某个条件。
例如,如果var1
和var2
满足
(var1 == 3 & var2 == 1) | (var1 == 4 & var2 == 1)
然后我可以将值1附加到新生成的变量,例如var3
,对于同一组中的每个人(在这种情况下为家庭,表示家庭结构),否则为0。
这似乎不是一个大问题,我想我应该使用一些
by group: egen
或
by group: gen
命令,但我不确定。我曾经使用像
这样的命令gen l_w_p = 0
by hhid: replace l_w_p = 1 if (var1 == 3 & a2004 == 1) | (var2 == 4 & a2004 == 1)
by hhid: replace l_w_p = 2 if (var1 == 3 & a2004 == 2) & (var2 == 4 & a2004 == 2)
但它似乎不起作用。这需要某种循环吗?
答案 0 :(得分:2)
我很难弄清楚你在问什么。一个好的策略是给出一个数据和所需输出的示例,尽可能简化问题的本质。这比用文字描述数据容易得多。
让我们开始吧。假设您的数据如下所示:
hhid x
1 1
1 2
2 0
2 1
并且您希望标记x
永远存在的家庭2.一种方式是
bys hhid: egen tag=max(cond(x==2,1,0))
这将产生:
hhid x tag
1 1 1
1 2 1
2 0 0
2 1 0
从内到外,对于每个成员,检查x
是否为2.如果是,则成员获得1
。如果没有,他会得到0
。 max()
计算整个家庭中此二进制指标的最大值。
条件可以变得更复杂,条件功能可以像俄罗斯娃娃一样嵌套。
这是一个更复杂的例子。假设您要在此数据集中标记有人x = 2
(标记为1
)或y >= 5
(标记为2
)的家庭:
hhid x y
1 1 1
1 2 2
2 0 3
2 1 4
3 1 5
3 3 5
我们先检查x
,然后检查y
x
条件是否为假:
bys hhid : egen tag=max(cond(x==2,1,cond(y>=5,2,0)))
这会产生:
hhid x y tag
1 1 1 1
1 2 2 1
2 0 3 0
2 1 4 0
3 1 5 2
3 3 5 2
答案 1 :(得分:2)
@Dimitriy V.Masterov提供了一个很好的具体答案,但是可以更广泛地解决这个问题。
正如他的答案所示,
egen
的{{1}}函数来处理产生0或1的真或假表达式,即指标(或在某些字段中流行的不良术语,虚拟) 。 一点点思考表明
max()
的{{1}}函数对群组进行处理,使其为0或1的真或假表达式等。整个故事在常见问题How do I create a variable recording whether any members of a group (or all members of a group) possess some characteristic?中充实(因此,元课程是利用您可用的资源)。
一步之遥是关于小组其他成员的问题,也在常见问题解答How do I create variables summarizing for each individual properties of the other members of a group?中讨论
有关可能有用的更全面的讨论,请参阅this article和 this article
另外两条评论:
一个。在像这样的代码
egen
min()
前缀对所做的事情没有任何影响。代码仍然在个人级别工作,并且前缀不会将操作扩展到组。这就是它“无效”的原因,通常是一个相当无用的错误报告。
湾轻度抽象在解释问题时非常有用,但命名变量中的抽象只会使代码更难以阅读。我不会使用诸如gen l_w_p = 0
by hhid: replace l_w_p = 1 if (var1 == 3 & a2004 == 1) | (var2 == 4 & a2004 == 1)
by hhid: replace l_w_p = 2 if (var1 == 3 & a2004 == 2) & (var2 == 4 & a2004 == 2)
,by:
等变量名称,这只会给记住什么是负担。使用令人回味的名称,例如var1
或var2
或其他。这不仅仅是个人风格,因为当你要求别人思考你的代码时(就像这里一样),能够轻松阅读它是一个很大的帮助。