作者:吳雄 (湘潭大學)

Stata 連享會: 知乎 | 簡書 | 碼雲

  • Stata連享會 精品專題 || 精彩推文

之前,我在處理數據的時候,經常碰到一些非平衡面板數據,當時處理完後才發現連玉君老師之前已經編寫了一個 xtbalance 的命令,該命令專門用於將連續時間非平衡面板處理成平衡面板。但是,該命令在處理非連續時間的非平衡面板有點缺陷,所以平時我還是自己寫命令來處理非平衡面板數據的問題,這兩天我發現有同學還有一些別的交流群里的群友在用的時候就碰到這個問題,今天,我就打算細講如何將非平衡面板轉換成平衡面板。

  • 目錄
  • 1.xtbalance 命令的使用
  • 2.xtbalance 的流程
    • 2.1 生成連續時間的非平衡面板
    • 2.2 不用xtbalance命令的處理成平衡面板的方法
    • 2.3 xtbalance的使用
  • 3.非連續時間的非平衡面板的處理
    • 3.1 生成數據
    • 3.2 處理成平衡面板
    • 3.3 使用 xtbalance
  • 4.非平衡面板非連續時間也沒有固定間隔

1.xtbalance 命令的使用

首先,這個命令是 Stata 外部命令,需要先下載安裝才能使用。下載安裝的命令為: ssc install xtbalance。完成後,輸入 help xtbalance 查看幫助文檔,以了解該命令的使用方法。

xtbalance 的語法格式: xtbalance, range(numlist) [ miss(varlist) ]

  • 請注意,在使用該命令之前你需要設置你的面板數據,你可以通過 xtset panelvar timevartsset panelvar timevar 將數據設定成面板數據格式。

接下來,你可以根據所需時間段來處理數據,比如我需要 1992-1998 年的平行面板,命令為 xtbalance, range(1992 1998)

  • 局限:當你的 timevar 不是 1991、1992、……2000 這樣的連續時間,而是類似 1992、1994、1996 …… 2000 這種非連續時間的時,直接使用 xtbalance, range(1992 1998) 會導致所有觀察值都被刪除了。結果將會刪除你的整個樣本,這是怎麼回事呢?
  • 當我對我的非連續時間的平衡面板 1992(2)2000 ,進行上述命令的時候,出來的結果如下:

//數據生成
. set obs 100
. gen id = int(_n/5.001)+1
. bysort id:gen year = 1992 +2*(_n-1)
. xtset id year

panel variable: id (strongly balanced)
time variable: year, 1992 to 2000, but with gaps
delta: 1 unit

//取1992-1998年段的平衡面板
. xtbalance, range(1992 1998)

(20 observations deleted due to out of range)
(80 observations deleted due to discontinues)

  • 即,該命令首先將不在你選定的時間段內的樣本刪掉,之後,它在清理每個 id 的時候,將組內非連續時間的 id 刪掉,但為什麼我的平衡面板會被全部刪除呢?因為我的不是連續時間。那麼連續是怎麼計算的呢?我的猜測是這個命令按照連續時間來計算每個 id 的樣本數量,將其樣本數量與預計間隔相比較,即它在清理每個 id 的時候,將組內沒有 1998 - 1992 + 1 數量的id刪掉,但是我們的時間間隔不一樣,每個組內的樣本數是不一樣的,我的每個 id 應該只有 ( 1998 - 1992 ) / 2 +1個,它按照連續時間來計算的話會比我多,所以它認為我的組內缺失了樣本,不是平衡的,所以會將這些也刪掉。結果,數據就全被刪了。

2.xtbalance 的流程

我們這裡就不貼xtbalance命令的源代碼,但是我通過自己編寫的一個do文件來展示我猜測的具體操作流程。

2.1 生成連續時間的非平衡面板

我們首先生成一個 id 為 0 (1) 99,year 為 1991 (1) 2000 的平衡面板:

. clear
. set obs 1000
. gen id =int(_n/10.000001)
. bysort id :gen year = 1990 + _n
. xtset id year

panel variable: id (strongly balanced)
time variable: year, 1991 to 2000
delta: 1 unit

然後,我們生成均勻分布的隨機數,將隨機數小於 0.2 的樣本刪掉,即每條都有 20% 的概率被刪掉,剩下的樣本為非平衡的樣本

. drop if runiform() <0.2
. xtset id year

panel variable: id (unbalanced)
time variable: year, 1991 to 2000, but with gaps
delta: 1 unit

同時,通過tab id我們可以看每個id的樣本數(受限於編輯器,這裡只列出幾行)都不一樣

