代码之家  ›  专栏  ›  技术社区  ›  Erdne Htábrob

stata中嵌套for循环

  •  0
  • Erdne Htábrob  · 技术社区  · 8 年前

    我很难理解为什么for循环构造不起作用。我真的不习惯for循环,所以如果我错过了一些基本的东西,我道歉。无论如何,我很感激你的任何建议。

    我使用的是来自 parlgov project . 我试图创建一个变量来捕捉一个政党在当前观察之前执政的次数。时间很重要,如果一方之前没有执政过,即使在观察期之后多次执政,计数器也应该为零。政党嵌套在国家和内阁日期中。

    代码如下:

    use "http://eborbath.github.io/stackoverflow/loop.dta", clear //to get the data
    

    如果这不起作用,我还以csv格式上传,请尝试:

    import delimited "http://eborbath.github.io/stackoverflow/loop.csv", bindquote(strict) encoding(UTF-8) clear
    

    循环应遍历每个国家具体的内阁日期,确定之前的观察结果,并检查该党是否已经执政。这就是我取得的成绩:

    gen date2=cab_date
    gen gov_counter=0    
    levelsof country, local(countries) // to get to the unique values in countries    
    foreach c of local countries{
        preserve // I think I need this to "re-map" the unique cabinet dates in each country
        keep if country==`c'
        levelsof cab_date, local(dates) // to get to the unique cabinet dates in individual countries
        restore        
        foreach i of local dates {
            egen min_date=min(date2) // this is to identify the previous cabinet date
            sort country party_id date2     
            bysort country party_id: replace gov_counter=gov_counter+1 if date2==min_date & cabinet_party[_n-1]==1 // this should be the counter
            bysort country: replace date2=. if date2==min_date // this is to drop the observation which was counted
            drop min_date //before I restart the nested loop, so that it again gets to the minimum value in `dates'
    }
    }
    

    代码可以正常工作,但无法完成任务。显然哪里出了错,我只是不知道在哪里。

    顺便说一句,这是我经常遇到的一个问题的一个具体应用:如何计算多级数据结构中不同值的频率?这稍微更具体一些,因为“时间很重要”,它不应该只是所有遭遇的总和。如果你有更简单的解决方案,请告诉我。

    谢谢

    2 回复  |  直到 8 年前
        1
  •  1
  •   the.ge    8 年前

    您的循环存在的问题是,它不会在循环后保留替换的gov_计数器。然而,我推荐一种更简单的解决方案:

     sort country party_id cab_date
     by country party_id: gen gov_counter=sum(cabinet_party[_n-1])
    

    这会将数据分组,然后按组创建一个总和,始终达到(但不包括)当前观察值。

        2
  •  1
  •   Nick Cox    8 年前

    我从这里开始。我已经删除了注释,以便我们可以查看代码。我做了一些小的修饰。

     foreach i of local dates {
            egen min_date = min(date2) 
            sort country party_id date2     
            bysort country party_id: replace gov_counter=gov_counter+1 ///
                 if date2 == min_date & cabinet_party[_n-1] == 1 
            bysort country: replace date2 = . if date2 == min_date 
            drop min_date 
     }
    

    此循环不包括对循环索引的引用 i 定义于 foreach 陈述因此,代码是相同的,完全不受循环索引的影响。变量 min_date 只是数据集的一个常数,在循环中每次都是相同的。取决于循环执行次数的是计数器递增的次数。

    这里的谬论似乎是与其他软件中的构造的错误类比,在其他软件中,循环自动为循环索引的不同值生成单独的计算。

    很容易看出,循环内容从不引用循环索引并不违法

    forval j = 1/3 {
       di "Hurray"
    }
    

    生产

    Hurray
    Hurray
    Hurray
    

    但是,如果要对循环索引的不同值进行不同的计算,则必须明确。