Loops 元素数量不断增加的嵌套循环

Loops 元素数量不断增加的嵌套循环,loops,foreach,stata,Loops,Foreach,Stata,我有一个18个时间段的纵向数据集。出于不在此讨论的原因,此数据集的形状为宽,而不是长型。更准确地说,时变变量有一个字母前缀,用来标识它所属的时间。为了这个问题,考虑一个被称为“代码>支付的兴趣。此变量在第一个周期中表示为apay,在第二个周期中表示为bpay,依此类推,直到rpay 重要的是,不同的观测值在不同时期以不可预测的方式丢失了该变量的值。因此,在整个周期内运行一个小组将大大减少我的观察次数。因此,我想知道一个不同长度的小组将有多少次观察。为了评估这一点,我想创建变量,对于每个时段和每个

我有一个18个时间段的纵向数据集。出于不在此讨论的原因,此数据集的形状为,而不是型。更准确地说,时变变量有一个字母前缀,用来标识它所属的时间。为了这个问题,考虑一个被称为“代码>支付<代码>的兴趣。此变量在第一个周期中表示为
apay
,在第二个周期中表示为
bpay
,依此类推,直到
rpay

重要的是,不同的观测值在不同时期以不可预测的方式丢失了该变量的值。因此,在整个周期内运行一个小组将大大减少我的观察次数。因此,我想知道一个不同长度的小组将有多少次观察。为了评估这一点,我想创建变量,对于每个时段和每个连续时段的数量统计有多少受访者拥有该时间序列的变量。例如,我希望变量
b_count_2
计算在第一个周期和第二个周期中有多少个观察值没有减少
pay
。这可以通过以下方式实现:

local b_count_2 = 0
if apay != . & bpay != . {
        local b_count_2 = `b_count_2' + 1 // update for those with nonmissing pay in both periods
    }
local list a b c d e f g h i j k l m n o p q r                  // periods over which iterate
foreach var of local list {                         // loop over periods
    local list `var'_counter_*                      // group of sequence variables for each period
    foreach var2 of local list {                        // loop over each element of the list
        quietly sum `var'_counter_`var2' if `var'_counter_`var2' == 1   // sum the number of individuals with value = 1 with sequence of length var2 in period var
        di as text "Wave `var' has a sequence of length `var2' with " as result r(N) as text " observations." // print result
    }
}
现在,因为我想自动完成这项工作,这必须是一个循环。此外,每个周期都有不同数量的序列。例如,对于第三个期间,有两个序列(在第2和第3个期间有薪酬的序列,以及在第1、2和第3个期间有序列的序列)。因此,要创建的变量数为1+2+3+4+…+17=153。这种可变性必须反映在循环中。我在下面提出了一个代码,但是有一些地方是错误的,或者我不确定,正如在评论中强调的那样

local list b c d e f g h i j k l m n o p q r               // periods over which iterate
foreach var of local list {                 // loop over periods
    local counter = 1                   // counter to update; reflects sequence length 
    while `counter' > 0 {                   // loop over sequence lengths
        gen _`var'_counter_`counter' = 0        // generate variable with counter
        if `var'pay != . {              // HERE IS PROBLEM 1. NEED TO MAKE THIS TO CHECK CONDITIONS WITH INCREASING NUMBER OF ELEMENTS 
            recode _`var'_counter_`counter' (0 = 1) // IM NOT SURE THIS IS HOW TO UPDATE SPECIFIC OBSERVATIONS.
            local counter = `counter' - 1       // update counter to look for a longer sequence in the next iteration
        }
    }
    local counter = `counter' + 1               // HERE IS PROBLEM 2. NEED TO STOP THIS LOOP! Otherwise counter goes to infinity.
}
上述代码(如果正确)的结果示例如下。考虑四个周期(表示A、B、C和D)的五个观测数据集:

式中,1表示在该期间观察到的数值,以及。事实并非如此。代码的目标是创建1+2+3=6个新变量,以便新数据集为:

