Stata - 如果列表的任何字符串变量以特定字符开头,则生成虚拟变量

时间:2014-06-16 02:12:46

标签: string substring stata dummy-data

我试图在Stata中创建虚拟变量,如果任何变量dx1dx25以特定字符串开头,则为1。我知道我可以使用以下内容执行此操作,但对于所有25个dx变量:

gen dummy=0
replace dummy=1 if substr(dx1,1,4)=="6542" | substr(dx2,1,4)=="6542" 

如果dx中的任何一个以这些为开头,我会创建等于1的其他虚拟对象:

   6542     6522    6696    6410    6411    6412    6630    218     6426    459 490 491 492 493 494 495 496 9971    250     2810    28249   05410   054     657 V27.2   V27.3   V27.4   V27.5   V27.6   V27.7

我一直在努力找出一种更有效,更优雅的方法。

数据结构示例(由于空间原因,我会将dx1通过dx5保留在此处):

     +---------------------------------------+
     |   dx1     dx2     dx3     dx4     dx5 |
     |---------------------------------------|
  1. | 65421    V270                         |
  2. | 65221   65801   64232   65951   64892 |
  3. | 64511    V270                         |
  4. | 64781    V270                         |
  5. | 65571   66331   64891     340    V270 |
     |---------------------------------------|
  6. | 66401   67202   66331    V270         |
  7. | 66411    V270   V1321                 |
  8. | 65571    V270   V5864                 |
  9. | 65421    V270    V252                 |
 10. | 64511   64231   66331   66401    V270 |
     |---------------------------------------|
 11. | 65651   66401    V270                 |
 12. |   650    V270                         |
 13. | 64881   66541   66331    V270    V161 |
 14. | 66311   65971    V270                 |
 15. | 64781    V270   V1589                 |
     |---------------------------------------|
 16. | 65571   66191    V270                 |
 17. | 64241   66401    V270                 |
 18. | 66031   65971   66071    V270         |
 19. | 64841   66401   30520    V270         |
     +---------------------------------------+

1 个答案:

答案 0 :(得分:4)

我首先尝试让事情奏效。在那之后,如果它对我的需求来说效率太低(有时候在美学上不愉快),我会尝试以不同的方式解决问题。按照你的想法,为什么不尝试循环:

clear all
set more off

*----- Example data -----

input ///
str10(dx1     dx2     dx3     dx4     dx5)
    65421    V270                         
    65221   65801   64232   65951   64892 
    64511    V270                         
    64781    V270                         
    65571   66331   64891     340    V270 
    66401   67202   66331    V270         
    66411    V270   V1321                 
    65571    V270   V5864                 
    65421    V270    V252                 
   64511   64231   66331   66401    V270 
   65651   66401    V270                 
     650    V270                         
   64881   66541   66331    V270    V161 
   66311   65971    V270                 
   64781    V270   V1589                
   65571   66191    V270                 
   64241   66401    V270                 
   66031   65971   66071    V270         
   64841   66401   30520    V270         
end

list in 1/15

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

local li "6542 6522 6696 6410 6411 6412 6630 218 6426 459 490 491 492 493 494 495 496 9971 250 2810 28249 05410 054 657 V27.2 V27.3 V27.4 V27.5 V27.6 V27.7"

quietly foreach val of local li {

    local tname = strtoname("ind`val'")
    gen byte `tname' = 0     

    foreach var of varlist dx* {
        replace `tname' = 1 if substr(`var',1,4) == "`val'"
    }

}

browse

我使用感兴趣的字符串来命名指标变量(你称之为虚拟)。因为某些字符串会产生非法的Stata名称,所以我使用strtoname()函数。当然,这种命名约定不是强制性的。

正在进行的评估比实际需要的还多,但它可能就足够了。对于local li的每个元素,在执行第一个replace之后不需要进行更多评估。但代码会检查所有 dx个变量。

也许有更好的方法来达到最终结果,但你不能说出那是什么。这似乎只是一些中间步骤。

运行help <command_or_function>以获取有关特定语法的详细信息。

(请注意,在原帖中

list dx1 dx2 dx3 dx4 dx5 in 1/20

更有效
list dx1 dx2 dx3 dx4 dx5 if _n<20

因为Stata不需要检查数据库中每个观察点是否满足if条件。它只列出了前20个观测值。)