Stata-根据变量中的值分配不同的变量
对不起,这个标题让人困惑。希望下面是清楚的 我使用的是Stata,我想将值1赋给一个变量,该变量取决于不同变量中的值。我有20个顺序变量,还有20个相应的变量。例如,如果order1=3,我想分配variable3=1。下面是一个片段,如果每个变量只有3个,那么最终的数据集将是什么样子Stata-根据变量中的值分配不同的变量,stata,Stata,对不起,这个标题让人困惑。希望下面是清楚的 我使用的是Stata,我想将值1赋给一个变量,该变量取决于不同变量中的值。我有20个顺序变量,还有20个相应的变量。例如,如果order1=3,我想分配variable3=1。下面是一个片段,如果每个变量只有3个,那么最终的数据集将是什么样子 现在我用两个循环来做这件事,但我必须用另一个循环来做这件事,再经过9次,再加上我要用几百个数据文件来做这件事。我想提高效率 forvalues i = 1/20 { forvalues j = 1/2
现在我用两个循环来做这件事,但我必须用另一个循环来做这件事,再经过9次,再加上我要用几百个数据文件来做这件事。我想提高效率
forvalues i = 1/20 {
forvalues j = 1/20 {
replace variable`j' = 1 if order`i'==`j'
}
}
是否可以使用order'i'的值直接分配变量[order'i'value]?然后我就可以摆脱上面的j循环了。像这样的
forvalues i = 1/20 {
replace variable[`order`i'value] = 1
}
谢谢你的帮助
*****2月2日补充澄清**
我把我的问题和数据集简化得太多了,因为我提出的解决方案很有效,但没有达到我真正想要做的。谢谢你们三位提出的解决方案。我在我的岗位上不够清楚
要澄清的是,我的数据没有每个订单的一对一对应关系#赋值变量#a 1(如果没有缺失的话)。例如,order1=3的第一个观察值variable1不应该得到1,variable3应该得到1。我在最初的帖子中没有提到的是,我实际上正在检查其他条件,将其设置为1
为了了解更多的背景,我正在按出生顺序(第一个孩子、第二个孩子等)统计不同年龄母亲的出生情况。所以在数据中,每一行都是一个女人,每一个顺序都是出生的数字(顺序1=3,这是她的第三个孩子)。相应的变量#s是计数(变量#表示该妇女有一个出生顺序为#的孩子)。我在帖子中提到,我在公元前9次这样做,我是为5岁年龄组(15-19;20-24;等等)做的。因此,第一组变量#是15-19岁女性按顺序出生的数量;第二组变量#是20-24岁女性按顺序出生的数量。在这之后,我用不同的方式(通过女性教育、地理等)总结了这些数字
因此,对于附加循环,我所做的事情更像这样
forvalues k = 1/9{
forvalues i = 1/20 {
forvalues j = 1/20 {
replace variable`k'_`j' = 1 if order`i'==`j' & age`i'==`k' & birth_age`i'<36
}
}
}
值k=1/9时的{
对于值i=1/20{
For值j=1/20{
如果顺序'i'='j'和年龄'i'='k'和出生年龄'i'i将重塑
两次,则替换变量'k''uj'=1。首先重塑
为长
,然后在上条件变量
!缺失(顺序)
,然后重塑
回到宽
* generate your data
clear
set obs 3
forvalues i = 1/3 {
generate order`i' = .
local k = (3 - `i' + 1)
forvalues j = 1/`k' {
replace order`i' = (`k' - `j' + 1) if (_n == `j')
}
}
list
*. list
*
* +--------------------------+
* | order1 order2 order3 |
* |--------------------------|
* 1. | 3 2 1 |
* 2. | 2 1 . |
* 3. | 1 . . |
* +--------------------------+
* I would rehsape to long, then back to wide
generate id = _n
reshape long order, i(id)
generate variable = !missing(order)
reshape wide order variable, i(id) j(_j)
order order* variable*
drop id
list
*. list
*
* +-----------------------------------------------------------+
* | order1 order2 order3 variab~1 variab~2 variab~3 |
* |-----------------------------------------------------------|
* 1. | 3 2 1 1 1 1 |
* 2. | 2 1 . 1 1 0 |
* 3. | 1 . . 1 0 0 |
* +-----------------------------------------------------------+
我将重塑
两次。首先重塑
到长
,然后将变量
条件设置为!缺失(顺序)
,然后重塑
回到宽
* generate your data
clear
set obs 3
forvalues i = 1/3 {
generate order`i' = .
local k = (3 - `i' + 1)
forvalues j = 1/`k' {
replace order`i' = (`k' - `j' + 1) if (_n == `j')
}
}
list
*. list
*
* +--------------------------+
* | order1 order2 order3 |
* |--------------------------|
* 1. | 3 2 1 |
* 2. | 2 1 . |
* 3. | 1 . . |
* +--------------------------+
* I would rehsape to long, then back to wide
generate id = _n
reshape long order, i(id)
generate variable = !missing(order)
reshape wide order variable, i(id) j(_j)
order order* variable*
drop id
list
*. list
*
* +-----------------------------------------------------------+
* | order1 order2 order3 variab~1 variab~2 variab~3 |
* |-----------------------------------------------------------|
* 1. | 3 2 1 1 1 1 |
* 2. | 2 1 . 1 1 0 |
* 3. | 1 . . 1 0 0 |
* +-----------------------------------------------------------+
使用一个简单的forvalues
循环和generate
和missing()
比其他建议的解决方案(到目前为止)要快几个数量级。对于这个问题,你只需要一个循环就可以遍历完整的变量列表,而不是像原始帖子中那样需要两个。下面的一些代码显示了这两个点
*----------------- generate some data ----------------------
clear all
set more off
local numobs 60
set obs `numobs'
quietly {
forvalues i = 1/`numobs' {
generate order`i' = .
local k = (`numobs' - `i' + 1)
forvalues j = 1/`k' {
replace order`i' = (`k' - `j' + 1) if (_n == `j')
}
}
}
timer clear
*------------- method 1 (gen + missing()) ------------------
timer on 1
quietly {
forvalues i = 1/`numobs' {
generate variable`i' = !missing(order`i')
}
}
timer off 1
* ----------- method 2 (reshape + missing()) ---------------
drop variable*
timer on 2
quietly {
generate id = _n
reshape long order, i(id)
generate variable = !missing(order)
reshape wide order variable, i(id) j(_j)
}
timer off 2
*--------------- method 3 (egen, rowmax()) -----------------
drop variable*
timer on 3
quietly {
// loop over the order variables creating dummies
forvalues v=1/`numobs' {
tab order`v', gen(var`v'_)
}
// loop over the domain of the order variables
// (may need to change)
forvalues l=1/`numobs' {
egen variable`l' = rmax(var*_`l')
drop var*_`l'
}
}
timer off 3
*----------------- method 4 (original post) ----------------
drop variable*
timer on 4
quietly {
forvalues i = 1/`numobs' {
gen variable`i' = 0
forvalues j = 1/`numobs' {
replace variable`i' = 1 if order`i'==`j'
}
}
}
timer off 4
*-----------------------------------------------------------
timer list
定时程序给出
. timer list
1: 0.00 / 1 = 0.0010
2: 0.30 / 1 = 0.3000
3: 0.34 / 1 = 0.3390
4: 0.07 / 1 = 0.0700
其中,timer 1
是简单的gen
,timer 2
是重塑
,timer 3
是原始帖子的egen,rowmax()
,以及timer 4
您只需要一个循环的原因是Stata的方法是对数据库中的所有观察执行命令,从顶部(第一个观察)到底部(最后一个观察)。例如,variable1
是根据order1
是否缺失而生成的;这是针对两个变量的所有观察值进行的,没有显式循环
我想知道你是否真的需要这样做。对于未来的问题,如果你有进一步的目标,我认为一个好的策略是在你的帖子中提到它
注意:我重复使用了其他海报答案中的代码。使用简单的forvalues
循环,使用generate
和missing()。对于这个问题,您只需要一个循环就可以遍历完整的变量列表,而不是像原始帖子中那样需要两个。下面是一些显示这两个点的代码
*----------------- generate some data ----------------------
clear all
set more off
local numobs 60
set obs `numobs'
quietly {
forvalues i = 1/`numobs' {
generate order`i' = .
local k = (`numobs' - `i' + 1)
forvalues j = 1/`k' {
replace order`i' = (`k' - `j' + 1) if (_n == `j')
}
}
}
timer clear
*------------- method 1 (gen + missing()) ------------------
timer on 1
quietly {
forvalues i = 1/`numobs' {
generate variable`i' = !missing(order`i')
}
}
timer off 1
* ----------- method 2 (reshape + missing()) ---------------
drop variable*
timer on 2
quietly {
generate id = _n
reshape long order, i(id)
generate variable = !missing(order)
reshape wide order variable, i(id) j(_j)
}
timer off 2
*--------------- method 3 (egen, rowmax()) -----------------
drop variable*
timer on 3
quietly {
// loop over the order variables creating dummies
forvalues v=1/`numobs' {
tab order`v', gen(var`v'_)
}
// loop over the domain of the order variables
// (may need to change)
forvalues l=1/`numobs' {
egen variable`l' = rmax(var*_`l')
drop var*_`l'
}
}
timer off 3
*----------------- method 4 (original post) ----------------
drop variable*
timer on 4
quietly {
forvalues i = 1/`numobs' {
gen variable`i' = 0
forvalues j = 1/`numobs' {
replace variable`i' = 1 if order`i'==`j'
}
}
}
timer off 4
*-----------------------------------------------------------
timer list
定时程序给出
. timer list
1: 0.00 / 1 = 0.0010
2: 0.30 / 1 = 0.3000
3: 0.34 / 1 = 0.3390
4: 0.07 / 1 = 0.0700
其中,timer 1
是简单的gen
,timer 2
是重塑
,timer 3
是原始帖子的egen,rowmax()
,以及timer 4
您只需要一个循环的原因是Stata的方法是对数据库中的所有观察执行命令,从顶部(第一个观察)到底部(最后一个观察)。例如,variable1
是根据order1
是否缺失而生成的;这是针对两个变量的所有观察值进行的,没有显式循环
我想知道你是否真的需要这样做。对于未来的问题,如果你有进一步的目标,我认为一个好的策略是在你的帖子中提到它
注意:我重用了其他海报答案中的代码。这里有一个更简单的方法(仍然需要2个循环):
下面是一个更简单的方法(仍然需要2个循环):
是否只想标记(使用1)非缺失的观察值?我想用1或0标记所有观察值。所有缺失的顺序变量都得到0(我已经在此处未显示的代码中将变量的初始值设置为0)。感谢分享您的解决方案!我终于有机会仔细查看这些帖子,我把问题简化得太多了。我已经对我的原始帖子进行了编辑以澄清问题。我仍然无法准确理解您想要的内容。请向我们展示一个您的初始和最终数据集的代表性示例。您提到“计数”和“s