Obs   a  b  c  d  b_count_2  c_count_2  c_count_3  d_count_2  d_count_3  d_count_4
1     1  1  .  1      1          0          0          0          0          0
2     1  1  .  .      1          0          0          0          0          0
3     .  .  1  1      0          0          0          1          0          0
4     .  1  1  .      0          1          0          0          0          0
5     1  1  1  1      1          1          1          1          1          1
现在,为什么这有帮助?因为现在我可以运行一组
summary
命令来获得数据集的非常好的描述。一次性打印此信息的代码如下所示:

local b_count_2 = 0
if apay != . & bpay != . {
        local b_count_2 = `b_count_2' + 1 // update for those with nonmissing pay in both periods
    }
local list a b c d e f g h i j k l m n o p q r                  // periods over which iterate
foreach var of local list {                         // loop over periods
    local list `var'_counter_*                      // group of sequence variables for each period
    foreach var2 of local list {                        // loop over each element of the list
        quietly sum `var'_counter_`var2' if `var'_counter_`var2' == 1   // sum the number of individuals with value = 1 with sequence of length var2 in period var
        di as text "Wave `var' has a sequence of length `var2' with " as result r(N) as text " observations." // print result
    }
}
对于上述示例,这将生成以下输出:

"Wave 'b' has a sequence of length 2 with 3 observations."
"Wave 'c' has a sequence of length 2 with 2 observations."
"Wave 'c' has a sequence of length 3 with 1 observations."
"Wave 'd' has a sequence of length 2 with 2 observations."
"Wave 'd' has a sequence of length 3 with 1 observations."
"Wave 'd' has a sequence of length 4 with 1 observations."

这给了我一个关于宽面板和长面板之间权衡的很好的总结

我对@Dimitry V.Masterov表示真正的困惑,你正在使用这个数据集形状。出于某些目的,它可能很方便,但对于面板或纵向数据(如您所拥有的),在Stata中使用它充其量是尴尬的,充其量是不切实际的

首先,请特别注意

