如何以编程方式从单个文件创建多个文件

时间:2016-11-10 02:50:45

标签: stata data-manipulation

我有一个关于家庭观察的数据集;每个家庭内都有个人。每个家庭的人数不同。家庭被识别为id,并且家庭成员根据他们被采访的顺序被识别。因此,如果家庭1有4个成员,变量id在所有成员中都是相同的,但变量order从1变为4.我遇到的问题是,对于某些变量,只有第一个家庭成员为其余成员回答;因此,我的数据集中有长格式和宽格式的混合。

我需要做的是向家庭的通讯员分配由家庭的第一个成员回答的价值。为了进一步解释我的数据结构,我将给出以下玩具示例:

clear
input    ///
    id order age o_a1 o_a2  v1a1 v1a2  v2a1   v2a2  o_b1 o_b2  v1b1 v1b2 v2b1 v2b2 
      1  1   54    1     .   50    .    100      .   .     .     .    .    .    .
      1  2   50    .     .    .    .      .      .   .     .     .    .    .    .
      1  3   27    .     .    .    .      .      .   .     .     .    .    .    .
      1  4   18    .     .    .    .      .      .   .     .     .    .    .    .
      2  1   60    3     4   70   23     10     15   2     5    80   90  100  140
      2  2   72    .     .    .    .      .      .   .     .     .    .    .    .
      2  3   58    .     .    .    .      .      .   .     .     .    .    .    .
      2  4   20    .     .    .    .      .      .   .     .     .    .    .    .
      2  5   23    .     .    .    .      .      .   .     .     .    .    .    .
end

在上面的玩具示例中,我有一个家庭等级变量id和个人等级变量:order对应于家庭中个人的顺序; age是他们的年龄。其他变量对应债务。对于每种类型的债务,家庭最多可以报告两笔债务。在这种情况下,有两种类型的债务,债务ab'。

o_a1给出第一个a类债务的家庭成员的订单。如果我们查看数据集中的第5行,o_a1是3,意味着拥有该债务的家庭的个人是该家庭的第三个人,即第7行,即58岁的人。同样,{{ 1}}表示具有第二债务的个人的顺序。

o_a2v1a对应于债务v2a的第一个变量,例如以美元计算的债务规模。这意味着家庭2的成员3将负债70美元,家庭2的个人4负债23美元。变量av2a1对应于债务的第二个变量,依此类推。

然后我们有另一种债务,债务v2a2,逻辑和以前一样。

实际上,数据包含每个债务的许多变量,以及更多类型的债务(教育,住房,信贷,信用卡等),因为我还不确定我还要研究哪些债务,我想将来自不同类型债务的信息存储在不同的数据集中,然后使用变量bmerge作为标识符id我感兴趣的数据。因此,我希望为每个债务设置一个表格,并将个人的变量(在这种情况下也是他们的年龄)保存在其他表格中。在实际数据集中,其他变量包括性别,教育程度等。

我已经设法为几笔债务做了这个,但由于有很多,我想知道是否有办法以编程方式执行此操作。

我将展示我为每种债务做了什么。

1)我保留了某个债务的变量,仅适用于order。对于债务order == 1,我只保留变量a和标识符o_a1 o_a2 v1a1 v1a2 v2a1 v2a2id

order

2)我drop age keep if order==1 keep id order *a* 从长到长的数据,以长格式获得每个家庭的个人的顺序,以便每个债务与其对应的债务人在一行。

reshape

3)我reshape long o_a , i(id) j(ncred) d save d个新文件中的数据。

reshape

4)我为save "debt_a.dta", replace 类型的每个赠券创建了一个数据集。

4.1)我为债务a创建了一个数据集,a1创建了新创建的变量drop中缺少的观察结果。

o_a

接下来,我use "debt_a.dta", clear drop if o_a == . 修改与债务drop相对应的变量,并仅保留属于信用a2a1)的行。

ncred == 1

为了能够在步骤5中附加债务drop *a2 keep if ncred==1 和债务a1的数据集,我从a2债务变量中删除了子串a1。我在步骤4.2中做了同样的事情。债务a1

