2017-10-28 148 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