使用Stata中的本地来更改变量的值

时间:2014-12-08 01:56:57

标签: stata

我的数据集中有一个变量countrycode,它使用ISO数字代码(基本上是3个数字)来识别每个观察来自哪个国家/地区。但是,要与其他数据集合并,我需要将这些国家/地区代码更改为ISO alpha值(3个字母)。

我有一个匹配数字代码和alpha代码的csv文件(ISOcodes.csv);它看起来像这样:

num,name,alpha  
004,Afghanistan,AFG  
248,Åland Islands,ALA  
008,Albania,ALB   
...

这是我尝试过的解决方案:

insheet using ISOcodes.csv

* Create variables ISOnum_1, ISOnum_2, etc. and ISOalpha_1, ISOalpha_2, etc. 
* ISOnum_1 and ISOalpha_1 should refer to the same country
local N = _N
forvalues x = 1 (1) `N' {
    local ISOnum_`x' = num[`x']
    local ISOalpha_`x' = num[`x']
}

clear 
insheet using maindataset.csv

* Replace all numeric values in `countrycode` with the corresponding `alpha` values
recast countrycode str3
foreach x = 1 (1) `N' {
    replace countrycode = ISOalpha_`x' if countrycode == ISOnum_`x'
}

list countrycode

然而,我甚至无法创造当地人;当我运行它时,一旦我尝试分配第一个本地,我就会收到错误“num not allowed”。关于这里出了什么问题的任何想法?我在下一节中应该预见到的任何问题?我对Stata很新。

另外,当我清除ISOcodes.csv数据集以导入我的主数据集时,我会丢失刚分配的所有本地人吗?

2 个答案:

答案 0 :(得分:2)

你不需要循环。您想使用merge命令。接下来举个例子:

clear

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

// crosswalk file

input ///
str3 numiso str15 name str3 alpha
004 "afghanistan" "afg"
248 "aland islands" "ala"
008 "albania" "alb"
end

tempfile crossfile
save "`crossfile'"

list

more

// main data set

clear

input ///
str3 numiso str15 name gdp
004 "afghanistan" 476
248 "aland islands" 644
008 "albania" 500
end

list

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

merge 1:1 numiso using "`crossfile'"

list

您可能需要调整详细信息,因为您的数据集描述不准确。请参阅help merge

最近出现了这种情况:显式循环在Stata中并不像在其他语言中那样常见,因为默认情况下,命令会影响所有观察(从1到_N)。请参阅示例Stata counting substring

答案 1 :(得分:1)

@Roberto Ferrer正确地解释说,循环观察在这里不是一个好策略,或者实际上通常在Stata中,并提供了另一种解决方案。

这无法解释您的代码出了什么问题。

奇怪或不是,我无法看到产生您报告的错误的原因,但还有其他几个。

  1. 导入时,num中的前导零将被剥离,除非您将它们显式导入为字符串变量。 Stata将把012读为12.

  2. 首先,使用num的值创建两组本地宏。一套应该使用num;另一个应该使用alpha

  3. 本质上,Stata中的本地宏是变量。有关该问题和其他常见混淆的讨论,请参见this post

  4. 这不仅仅是纠正术语:你的代码错误,因为你指的是局部宏,好像它们是变量一样,并且不会起作用。

    您正在使用该表示法来评估本地宏,但必须一直携带。

    1. 在使用numalpha值时,您需要使用双引号来表明您希望进行文字字符串评估。

    2. 您还会混淆foreachforvalues

    3. 你的最后一个循环代表

      foreach x = 1 (1) `N' {
          replace countrycode = ISOalpha_`x' if countrycode == ISOnum_`x'
      }
      

      那应该更像是

      forval x = 1(1)`N' {
          replace countrycode = "`ISOalpha_`x''" if countrycode == "`ISOnum_`x''"  
      }
      

      更新:猜测,报告的错误出现,因为事实上你使用的语法与你说的完全不同。

      在Statalist帖子中,您报告语法,例如

        local ISOnum_`x' : num[`x']
      

      这确实是非法的。