Заполните переменную вложенной строкой l oop - PullRequest
0 голосов
/ 29 апреля 2020

Я пытаюсь создать переменную, подобную этой, в Stata:

date
2012_1
2012_2
2013_1
2013_2

со следующим l oop:

forval y=2012/2013{
forval m=1/2{
display `m'         
    gen date =  `y'_`m'
}
}   

Но я получаю эту ошибку в первая итерация: 2012_1 invalid name. Извините, если вопрос очевиден, я новичок ie в Stata.

Ответы [ 2 ]

2 голосов
/ 29 апреля 2020

Вы сталкиваетесь с большим количеством проблем, чем понимаете, но все просто.

  1. Непосредственная проблема с вашим l oop заключается в том, что значение, такое как 2012_1, предназначено вами как значение переменной, но если это так, оно должно быть явно строкой в окружении "". Причина в том, что подчеркивание _ допустимо только как часть строки. Стата явно озадачена вашей командой. Сообщение об ошибке не совсем соответствует ситуации, хотя верно, что 2012_1 не является допустимым именем, означающим имя переменной или скаляра.

  2. Если вы исправите это, ваша следующая проблема будет во второй раз, когда ваша l oop переменная уже существует, и поэтому generate недопустимо. Вам нужно будет replace. Таким образом, оператор generate должен быть взят за пределы l oop.

  3. Опять же, все, что делает ваш l oop даже с этими исправленными проблемами, это каждый раз перезаписывает переменную одним и тем же значением. В конце ваших циклов все наблюдения будут содержать постоянное значение 2013_2.

  4. В долгосрочной перспективе проблема все еще существует. Очевидно, вам нужна месячная переменная даты, но такие переменные в месячной дате мало полезны в Stata. Они сортируются в правильном порядке, но они практически бесполезны для статистики или графики.

Это лучшая идея со всех сторон:

generate mdate = . 
local i = 1 

forval y = 2012/2013 {
    forval m = 1/2 {
        replace mdate = ym(`y', `m') in `i' 
        local ++i       
    }
} 

Это все еще не хороший стиль. Полагаю, вам не нужны месяцы 1 и 2, но мы не можем знать, чего вы действительно хотите.

Сделайте это в Stata:

clear 
set obs 48 
generate mdate = ym(2011, 12) + _n 
format mdate %tm 
list 

, чтобы получить представление о лучшем подходе - без циклов вообще.

2 голосов
/ 29 апреля 2020

С вашим кодом довольно много проблем. Я пройду через них go один за другим.

`y'_`m' оценивает 2012_1 первую итерацию. Поскольку он содержит подчеркивание, его нельзя интерпретировать как цифры c. Чтобы быть интерпретированным как строковое значение, требуется, чтобы оно было заключено в "". В конце концов, Stata пытается интерпретировать его как переменную, но 2012_1 не является допустимым именем (должно начинаться с буквы), поэтому ваша ошибка.

Вы можете заключить свое значение в кавычки, чтобы создать строковую переменную: "`y'_`m'". Это будет работать для первой итерации, но на второй итерации вы получите ошибку, так как переменная 'date' уже существует. После создания переменной вы можете только replace it.

Наконец, ваш код ничего не говорит о том, какое значение соответствует какому наблюдению. Даже если вы исправите уже упомянутые проблемы, ваша переменная будет просто содержать одинаковые значения для всех наблюдений, что является значением последней итерации в l oop. Чтобы заменить только одно наблюдение, вы должны указать in i, где i - номер наблюдения.

В целом, это будет измененный код:

gen date = "."
local obs = 1
forval y=2012/2013{
    forval m=1/2{
        display `m'         
        replace date =  "`y'_`m'" in `obs'
        local ++obs
    }
}   

Однако я бы не стал рекомендуем создавать этот тип переменной даты, так как строковые переменные ограничены в том, что вы можете с ними делать Внутренний формат даты Stata является наиболее удобным. Если ваши значения 1 и 2 соответствуют полугодиям, вы можете создать полугодовую переменную даты, см. help datetime для получения информации о том, как это сделать. Другой вариант - создать переменную цифр c, содержащую год, и вторую переменную цифр c, содержащую 1 и 2.

...