Stata 跨变量发生的更改数

Stata 跨变量发生的更改数,stata,Stata,我有像var2000,var2001,var2002这样的变量,这意味着每个变量分别是2000年,2001年,2002年 我想数一数他们从上一年到下一年的变化次数 所以我的目的是这样构造Num\u change: var2000 var2001 var2002 Num_change 3 2 1 2 4 4 4 0 1 0 0 1 1 0 1

我有像
var2000
var2001
var2002
这样的变量,这意味着每个变量分别是
2000年
2001年
2002年

我想数一数他们从上一年到下一年的变化次数

所以我的目的是这样构造
Num\u change

var2000 var2001 var2002 Num_change
   3      2       1        2
   4      4       4        0
   1      0       0        1
   1      0       1        2
我尝试了以下几点:

replace Num_change=2 if var2000~=var2001 & var2001~=var2002
然而,当有很多年的时间时,这种方法太单调乏味了


有什么简单的捷径可以做到这一点吗?

以下几点对我很有用:

clear

input var2000 var2001 var2002 
   3      2       1       
   4      4       4       
   1      0       0       
   1      0       1       
end

generate id = _n
reshape long var, i(id)

bysort id (_j): generate tag = var != var[_n-1]
reshape wide var tag, i(id)

egen Num_change = rowtotal(tag*)
replace Num_change = Num_change - 1
drop id tag*

list, abbreviate(10)

     +------------------------------------------+
     | var2000   var2001   var2002   Num_change |
     |------------------------------------------|
  1. |       3         2         1            2 |
  2. |       4         4         4            0 |
  3. |       1         0         0            1 |
  4. |       1         0         1            2 |
     +------------------------------------------+

以下是我的作品:

clear

input var2000 var2001 var2002 
   3      2       1       
   4      4       4       
   1      0       0       
   1      0       1       
end

generate id = _n
reshape long var, i(id)

bysort id (_j): generate tag = var != var[_n-1]
reshape wide var tag, i(id)

egen Num_change = rowtotal(tag*)
replace Num_change = Num_change - 1
drop id tag*

list, abbreviate(10)

     +------------------------------------------+
     | var2000   var2001   var2002   Num_change |
     |------------------------------------------|
  1. |       3         2         1            2 |
  2. |       4         4         4            0 |
  3. |       1         0         0            1 |
  4. |       1         0         1            2 |
     +------------------------------------------+

@Pearly Spencer合理地关注了你的问题,如何得到一个特定的变量。我会更进一步,建议您应该
重塑long
而不是
重塑
back。您的数据看起来像面板或纵向数据,最好是左
。你的问题是有特点的:即使是简单的问题,对于长数据,也常常需要使用大布局(结构、格式)的笨拙答案。也有例外,主要是有人编写了一个
egen
函数来按行执行某些操作。有关详细讨论,请参阅

我的回答的其余部分显示了两种方法,可以通过循环从现有布局中获取所需内容。对于您的真实数据,有许多变量,不必键入所有变量的名称:有其他方法可以这样做,但如何最好地这样做取决于您的真实名称,而您不会告诉我们

clear 
input var2000 var2001 var2002 Num_change
   3      2       1        2
   4      4       4        0
   1      0       0        1
   1      0       1        2
 end 

 * 1 
 local vars var2000 var2001 var2002 
 gettoken first vars : vars 
 gen wanted = 0 

 quietly while "`vars'" != "" { 
    gettoken next vars : vars
    replace wanted = wanted + (`next' != `first') 
    local first `next' 
} 

* 2 
local vars var2000 var2001 var2002 
gen WANTED = 0 
tokenize `vars' 
local nvars : word count `vars' 

quietly forval j = 2/`nvars' { 
    local i = `j' - 1 
    replace WANTED = WANTED + (``j'' !=  ``i'') 
}

list 

     +----------------------------------------------------------+
     | var2000   var2001   var2002   Num_ch~e   wanted   WANTED |
     |----------------------------------------------------------|
  1. |       3         2         1          2        2        2 |
  2. |       4         4         4          0        0        0 |
  3. |       1         0         0          1        1        1 |
  4. |       1         0         1          2        2        2 |
     +----------------------------------------------------------+

@Pearly Spencer合理地关注了你的问题,如何得到一个特定的变量。我会更进一步,建议您应该
重塑long
而不是
重塑
back。您的数据看起来像面板或纵向数据,最好是左
。你的问题是有特点的:即使是简单的问题,对于长数据,也常常需要使用大布局(结构、格式)的笨拙答案。也有例外,主要是有人编写了一个
egen
函数来按行执行某些操作。有关详细讨论,请参阅

我的回答的其余部分显示了两种方法,可以通过循环从现有布局中获取所需内容。对于您的真实数据,有许多变量,不必键入所有变量的名称:有其他方法可以这样做,但如何最好地这样做取决于您的真实名称,而您不会告诉我们

clear 
input var2000 var2001 var2002 Num_change
   3      2       1        2
   4      4       4        0
   1      0       0        1
   1      0       1        2
 end 

 * 1 
 local vars var2000 var2001 var2002 
 gettoken first vars : vars 
 gen wanted = 0 

 quietly while "`vars'" != "" { 
    gettoken next vars : vars
    replace wanted = wanted + (`next' != `first') 
    local first `next' 
} 

* 2 
local vars var2000 var2001 var2002 
gen WANTED = 0 
tokenize `vars' 
local nvars : word count `vars' 

quietly forval j = 2/`nvars' { 
    local i = `j' - 1 
    replace WANTED = WANTED + (``j'' !=  ``i'') 
}

list 

     +----------------------------------------------------------+
     | var2000   var2001   var2002   Num_ch~e   wanted   WANTED |
     |----------------------------------------------------------|
  1. |       3         2         1          2        2        2 |
  2. |       4         4         4          0        0        0 |
  3. |       1         0         0          1        1        1 |
  4. |       1         0         1          2        2        2 |
     +----------------------------------------------------------+

请注意,您也可以对循环执行相同的操作。谢谢。但是,当数据量巨大时,
重塑
按排序
似乎需要花费大量时间。但我不是专家。你认为它和我写的粗糙的方式一样快吗?这要看情况了。我是根据你的玩具例子回答的。对于庞大的数据集,循环也会很慢。顺便说一句,你的方法不会计算任何东西,因此根据定义是不可比较的。请注意,你也可以对循环做同样的事情。谢谢。但是,当数据量巨大时,
重塑
按排序
似乎需要花费大量时间。但我不是专家。你认为它和我写的粗糙的方式一样快吗?这要看情况了。我是根据你的玩具例子回答的。对于庞大的数据集,循环也会很慢。顺便说一句,您的方法不会计算任何东西,因此根据定义是不可比较的。正如@PearlySpiner所暗示的,如果不显示如何获得新变量的0和1值,您的代码是不完整的。我很容易猜测,但关键是代码示例应该是完整的。正如@PearlySpencer所暗示的,如果不显示如何获得新变量的0和1值,那么代码就不完整。我很容易猜测,但关键是代码示例应该是完整的。我同意长格式,这就是我选择
重塑
的原因。我同意长格式,这就是我选择
重塑
的原因。