. tab id

id | Freq. Percent Cum.
------------+-----------------------------------
0 | 6 0.73 0.73
1 | 9 1.10 1.83
2 | 8 0.98 2.81
3 | 9 1.10 3.91
4 | 7 0.86 4.77
5 | 9 1.10 5.87

  • 注意:這時候,如果在1991(1)2000時間段上是平衡面板的話,每個id應該有2000-1991+1=10條記錄

2.2 不用 xtbalance 命令的處理成平衡面板的方法

實際上,xtbalance 命令的實現是這樣的:

刪除不在時間段內的樣本;
計算每個id的樣本數,如果每個 id 組內缺少樣本,則將這個 id 的樣本都刪除。

假如,我們需要將上述數據 id : 0 (1) 99 year: 1991 (1) 2000的非平衡面板轉為 id :0 (1) 99 year: 1992 (1) 1998的平衡面板的話,我們需要知道當轉為平衡面板後,每個id相對應的只有1998-1992+1=7條記錄

. preserve
. drop if year > 1998 | year < 1992
(243 observations deleted)

. bysort id :keep if _N ==7
(400 observations deleted)

. xtset id year
panel variable: id (strongly balanced)
time variable: year, 1992 to 1998
delta: 1 unit
. restore

2.3 xtbalance 的使用

. xtbalance, range(1992 1998)

(243 observations deleted due to out of range)
(400 observations deleted due to discontinues)

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

Stata連享會 「現場班專題課程-爬蟲-文本分析-空間計量」

3.非連續時間的非平衡面板的處理

  • 本節將介紹有固定間隔時間的非平衡面板的處理

實際過程中,有許多資料庫並不是連續時間的面板,這可能是因為多種原因,比如,某個資料庫在調查數據時候,分別在 1990、1992、1994 每兩年調查一次的,其實,這種滿好的,因為有固定間隔,然而,當不是固定間隔的時候,處理數據的時候你可能需要多留意。

3.1 生成數據

先生成平衡面板(不是連續時間)

  • obs : 1000
  • id :1 (1) 99
  • year:1991 (2) 2009

*-生成非連續時間的平衡面板
. clear
. set obs 1000
. gen id =int(_n/10.000001)
. bysort id :gen year = 1990 + 2*_n -1
. xtset id year
panel variable: id (strongly balanced)
time variable: year, 1991 to 2009, but with gaps
delta: 1 unit

. xtset id year, delta(2)
panel variable: id (strongly balanced)
time variable: year, 1991 to 2009
delta: 2 units

. tab year

year | Freq. Percent Cum.
------------+-----------------------------------
1991 | 100 10.00 10.00
1993 | 100 10.00 20.00
1995 | 100 10.00 30.00
1997 | 100 10.00 40.00
1999 | 100 10.00 50.00
2001 | 100 10.00 60.00
2003 | 100 10.00 70.00
2005 | 100 10.00 80.00
2007 | 100 10.00 90.00
2009 | 100 10.00 100.00
------------+-----------------------------------
Total | 1,000 100.00

*-直接使用xtbalance的缺陷/
. preserve

. count
1,000

. xtbalance, range(1993 2005)

(300 observations deleted due to out of range)
(700 observations deleted due to discontinues)

. count
0

. restore

  • 注意:
  1. xtset id yeartsset id year 都可以同時設置面板
  2. 因為是非連續時間的平衡面板 ,所以 xtset id year 命令會提示說你的數據 「strongly balanced" 但是時間有 "gap",如果你的面板 time variable 是有固定間隔的,那麼你可以在 xtset id year, delta()delta() 選項中設置。
  3. 通過上述 xtbalance 命令,我們可以看到,我們的非連續時間的平衡面板直接使用用xtbalance 是不合適的。

再通過隨機刪除部分樣本,使其成為非平衡面板:

. drop if runiform() <0.2
(168 observations deleted)

. xtset id year,delta(2)
panel variable: id (unbalanced)
time variable: year, 1991 to 2009, but with gaps
delta: 2 units

3.2 處理成平衡面板

我們所需要的樣本時間段為 1993(2)2005:

先查看一下數據:

. tab year

year | Freq. Percent Cum.
------------+-----------------------------------
1991 | 78 9.38 9.38
1993 | 84 10.10 19.47
1995 | 80 9.62 29.09
1997 | 82 9.86 38.94
1999 | 82 9.86 48.80
2001 | 88 10.58 59.38
2003 | 79 9.50 68.87
2005 | 86 10.34 79.21
2007 | 87 10.46 89.66
2009 | 86 10.34 100.00
------------+-----------------------------------
Total | 832 100.00

