2017-10-28 143 views
2

我有一個包含多個子組(變量economist)和日期(變量temps99)的數據集。 我想運行一個不接受bysortby前綴的命令tabsplit多個本地foreach命令宏

所以我創建了一個宏來我的數據中我tabsplit命令適用於我的每一個分組,例如:

levelsof economist, local(liste) 
foreach gars of local liste { 
    display "`gars'" 
    tabsplit SubjectCategory if economist=="`gars'", p(;) sort 
    return list 
    replace nbcateco = r(r) if economist == "`gars'" 
} 

每個小組的Stata跑tabsplit命令,我使用變量nbcateco存儲計數結果。

我也做了同樣的日期,所以我可以有r(r)的隨時間的變化:

levelsof temps99, local(liste23) 
foreach time of local liste23 { 
    display "`time'" 
    tabsplit SubjectCategory if temps99 == "`time'", p(;) sort 
    return list 
    replace nbcattime = r(r) if temps99 == "`time'" 
} 

現在我想按日期temps99做每個分組economist。我嘗試了多種組合,但我對宏不太好(還沒有?)。

我想要的是能夠爲我的每個小組提供我的r(r)隨着時間的推移。

回答

1

這是一個XY問題的例子,我想。參見http://xyproblem.info/

tabsplit是來自SSC的包tab_chi中的命令。我對它沒有負面感受,就像我寫的那樣,但在這裏似乎很沒有必要。

您想計算字符串變量中的類別:分號是分隔符。因此,計算分號,並添加1

local SC SubjectCategory 
gen NCategory = 1 + length(`SC') - length(subinstr(`SC', ";", "", .)) 

然後(例如)tabletabstat會讓您的利益集團進一步探索。

要查看計數的想法,請考慮3分類與2分號。

. display length("frog;toad;newt") 
14 

. display length(subinstr("frog;toad;newt", ";", "", .)) 
12 

如果我們用空字符串替換每個分號,長度的改變是刪除的分號的數量。請注意,我們不必更改變量來執行此操作。然後加1.另請參閱this paper

這就是說,一個方法來擴展你的方法可能是

egen class = group(economist temps99), label 
su class, meanonly 
local nclass = r(N) 
gen result = . 

forval i = 1/`nclass' { 
    di "`: label (class) `i''" 
    tabsplit SubjectCategory if class == `i', p(;) sort 
    return list 
    replace result = r(r) if class == `i' 
} 

使用statsby甚至會更好。另請參閱this FAQ

+0

我也對tabsplit結果感興趣,這也是我使用它的部分原因。我嘗試使用像你所建議的變量NC類,但如果我沒有弄錯,這給了我多少類別的計數。我感興趣的是不同類別的計數(爲什麼SubjectCategory有用)。 你的最後一個建議正在工作,儘管我有一些可能只有很少觀察數據的子數據集給我提供了錯誤:'指定的變量太少'。問題是它會中斷宏。 謝謝你在包裝上的工作。 – Homard

+0

謝謝,但我不明白什麼是行不通的。您沒有顯示任何數據或您自己的代碼進行檢查。 –

2

下面是一個解決方案,顯示如何計算每個組中不同發佈類別的數量。這使用runby(來自SSC)。 runby在每個分組上循環,每次用來自當前分組的數據替換內存中的數據。對於每個分組,執行用戶程序中包含的命令。無論用戶程序終止時留在內存中的是什麼,都會被視爲結果並累積起來。一旦所有的組都被處理完畢,這些結果將取代內存中的數據。

我使用verbose選項,因爲我想使用漂亮的格式來顯示每個分組的結果。通過分割每個列表來完成不同類別列表的推導,轉換爲長佈局,並且每個不同的值減少到一個觀察值。 distinct_categories程序生成一個變量,其中包含分組的不同類別的最終計數。

* create a demontration dataset 
* ------------------------------------------------------------------------------ 
clear all 
set seed 12345 

* Example generated by -dataex-. To install: ssc install dataex 
clear 
input str19 economist 
"Carmen M. Reinhart" 
"Janet Currie"  
"Asli Demirguc-Kunt" 
"Esther Duflo"  
"Marianne Bertrand" 
"Claudia Goldin"  
"Bronwyn Hughes Hall" 
"Serena Ng"   
"Anne Case"   
"Valerie Ann Ramey" 
end 

expand 20 
bysort economist: gen temps99 = 1998 + _n 
gen pubs = runiformint(1,10) 
expand pubs 
sort economist temps99 
gen pubid = _n 
local nep NEP-AGR NEP-CBA NEP-COM NEP-DEV NEP-DGE NEP-ECM NEP-EEC NEP-ENE /// 
      NEP-ENV NEP-HIS NEP-INO NEP-INT NEP-LAB NEP-MAC NEP-MIC NEP-MON /// 
      NEP-PBE NEP-TRA NEP-URE 
gen SubjectCategory = "" 
forvalues i=1/19 { 
    replace SubjectCategory = SubjectCategory + " " + word("`nep'",`i') /// 
     if runiform() < .1 
} 
replace SubjectCategory = subinstr(trim(SubjectCategory)," ",";",.) 
leftalign // from SSC 
* ------------------------------------------------------------------------------ 


program distinct_categories 
    dis _n _n _dup(80) "-" 
    dis as txt "fille = " as res economist[1] as txt _col(68) " temps = " as res temps99[1] 

    // if there are no subjects for the group, exit now to avoid a no obs error 
    qui count if !mi(trim(SubjectCategory)) 
    if r(N) == 0 exit 

    // split categories, reshape to a long layout, and reduce to unique values 
    preserve 
    keep pubid SubjectCategory 
    quietly { 
    split SubjectCategory, parse(;) gen(cat) 
    reshape long cat, i(pubid) 
    bysort cat: keep if _n == 1 
    drop if mi(cat) 
    } 

    // show results and generate the wanted variable 
    list cat 
    local distinct = _N 
    dis _n as txt "distinct = " as res `distinct' 
    restore 
    gen wanted = `distinct' 
end 

runby distinct_categories, by(economist temps99) verbose