预告所有缺失的价值观

时间:2014-11-06 22:35:37

标签: loops stata type-mismatch

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

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

我使用我的数据集中的所有变量定义了我的varlist,但是我收到"type mismatch"错误。我只用一个变量尝试replace命令,我注意到错误与数字变量有关。任何想法如何使foreach使用所有变量?或者我是否只需要选择字符串变量?

2 个答案:

答案 0 :(得分:4)

考虑一些例子。

变量是数字但附加了标签。带有" 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" s并不是真正的错失。它只是文字而没有特殊含义。

    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),则该变量必须为数字。系统缺失和延长缺失仅适用于它们。 字符串类型唯一缺失的是空白("")。

由于您报告的错误,您似乎有数字变量。如果您的变量都是字符串类型,那么您将不会遇到类型不匹配错误。不过,你提到 一些" n.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。其他选项可以在

找到

The Stata Journal(2010) 10,第2期,第281-296页, Speaking Stata:查找变量, 作者:Nick Cox。 (可在网上免费获得。)

答案 1 :(得分:3)

代码确实只适用于字符串变量。考虑一下

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