Stata:执行foreach循环以计算大数据文件中的kappa

时间:2015-10-12 17:14:15

标签: foreach stata

我在Stata中有一个包含50个变量的数据文件

   j-r-hp   j-p-hp  j-m-hp   p-c-hp  p-r-hp  p-p-hp   p-m-hp ... etc, 

我想在对之间执行加权kappa,因此第一个可能是

  kap j-r-hp j-p-hp, wgt(w2)

,接下来就是

  kap j-r-hp j-m-hp, wgt(w2)

我是Stata的新手。是否有一种直接使用循环的方法,如foreach循环?

4 个答案:

答案 0 :(得分:3)

您的变量名称在Stata中不是合法名称,因此我在下面的示例中将连字符更改为下划线。另外,我不知道执行加权kappa意味着什么,所以我的回答使用随机正常变量和corr[elate]命令。您可以使用Stata留下的结果r()(请参阅return list)来收集单独分析的结果。

我们的想法是使用local将变量收集到列表中,然后循环遍历该列表中的每个元素(但使用continue跳过重复的对)。如果您有许多带有结构化名称的变量,则可以改为使用dsr(varlist)留下r()。请查看宏的帮助文件(help macro和{ {1}}),尤其是用于解析'的宏扩展函数部分。希望这会有所帮助。

help extended_fcn

答案 1 :(得分:3)

您可以利用用户编写的命令tuples(运行ssc install tuples):

clear
set more off

*----- example data -----

set obs 100
local vars j_r_hp j_p_hp j_m_hp p_c_hp p_r_hp p_p_hp p_m_hp

foreach var of local vars   {
    gen `var' = abs(round(rnormal()*100))
}

*----- what you want -----

tuples `vars', min(2) max(2)
forvalues i = 1/`ntuples' {
    display _newline(3) "variables `tuple`i''"
    kappa `tuple`i''
}

如何将变量名称组合在一起以将它们输入tuples取决于数据集。

答案 2 :(得分:2)

这是@Matthijs对有用答案的一种变体,但它确实不太适合评论。主要的额外曲折是

  1. 使用tokenize来避免重复使用wordof。在tokenize之后,参数的单独单词(这里是单独的变量名称)保存在宏1中。因此tokenize a b ca置于本地宏1中,b置于本地宏2中,c置于局部宏3中。嵌套宏引用的处理方式与初等代数中的括号表达式完全相同;首先评估内部的内容。

  2. 直接关注对角线一侧的部分结果概念矩阵。小技巧是确保一个矩阵下标超过其他下标。

  3. 随机正常输入对kap没有意义,但您将以任何方式使用自己的数据。

    clear
    set obs 100
    local vars j_r_hp j_p_hp j_m_hp p_c_hp p_r_hp p_p_hp p_m_hp
    foreach var of local vars   {
        gen `var' = rnormal()
    }
    
    tokenize `vars'  
    local p : word count `vars'  
    local pm1 = `p' - 1
    
    forval i = 1/`pm1'   {
        local ip1 = `i' + 1 
        forval j = `ip1'/`p'   {
            di "``i'' and ``j''" 
            kap ``i'' ``j'' 
            di  
        }
    }
    

答案 3 :(得分:1)

我想我可以添加自己的答案,并强调一些事情。

首先要注意的是,对于新用户来说,最直接的"这样做的方法可能包括将所有变量硬编码到local中以在循环中使用(如其他答案所示),或者使用通配符引用它们并为每个组写入多个循环。请参阅下面的示例,了解如何使用通配符:

clear *
sysuse auto

/* Rename variables to match your .dta file and identify groups */
rename (price mpg rep78) (j_r_hp j_p_hp j_m_hp)
rename (headroom trunk weight) (p_c_hp p_r_hp p_m_hp)
rename (length turn displacement foreign) (z_r_hp z_m_hp z_p_hp z_c_hp)

/* Loop over all variables beginning with j and ending hp */
foreach x of varlist j*hp {
    foreach i of varlist j*hp {
        if "`x'" != "`i'" & "`i'" >= "`x'"{    // This section ensures you get only 
                                               // unique pairs of x & i
            kap `x' `i'
        }
    }
} 

/* Loop over all variables beginning with p and ending hp */
foreach x of varlist p*hp {
    * something involving x 
}
* etc. 

现在,根据您拥有的群组数量或您拥有的变量数量,这可能看起来并不简单。

这提出了我想提及的第二件事。在硬编码许多变量或许多重复命令变得麻烦的情况下,我倾向于支持程序化解决方案。这通常涉及预先编写更多代码,但在许多情况下往往至少是可以推广的,并且如果您有需要而无需全部编写,将允许您轻松评估数百个变量。

下面的代码使用describe的返回结果,以及一些foreach循环和一些扩展宏函数来对变量执行kappa命令,而不必将它们存储在手动local

clear *
sysuse auto

rename (price mpg rep78) (j_r_hp j_p_hp j_m_hp)
rename (headroom trunk weight) (p_c_hp p_r_hp p_m_hp)
rename (length turn displacement foreign) (z_r_hp z_m_hp z_p_hp z_c_hp)


/*
use gear_ratio as an arbitrary weight, order it first to easily extract
from the local containing varlist
*/
order gear_ratio, first 


qui describe, varlist
local Varlist `r(varlist)'            // store varlist in a local macro

preserve                              // preserve data so canges can be reverted back

foreach x of local Varlist {
    capture confirm numeric variable `x'
    if _rc {
        drop `x'                      // Keep only numeric variables to use in kappa 
    }
}

qui describe, varlist                 // replace the local macro varlist with now numeric only variables
local Varlist `r(varlist)'

local vars : list Varlist - weight    // remove weight from analysis varlist 

foreach x of local vars {
    foreach i of local vars  {
        if "`x'" != "`i'" & "`i'" >= "`x'"  {
            gettoken leftx : x, parse("_")
            gettoken lefti : i, parse("_")
            if "`leftx'" == "`lefti'" {
                kap `x' `i'
            }
        }
    }
}

restore

对于新用户来说,这里当然会有一个学习曲线,但我发现使用宏,循环和返回的结果非常有效地增加了我的程序和文件的灵活性 - 我强烈建议任何人使用Stata至少可以研究这三个主题的基础知识。