我們所需要的是 1993(2)2005 的時間段的話,每個 id 在 1993(2)2005時間段內的樣本數應該是1+(2005-1993)/2 = 7,所以,我們的操作流程就是:

1.先只保留1993-2005年的所有樣本,不在時間段內的刪除掉;2.計算每個id的樣本數,只包括樣本數為7的。

. preserve

. drop if year>2005 | year <1993
(251 observations deleted)

. bysort id :drop if _N != 7
(413 observations deleted)

. xtset id year,delta(2)
panel variable: id (strongly balanced)
time variable: year, 1993 to 2005
delta: 2 units

. restore

3.3 使用 xtbalance 的新姿勢

對於有固定間隔的平衡面板數據,我們可以預先生成一個新的時間變數 (連續的),進而使用 xtbalance 命令進行處理。

. xtset id year, delta(2)
panel variable: id (unbalanced)
time variable: year, 1991 to 2009, but with gaps
delta: 2 units

. bysort id: gen new_year = _n //使用該命令前一點要先對數據排序
* 或 gen new_year = 1 + (year - r(min))/2

現在 1993 年在 new_year 中就是 2,而 2005 年就是 8 ,然後用新的時間來設置面板,再使用xtbalance,range(2 8) 就OK了

. xtset id new_year
panel variable: id (unbalanced)
time variable: new_year, 1 to 10, but with gaps
delta: 1 unit

. xtbalance,range(2 8)

(251 observations deleted due to out of range)
(413 observations deleted due to discontinues)

. xtset id year,delta(2)
panel variable: id (strongly balanced)
time variable: year, 1993 to 2005
delta: 2 units

4.非平衡面板非連續時間也沒有固定間隔

股票日交易資料有一個典型的特徵:所有公司的資料在非交易日都是缺失的。因此,雖然股票日交易資料本質上是一份連續數據,但 Stata 在接到 xtset id date 的通知後,將其視為非平衡面板數據。(Note: 這裡暫不考慮那些在交易日里停牌的公司)

此時的處理方法與上一小節相似:可以先使用 bysort id: gen new_data=_n 命令或 egen new_date = group(date) 命令生成新的時間變數。

對於更為一般的情形,處理方法也會相對複雜:先刪掉不在時間段內的樣本,然後通過某種方法將你的時間變數轉為一個新的具有連續時間的變數,之後通過每個 id 的樣本數與為平衡時的樣本數進行比較,一樣則保留,否則刪除。

5. 後記 (連玉君)

在寫作這篇推文過程中,我與吳雄多次溝通,受到了不少啟發。

後續我們會將文中提及的 xtbalance 的局限一一解決掉,以便大家能夠更為便捷地進行非平行面板 → 平行面板的轉換。

計劃添加的功能如下(歡迎各位補充,反饋至:[email protected] ):

  • 添加 delta() 選項:以便處理有固定間隔的平衡面板數據
  • 添加 gen(newvarname) 選項:以便對平行面板構成的觀察值進行標記;
  • 添加 force 選項:由程序自動對用戶的數據進行處理;
  • ……

關於我們

  • Stata 連享會(公眾號:StataChina)】由中山大學連玉君老師團隊創辦,旨在定期與大家分享 Stata 應用的各種經驗和技巧。
  • 公眾號推文同步發佈於 CSDN-Stata連享會 、簡書-Stata連享會 和 知乎-連玉君Stata專欄。可以在上述網站中搜索關鍵詞StataStata連享會後關注我們。
  • 點擊推文底部【閱讀原文】可以查看推文中的鏈接並下載相關資料。
  • Stata連享會 精彩推文1 || 精彩推文2

聯繫我們

  • 歡迎賜稿: 歡迎將您的文章或筆記投稿至Stata連享會(公眾號: StataChina),我們會保留您的署名;錄用稿件達五篇以上,即可免費獲得 Stata 現場培訓 (初級或高級選其一) 資格。
  • 意見和資料: 歡迎您的寶貴意見,您也可以來信索取推文中提及的程序和數據。
  • 招募英才: 歡迎加入我們的團隊,一起學習 Stata。合作編輯或撰寫稿件五篇以上,即可免費獲得 Stata 現場培訓 (初級或高級選其一) 資格。
  • 聯繫郵件: [email protected]

往期精彩推文

  • Stata連享會推文列表1
  • Stata連享會推文列表2
  • Stata連享會 精品專題 || 精彩推文


推薦閱讀:
相关文章