a2

4.2)与步骤4.1相同,但对于债务foreach var of varlist * { local newname : subinstr local var "a1" "", all if "`newname'" != "`var'" { rename `var' `newname' } } save "debt_a1.dta", replace

a2

5)然后我use "debt_a.dta", clear drop if o_a == . drop *a1 keep if ncred==2 foreach var of varlist * { local newname : subinstr local var "a2" "", all if "`newname'" != "`var'" { rename `var' `newname' } } save "debt_a2.dta", replace 编辑了两个数据集。

append

所以我结束了以下数据集:

use "debt_a1.dta", clear 
append using "debt_a2.dta"
drop ncred 
replace order = o_a 
drop o_a
sort id order
save "debts_a_long.dta", replace

因此,现在我可以id order v1 v2 1 1 50 100 2 3 70 10 2 4 23 15 与其他表格的个人债务数据。我们假设单个数据表看起来像这样:

merge

因此,我不仅仅有关于年龄的信息,而且还有性和多年的教育。

现在我可以clear input /// id order age sex years_education 1 1 54 1 12 1 2 50 1 14 1 3 27 0 8 1 4 18 1 12 2 1 60 0 6 2 2 72 1 8 2 3 58 0 12 2 4 20 0 14 2 5 23 1 17 end save "individual.dta", replace 使用个人'sociodemographic'数据的债务数据。在这种情况下,merge对应于SQL中的左连接。

merge

结束于:

use "debts_a_long.dta", clear
joinby id order  using "individual.dta"

这就是为什么我想为每种类型的债务创建一个表。

有没有办法在Stata中以编程方式为每个债务执行此操作,而不是多次编写代码?

1 个答案:

答案 0 :(得分:1)

这清楚地解释了,但同时要掌握很多。最好一次提出一个问题!

我会做一些初步评论,并且可以在时间允许的情况下延长这个答案,除非其他人自然发布完整或更好的答案。

作为战略评论:将数据集细分为不同数据集的冲动在这里似乎是错误的。当然,您想要对数据的不同部分进行分析,但我认为没有多重原因可以解释为什么多个数据集会使这些更容易。

同样,我们非常重视mergejoinby等等,但我不会觉得它们是必需的。

以下是令牌代码,用于说明如何将order 1的个人信息复制到其他观察中:

clear
input id order age o_a1 o_a2 v1a1 v1a2 v2a1 v2a2 o_b1 o_b2 v1b1 v1b2 v2b1 v2b2 
1 1 54 1 . 50 . 100 . . . . . . .
1 2 50 . . . . . . . . . . . .
1 3 27 . . . . . . . . . . . .
1 4 18 . . . . . . . . . . . .
2 1 60 3 4 70 23 10 15 2 5 80 90 100 140
2 2 72 . . . . . . . . . . . .
2 3 58 . . . . . . . . . . . .
2 4 20 . . . . . . . . . . . .
2 5 23 . . . . . . . . . . . .
end 

forval j = 1/2 { 
    bysort id (order) : replace v1a`j' = v1a`j'[1] if order == o_a`j'[1] 
} 

list id order age *a1 *a2, sepby(id) 

     +------------------------------------------------------------+
     | id   order   age   o_a1   v1a1   v2a1   o_a2   v1a2   v2a2 |
     |------------------------------------------------------------|
  1. |  1       1    54      1     50    100      .      .      . |
  2. |  1       2    50      .      .      .      .      .      . |
  3. |  1       3    27      .      .      .      .      .      . |
  4. |  1       4    18      .      .      .      .      .      . |
     |------------------------------------------------------------|
  5. |  2       1    60      3     70     10      4     23     15 |
  6. |  2       2    72      .      .      .      .      .      . |
  7. |  2       3    58      .     70      .      .      .      . |
  8. |  2       4    20      .      .      .      .     23      . |
  9. |  2       5    23      .      .      .      .      .      . |
     +------------------------------------------------------------+

注意:要从变量名称包中删除后缀,您不需要循环。

rename *a1 *

将后缀a1剥离在任何位置(取决于该请求不会出现问题)。