【问题标题】:Invalid syntax loop in StataStata中的无效语法循环
【发布时间】:2021-06-14 20:31:52
【问题描述】:

我正在尝试运行 for 循环以在 Stata 中制作余额表(将我的数据集的人口统计数据与国家级统计数据进行比较)

为此,我正在准备我的数据集并尝试计算一些关键人口统计数据的百分比/平均值。

preserve
    rename unearnedinc_wins95 unearninc_wins95
    foreach var of varlist fem age nonwhite hhsize parent employed savings_wins95 debt_wins95 earnedinc_wins95 unearninc_wins95 underfpl2019 { //continuous or binary; to put categorical vars use kwallis test
            dis "for variable `var':"
            tabstat `var' 
            summ `var' 
            local `var'_samplemean=r(mean)
        }    
    clear
    set obs 11
    gen var=""
    gen sample=.
    gen F=.
    gen pvalue=.
    replace var="% Female" if _n==1 
    replace var="Age" if _n==2
    replace var="% Non-white" if _n==3
    replace var="HH size" if _n==4
    replace var="% Parent" if _n==5
    replace var="% Employed" if _n==6
    replace var="Savings stock ($)" if _n==7
    replace var="Debt stock ($)" if _n==8
    replace var="Earned income last mo. ($)" if _n==9
    replace var="Unearned income last mo. ($)" if _n==10
    replace var="% Under FPL 2019" if _n==11
    foreach col of varlist sample {
        replace `col'=100*round(`fem_`col'mean', 0.01) if _n==1
        replace `col'=round(`age_`col'mean') if _n==2
        replace `col'=100*round(`nonwhite_`col'mean', 0.01) if _n==3
        replace `col'=round(`hhsize_`col'mean', 0.1) if _n==4
        replace `col'=100*round(`parent_`col'mean', 0.01) if _n==5
        replace `col'=100*round(`employed_`col'mean', 0.01) if _n==6
        replace `col'=round(`savings_wins95_`col'mean') if _n==7
        replace `col'=round(`debt_wins95_`col'mean') if _n==8
        replace `col'=round(`earnedinc_wins95_`col'mean') if _n==9
        replace `col'=round(`unearninc_wins95_`col'mean') if _n==10
        replace `col'=100*round(`underfpl2019_`col'mean', 0.01) if _n==11
    }

