【问题标题】:Stata: ignore missing values when countingStata:计数时忽略缺失值
【发布时间】:2013-12-16 08:44:40
【问题描述】:

我想创建一个变量 (counter),它每年计算另一个变量 (firmage0) 的非缺失值。我的代码如下所示:

sort year  
quietly by year: gen counter = _n if firmage0 != . 

不幸的是,即使有缺失值,Stata 也会从 1 开始计数。但是我想在有非缺失值时开始计数。此外,第二个非缺失值应为“2”,第三个为“3”,依此类推。有一个重要的限制。不要使用preserve和restore!创建变量 counter 后,我的数据集如下所示(这只是其中的一小部分)。可用空间意味着缺失值!

year    firmage0    counter
1975        
1975        
1975        
1975        
1975    21  5
1975        
1975    60  7
1975        
1975        
1975        
1975        
1975        
1975        
1975        
1975        
1975        
1975        
1975        
1975        
1975    115 20
1975        
1975        
1975

但是数据集应该是这样的:

year    firmage0    counter
1975        
1975        
1975        
1975        
1975    21  1
1975        
1975    60  2
1975        
1975        
1975        
1975        
1975        
1975        
1975        
1975        
1975        
1975        
1975        
1975        
1975    115 3
1975        
1975        
1975    

【问题讨论】:

    标签: stata


    【解决方案1】:

    系统变量_n 是固定,它表示当前观察的数量,与if 条件无关。您对代码的要求是counter,它采用观察值的数值 if 它没有丢失。这与直到某个点的非缺失观察计数不同,这是您真正想要的。

    注意 缺失的数据类型。当你展示它时,firmage0 看起来像一个字符串变量,因为 字符串中缺少空格。数值的缺失是 表示为.(或.<something>)。见help missings。

    一种解决方案是以missings 为条件的累积sum。我假设变量类型是数字:

    clear all
    set more off
    
    input year firmage0
    1975      .  
    1975      . 
    1975      .      
    1975      .  
    1975    21
    1980    60 
    1980    .
    1980    89       
    1985      . 
    1985      .  
    1985    23    
    1985    45    
    1985    47
    1985     .   
    end 
    
    list, sepby(year)
    
    bysort year: gen counter = sum(!missing(firmage0))
    replace counter = . if missing(firmage0) // optional
    
    list, sepby(year)
    

    !missing(firmage0) 的计算结果为 false (0) 或 true (1),具体取决于 firmage0 的观察是否缺失。然后sum 进行累计。

    如果变量实际上是字符串类型,则将对应的行替换为:

    replace counter = "" if missing(firmage0) // optional
    

    单行(用于数字类型)是:

    bysort year: gen counter = cond(missing(firmage0), ., sum(!missing(firmage0)))
    

    但我更喜欢第一种方式,因为它更容易阅读。

    【讨论】:

    • 非常感谢!很好的答案。
    【解决方案2】:

    我相信如果你按照year和firmage0之前的排序:

    . sort year firmage0
    

    您的问题将得到解决。我更改了 firmage0 值之一的年份,只是为了确认它会重新开始计数。

    . by year : gen counter = _n if firmage0 !=.
    
    year    firmage0    counter               
    1975    21  1     
    1975    60  2   
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1975        
    1976    115 1
    

    【讨论】:

    • 考虑使用!missing(firmage0) 而不是firmage0 !=. 来泛化到字符串和数字类型。
    • 这是有风险的,因为如果没有额外的代码,您之前的 sort 订单将无法可靠地恢复。
    猜你喜欢
    • 1970-01-01
    • 2020-08-11
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 2016-02-28
    • 2017-06-20
    相关资源
    最近更新 更多