local b_count_2 = 0
if apay != . & bpay != . {
        local b_count_2 = `b_count_2' + 1 // update for those with nonmissing pay in both periods
}
将仅根据第一次观察进行评估,即,就像您已编码一样

if apay[1] != . & bpay[1] != . 
这是有案可查的。即使这是你想要的,通常也不是其他人可以遵循的模式

第二,更一般地说,我没有试图理解代码的所有细节,因为我看到的是创建大量变量,即使是在草图中的小数据集。对于一系列的T周期,您将创建一个三角形数字[(T-1)T]/2的新变量;在你的例子中(17 x 18)/2=153。如果有人有100个周期,他们需要4950个新变量

请注意,由于刚才提到的第一点,这些新变量只适用于个别变量,如
pay
个别面板。据推测,对单个面板的限制可能是固定的,但其主要思想在许多方面似乎都是不明智的。简而言之,除了编写更多的嵌套循环外,您还需要采用什么策略来处理这些成百上千的新变量

您的主要需求似乎是识别非缺失值和缺失值的咒语。长期以来,已经有了一种简单的机械。讨论了一般原则,可从SSC下载实现,如
TSSpill

在Statalist上,人们被要求提供数据和代码的可行示例。看,这完全等同于长期存在的请求


尽管有这些建议,我还是先看看Stata命令
xtdescriple
和您已经可以使用的相关
xt
工具。这些工具确实需要一个长的数据形状,
重塑
将为您提供

让我根据现在添加到问题中的示例添加另一个答案

Obs   a  b  c  d
1     1  1  .  1
2     1  1  .  .
3     .  .  1  1
4     .  1  1  .
5     1  1  1  1
这个答案的目的不是提供OP要求的内容,而是指出有多少简单的工具可用于查看非缺失值和缺失值的模式,所有这些都不需要为每个新问题创建大量额外变量或基于嵌套循环编写复杂的代码。这些工具中的大多数都需要一个
长形整形

. clear  

. input a b c d

             a          b          c          d
  1.  1 1 . 1
  2.  1 1 . .
  3.  . . 1 1
  4.  . 1 1 .
  5.  1 1 1 1
  6. end 

. rename (a b c d) (y1 y2 y3 y4) 

. gen id = _n 

. reshape long y, i(id) j(time) 
(note: j = 1 2 3 4)

Data                               wide   ->   long
-----------------------------------------------------------------------------
Number of obs.                        5   ->      20
Number of variables                   5   ->       3
j variable (4 values)                     ->   time
xij variables:
                           y1 y2 ... y4   ->   y
-----------------------------------------------------------------------------

. xtset id time 
       panel variable:  id (strongly balanced)
        time variable:  time, 1 to 4
                delta:  1 unit

. preserve 

. drop if missing(y) 
(7 observations deleted)

. xtdescribe 

      id:  1, 2, ..., 5                                      n =          5
    time:  1, 2, ..., 4                                      T =          4
           Delta(time) = 1 unit
           Span(time)  = 4 periods
           (id*time uniquely identifies each observation)

Distribution of T_i:   min      5%     25%       50%       75%     95%     max
                         2       2       2         2         3       4       4

     Freq.  Percent    Cum. |  Pattern
 ---------------------------+---------
        1     20.00   20.00 |  ..11
        1     20.00   40.00 |  .11.
        1     20.00   60.00 |  11..
        1     20.00   80.00 |  11.1
        1     20.00  100.00 |  1111
 ---------------------------+---------
        5    100.00         |  XXXX

* ssc inst xtpatternvar 
. xtpatternvar, gen(pattern) 

* ssc inst groups 
. groups pattern

  +------------------------------------+
  | pattern   Freq.   Percent     % <= |
  |------------------------------------|
  |    ..11       2     15.38    15.38 |
  |    .11.       2     15.38    30.77 |
  |    11..       2     15.38    46.15 |
  |    11.1       3     23.08    69.23 |
  |    1111       4     30.77   100.00 |
  +------------------------------------+

. restore  

. egen npresent = total(missing(y)), by(time)

. tabdisp time, c(npresent) 

----------------------
     time |   npresent
----------+-----------
        1 |          2
        2 |          1
        3 |          2
        4 |          2
----------------------
。清楚的
. 输入a b c d
a、b、c、d
1.1 1 . 1.
2.1 1 . .
3.1 1
4.1 1 .
5.1 1 1 1
6.结束
. 更名(AB c d)(y1 y2 y3 y4)
. 发电机id=\u n
. 重塑长y,i(id)j(时间)
(注:j=1 2 3 4)
数据范围->长
-----------------------------------------------------------------------------
OB的数量。5   ->      20
变量数5->3
j变量(4个值)->时间
xij变量:
Y1Y2。。。y4->y
-----------------------------------------------------------------------------
. 设置id时间
面板变量:id(强平衡)
时间变量:时间,1到4
增量:1个单位
. 保存
. 如果缺失,则下降(y)
(删除7项意见)
. 描述
id:1,2,…,5
* create some fake data in wide form
clear
set seed 12341
set obs 10
foreach pre in a b c d e f g {
    gen `pre'pay = runiform() if runiform() < .8
}

* reshape to long form
gen id = _n
reshape long @pay, i(id) j(wave) string

* identify spells of contiguous periods
egen wavegroup = group(wave), label 
tsset id wavegroup  
tsspell, cond(pay < .)
drop if mi(pay)

foreach pre in b c d e f g {
    dis "{hline 80}" _n as res "Wave `pre'"

    sum _seq if wave == "`pre'", meanonly
    local n = r(max)
    forvalues i = 2/`n' {
        qui count if _seq >= `i' & wave == "`pre'"
        dis as txt "length = " as res `i' as txt " obs = " as res r(N)
    }

}