创建具有多个类别的变量

时间:2018-05-16 00:50:51

标签: stata

我想创建一个numerical变量pets,其中包含以下类别:

  • Cat(24%)
  • 狗(36%)
  • 鱼(16%)
  • 仓鼠(12%)
  • 兔子(10%)
  • Snake(2%)

是否可以这样做?

2 个答案:

答案 0 :(得分:2)

我认为创建此变量的最简单方法是使用mata函数rdiscrete()

假设有1000次观察:

clear
set obs 1000

generate pets = . 
mata: st_store(., "pets", rdiscrete(1000, 1, (0.24, 0.36, 0.16, 0.12, 0.1, 0.02)))

(注意:mata st_store()函数用于修改pets变量中存储的值

然后,您为变量value label定义并分配pets

label define petslabel 1 "Cat" 2 "Dog" 3 "Fish" 4 "Hamster" 5 "Rabbit" 6 "Snake"
label values pets petslabel

tabulate pets

       pets |      Freq.     Percent        Cum.
------------+-----------------------------------
        Cat |        241       24.10       24.10
        Dog |        350       35.00       59.10
       Fish |        165       16.50       75.60
    Hamster |        111       11.10       86.70
     Rabbit |        112       11.20       97.90
      Snake |         21        2.10      100.00
------------+-----------------------------------
      Total |      1,000      100.00

然而,正如您所看到的,结果是函数以来的近似值 使用discrete分布绘制随机样本。因此,您可能需要运行 这段代码几次,以使数字最接近你想要的数字。

如果您需要准确的结果,则必须手动创建类别:

clear
set obs 1000

generate pets = 1 if _n <= 0.24 * 1000
replace  pets = 2 if _n <= 0.60 * 1000 & _n > 0.24 * 1000
replace  pets = 3 if _n <= 0.76 * 1000 & _n > 0.60 * 1000
replace  pets = 4 if _n <= 0.88 * 1000 & _n > 0.76 * 1000
replace  pets = 5 if _n <= 0.98 * 1000 & _n > 0.88 * 1000
replace  pets = 6 if _n >  0.98 * 1000

label define petslabel 1 "Cat" 2 "Dog" 3 "Fish" 4 "Hamster" 5 "Rabbit" 6 "Snake"
label values pets petslabel

tabulate pets

       pets |      Freq.     Percent        Cum.
------------+-----------------------------------
        Cat |        240       24.00       24.00
        Dog |        360       36.00       60.00
       Fish |        160       16.00       76.00
    Hamster |        120       12.00       88.00
     Rabbit |        100       10.00       98.00
      Snake |         20        2.00      100.00
------------+-----------------------------------
      Total |      1,000      100.00

修改

按照@Nick Cox的慷慨解答,以下是您如何引入随机性的方法:

generate double random = runiform()
sort random pets

但是,请注意, 与从特定分布中抽取随机样本相同。

最好先设置seed,以便能够复制结果。

答案 1 :(得分:2)

这是对@Pearly Spencer的优秀答案的旁注。

另一种方法是

clear
set obs 50
generate pets = cond(_n <= 12, 1, ///
                cond(_n <= 30, 2, ///
                cond(_n <= 38, 3, ///
                cond(_n <= 44, 4, ///
                cond(_n <= 49, 5, ///
                6 )))))  

然后根据需要创建和分配值标签(如Pearly的答案)和expand

数据集中的顺序的随机性可以通过根据随机数的混洗来赋予。

cond()并不像通常所说或所想的那样使用多次嵌套。它有助于记住简单规则,如在初等代数中,每个左括号(是一个约束承诺,以便稍后与右括号)匹配并在心理上通过代码(如果是X1,那么Y1;否则如果是X2,那么Y2;否则如果是X3,那么Y3; ......;否则为Yk)。

请注意,{@ 1}}形式的注释不允许以交互方式进行,但上面的布局是提高清晰度和减少错误的好主意。在任何情况下,最好在do-file或program中编写这种代码。