【问题标题】:foreach for all missing valuesforeach 查找所有缺失值
【发布时间】:2014-11-06 22:35:37
【问题描述】:

我正在尝试在 Stata 中编写一个 foreach 循环,它会自动将我在数据库中的所有 "n.a." 值替换为缺失值 (".a")。我有以下代码:

foreach var of varlist `allvar' {
    replace `var' = ".a" if `var' == "n.a."
}

我用我的数据集中的所有变量定义了我的 varlist,但我收到了 "type mismatch" 错误。我用一个变量尝试了replace 命令,我注意到错误与数值变量有关。知道如何将foreach 用于所有变量吗?还是只需要选择字符串变量?

【问题讨论】:

  • 请注意,Stata 没有为字符串 ".a" 附加任何特殊含义,它确实为数值 .a 附加了特殊含义。尽管该主题是关于如何做到这一点,但将具有易于解释的含义的字符串值替换为需要解释的另一个值显然不是一个有用的步骤。

标签: loops stata type-mismatch


【解决方案1】:

代码确实只适用于字符串变量。考虑这条线

replace `var' = ".a" if `var' == "n.a."

type mismatch 错误在此行中的两个条件下返回:尝试将字符串 ".a"(与缺失值 .a 不同)分配给数字变量,并尝试检查是否为数字变量变量等同于字符串"n.a."

以下代码通过仅选择字符串变量来避免该问题(感谢 Nick Cox 的简化建议)。

ds,has (type string)
foreach var in `r(varlist)' {
    replace `var' = ".a" if `var' == "n.a."
}

这个有用的警告来自 Nick Cox: “另外,在使用等号将字符串分配给本地宏时要小心。在许多版本的 Stata 中,由于字符串表达式的长度限制,字符串会被截断。”

阅读罗伯托的回答后添加

Roberto 的示例非常有用。特别是,我没有将"n.a." 的问题视为价值标签。我扩展了其中一个示例和代码,该代码将标记为"n.a." 的值替换为缺失值.a

clear
input x y
3 2
1 3
2 3
3 3
1 1
end
label define lblx 1 "a" 2 "b" 3 "n.a."
label values x y lblx
list

foreach var of varlist _all {
    loc na ""   // reset local
    loc vallab "" // reset local

    loc vallab:value label `var'
    qui levelsof `var',l(lvs)
    foreach val of local lvs    {
        loc na: label `vallab' `val'
        replace `var'=.a if "`na'"=="n.a." & `var'==`val'
    }

}
list

【讨论】:

  • @Nick 对代码的最终简化工作顺利。对于我的特殊情况,我还尝试了其他代码,它们对我进入 foreach 并理解它真的很有帮助。真的很有帮助,谢谢大家。
  • 请注意,foreach var of varlist 不是我建议的。 ds 的输出已经 (a) 已知是一个 varlist (b) 保证解析为不同的变量名。所以foreach var in 可以正常工作,并声明否则会迫使 Stata 做少量不必要的工作。
  • 对不起。这是我没有从行中删除 varlist 的疏忽。
【解决方案2】:

考虑一些例子。

变量是数字但带有标签。带有“n.a.”标签的观察结果已替换为缺失。

clear

input ///
x
1
1
2
3
3
end

label define lblx 1 "a" 2 "b" 3 "n.a."
label values x lblx

list
list, nolabel

foreach var of varlist _all {
    replace `var' = .a if `var' == 3
}

list, nolabel
count if missing(x)

变量是字符串类型。字符串被其他字符串替换;就Stata而言,“.a”并不是真正的缺失。只是没有特殊含义的文字。

    clear

    input ///
    str5 x
    a
    a
    b
    n.a.
    n.a.
    end

    list

    foreach var of varlist _all {
        replace `var' = ".a" if `var' == "n.a."
    }

    list

以下不起作用,也许是您的情况。您有一个数字变量(同样带有标签),并且您要求 Stata 检查字符串字符。因此,存在类型不匹配。

clear

input ///
x
1
1
2
3
3
end

label define lblx 1 "a" 2 "b" 3 "n.a."
label values x lblx

list

foreach var of varlist _all {
    replace `var' = ".a" if `var' == "n.a."
}

事实上,您的代码将变量视为字符串类型(因为循环中使用了引号)。如果您想使用扩展缺失值 (.a),那么变量必须是数字。系统缺失和扩展缺失仅适用于它们。 字符串类型唯一缺少的是空白 ("")。

由于您报告的错误,您似乎有数字变量。如果您的变量都是字符串类型,那么您将不会收到类型不匹配错误。尽管如此,你提到 一些“不适用” ,我认为这是价值标签。值标签的基础是一些数值。你可以看到他们在运行list, nolabel

如果是这种情况,您可以replace 对应于等于“n.a.”的值标签的数值,例如:

clear

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

input ///
x y
1 1
1 4
2 4
3 4
3 2
end

label define lblx 1 "a" 2 "b" 3 "n.a."
label values x lblx

label define lbly 1 "a" 2 "b" 4 "n.a."
label values y lbly

list
list, nolabel

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

foreach var of varlist _all {
    replace `var' = .a if `var' == "n.a.":`:value label `var''
}

// check
list, nolabel
count if missing(x)
count if missing(y)

请注意,对于变量 x,值标签 n.a. 映射到值 3,而对于变量 y,它映射到值 4。因此,对于一个变量,您想要替换值 3 ,对于另一个,值为 4。代码将自动处理该问题。此外,Stata 现在将替换的值识别为缺失值。

请参阅 help labelshelp missinghttps://stackoverflow.com/a/25942520/2077064,其中详细说明了 replace 中的条件如何工作。

如果你需要选择一种特定类型的变量,Aspen Chen 已经提到了ds。其他选项可以在

找到

Stata 杂志(2010 年) 10,第 2 期,第 281-296 页, Speaking Stata:寻找变量, 通过尼克考克斯。 (在网络上免费提供。)

【讨论】:

  • 这是很棒的附加信息。将扩展的宏功能应用于命令会更有效。
  • 对于我的特殊情况,@Roberto 进入 foreach 并理解它真的很有帮助。
  • 不客气。我仍然认为您的问题不在于foreach 循环,而在于Stata 中的标签、缺失和变量类型的概念。如果您有分配“.a”以表示缺失的字符串变量,那是您的选择并且最终可以处理。但我只想强调,Stata 并不认为这是缺失的,因此,这似乎不是自然的方式。老实说,我仍然不确定您的问题是什么,我的回答是基于猜测。但是,我不知道这个猜测是否正确。这对未来的读者来说是有帮助的。
  • 我有一个带有“n.a.”的数据库:不可用; “-”;不适用。我使用foreach 循环来替换它们并创建不同的缺失代码。 “.a”、“.b”。之后我使用了destring。我解决了我的问题,希望现在很清楚。但是我不想用我的数据库的细节来打扰你,只要了解基本的想法,你解释得很好,然后从那里开始工作。所以真的很有帮助,再次感谢。现在希望很明确。
  • @Emanuel:RobertoFerrer 在这里是正确的。尽管您已经解决了您的问题(很好,自然),但准确地弄清楚它是什么对于未来的读者仍然很重要。
猜你喜欢
  • 2012-07-05
  • 2019-12-13
  • 2013-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-18
相关资源
最近更新 更多