我正在尝试运行以下循环,但在循环的后半部分,我不断收到“无效语法”错误。对于上下文,在循环的前半部分(清除数据集之前),代码将变量的平均值存储为宏(`var'_samplemean)。有人可以帮我解决这个循环吗?

我的样本数据:

clear
input byte fem float(age nonwhite) byte(hhsize parent) float employed double(savings_wins95 debt_wins95 earnedinc_wins95 unearninc_wins95) float underfpl2019
1 35 1 6 1 1   0  2500    0 0 0
0 40 0 4 1 1   0 10000 1043 0 0
0 40 0 4 1 1   0 20000 2400 0 0
0 40 0 4 1 1 .24 20000 2000 0 0
0 40 0 4 1 1  10     . 2600 0 0

谢谢!

【问题讨论】:

  • 如果没有可重现的例子,很难说。您可以使用dataex 创建一些我们可以重现错误的示例数据吗? (请参阅此页面上的dataexstackoverflow.com/tags/stata/info)。或者您可以运行set trace on 并再次运行您的代码并编辑您的问题以包含您在错误之前获得的几行输出吗?
  • 嗨,编辑了问题以包含数据!
  • 如果您先运行input 部分,然后运行示例中的其余代码,则没有错误(只要您注释掉rename unearnedinc_wins95 unearninc_wins95)。它可能不是您期望的输出,但没有错误。请确保您提供的代码在独立运行时确实会产生错误
  • 限定符if _n==1if _n==2等可以替换成in 1in 2等,这样更快也更容易打字。
  • 如果@C.Robin 能满意地回答您的问题,请接受。

标签: for-loop stata stata-macros


【解决方案1】:

感谢分享sn-p数据。除了变量unearninc_wins95 已在您的示例数据中重命名之外,代码对我来说运行良好,没有返回错误。

话虽如此,一旦代码底部的循环完成,您的 F 统计量和 p 值的列就是空的。据我所见,没有名为sample 的本地/变量列表,您尝试使用foreach col of varlist sample{ 行调用它。这可能是因为您没有将它包含在您的代码中,在这种情况下请这样做,或者可能是因为您没有创建本地/varlist sample,在这种情况下这很可能是您的错误的来源消息。

退后一步,有更有效的方法可以实现我认为您所追求的目标。例如,您可以使用包stat2data 获得(部分)您想要的东西(如果您还没有安装它,请从命令提示符运行ssc install stat2data)。然后您可以运行以下代码:

stat2data fem age nonwhite hhsize parent employed savings_wins95 debt_wins95 earnedinc_wins95 unearninc_wins95 underfpl2019,  saving("~/yourstats.dta") stat(count mean)

*which returns:

preserve
use "~/yourstats.dta", clear

. list, sep(11)

     +----------------------------+
     |        _name   sN    smean |
     |----------------------------|
  1. |          fem    5       .2 |
  2. |          age    5       39 |
  3. |     nonwhite    5       .2 |
  4. |       hhsize    5      4.4 |
  5. |       parent    5        1 |
  6. |     employed    5        1 |
  7. | savings_wins    5    2.048 |
  8. |  debt_wins95    4    13125 |
  9. | earnedinc_wi    5   1608.6 |
 10. | unearninc_wi    5        0 |
 11. | underfpl2019    5        0 |
     +----------------------------+

restore

这缺少您在上面的代码中创建的空 F 统计量和 p 值变量,但您始终可以使用与 gen F=.gen pvalue=. 相同的方式添加它们。但是,这些变量的存在表明您希望在某个时候运行一些测试,然后用它们中的值填充单元格。我会就如何做到这一点提供建议,但从你的代码中我看不出你想要测试什么。如果您能澄清这一点,我将尝试编辑此答案以包含该内容。

【讨论】:

    【解决方案2】:

    这并不能直接回答您的问题;正如其他人温和指出的那样,如果没有可重复的例子,这个问题很难回答。但是我在您的代码中有几个小 cmets,以这种形式更好地呈现。

    假设所有需要的变量确实存在于数据集中,我会推荐类似这样的东西:

    local myvarlist fem age nonwhite hhsize parent employed savings_wins95 debt_wins95 earnedinc_wins95 unearninc_wins95 underfpl2019
    
    local desc `" "% Female"  "Age" "% Non-white" "HH size" "% Parent" "% Employed" "Savings stock ($)" "Debt stock ($)" "Earned income last mo. ($)" "Unearned income last mo. ($)" "% Under FPL 2019" "' 
    
    local i = 1 
    
    gen variable = "" 
    gen mean = "" 
    
    local i = 1 
    foreach var of local myvars { 
        summ `var', meanonly 
        local this : word `i' of `desc'
        
        replace variable = "`this'" in `i'
        
        if inlist(`i', 1, 3, 5, 6, 11) { 
            replace mean = strofreal(100 * r(mean), "%2.0f") in `i'
        } 
        else if `i' == 4 { 
            replace mean = strofreal(r(mean), "%2.1f") in `i' 
        } 
        else replace mean = strofreal(r(mean), "%2.0f") in `i' 
        
        local ++i 
    } 
    

    这还没有经过测试。

    出现的要点包括:

    1. 使用in 比使用if 测试观察号更可取。

    2. round() 舍入到这么多小数位是危险的。大多数时候你会得到你想要的,但偶尔你会得到奇怪的结果,因为 Stata 在二进制中工作,就像任何等效的程序一样。在字符串操作中将舍入视为一个问题并使用显示格式来提供您想要的内容会更安全。

    3. 如果您要显示的文本只是每个变量的变量标签,则可以进一步简化此代码。

    4. 代码暗示了显示其他内容的意图,这很容易与此设计兼容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多