Подсчет количества изменений категориальной переменной в наборе панельных данных

Я работаю с набором данных панели со следующими переменными. Вот фрагмент моих данных:

i     region urban year
8431  3      1     1979
8431  3      1     1980
8431  3      1     1981
8431  3      1     1982
8431  3      0     1983
8431  3      0     1984
8431  3      0     1985
8431  3      0     1986
8431  3      0     1987
8431  3      0     1988
8431  3      0     1989
8431  3      1     1990
8431  3      1     1991
8431  3      1     1992
8431  3      1     1993
8431  3      1     1994
8431  3      1     1996
8431  3      0     1998
8431  3      1     2000
8431  3      1     2002
8431  3      1     2004
8431  3      1     2006
8431  2      0     2008
8431  3      1     2010
8431  3      1     2012

Панель сильно сбалансирована, но есть некоторые недостающие наблюдения в данных, которые я обрабатываю с помощью интерполяции.

Я хочу подсчитать общее количество раз region и urban изменения в течение периода наблюдения для каждого человека.

Первое, что я попробовал, это запаздывающие значения:

bysort i: gen urban_lag = l1.urban
bysort i (year): gen urbanchange = 0 if urban==urban_lag & !missing(urban)
replace urbanchange = 1 if urban!=urban_lag & !missing(urban)

По какой-то причине это генерирует много пропущенных значений, даже для тех, у кого нет пропущенных значений для region. Кто-нибудь знает, почему это так?

Затем я попробовал это:

sort i year
by i: gen byte urbanchange = urban != urban[_n-1]

Это в основном работает и приближает меня к тому месту, где я хочу, за исключением того, что первое наблюдение каждого человека равно 1, потому что change[0] находится перед началом данных, и поэтому Stata возвращает его как отсутствующее, поэтому я получаю urbanchange[1] = 1 для каждого человека.

Вот результат, который я хочу:

i     region urban year  regionchange  urbanchange
8431  3      1     1979  0             0
8431  3      1     1980  0             0
8431  3      1     1981  0             0
8431  3      1     1982  0             0
8431  3      0     1983  0             1
8431  3      0     1984  0             0
8431  3      0     1985  0             0
8431  3      0     1986  0             0
8431  3      0     1987  0             0
8431  3      0     1988  0             0
8431  3      0     1989  0             0
8431  3      1     1990  0             1
8431  3      1     1991  0             0
8431  3      1     1992  0             0
8431  3      1     1993  0             0
8431  3      1     1994  0             0
8431  3      1     1996  0             0
8431  3      0     1998  0             1
8431  3      1     2000  0             1
8431  3      1     2002  0             0
8431  3      1     2004  0             0
8431  3      1     2006  0             0
8431  2      0     2008  1             1
8431  3      1     2010  1             1
8431  3      1     2012  0             0

Этот вопрос в основном является версией Stata этого вопроса, который я задал год назад Подсчет количества изменений категориальной переменной во время повторных измерений в категории

Изменить в отношении интерполяции: поскольку в моих данных много пробелов, для наблюдений с пропущенными значениями я предполагаю, что, например, текущая городская ценность человека такая же, как и последнее наблюдаемое ( неотъемлемая часть) городского значения.

Например:

region  urban   year
1       1       1979
1       1       1980
1       1       1981
3       1       1982
3       1       1983
3       1       1984
.       .       1985
1       1       1986
1       1       1987
1       1       1988
1       1       1989
.       .       1990
.       .       1991
.       .       1992
.       .       1993
.       .       1994
        

Я заполняю недостающие значения следующим образом:

gen urban1 = urban
bysort i (year): replace urban1 = urban1[_n-1] if missing(urban1)
gsort i -year 
replace urban1 = urban1[_n-1] if urban1 >=. 

и сделайте то же самое для региона.

Выход:

region  urban   year   region1  urban1
1       1       1979   1        1
1       1       1980   1        1
1       1       1981   1        1        
3       1       1982   3        1
3       1       1983   3        1        
3       1       1984   3        1        
.       .       1985   3        1
1       1       1986   1        1
1       1       1987   1        1
1       1       1988   1        1
1       1       1989   1        1
.       .       1990   1        1
.       .       1991   1        1
.       .       1992   1        1
.       .       1993   1        1
.       .       1994   1        1

Я делаю здесь несколько сильных предположений, и некоторые могут не согласиться с тем, что я здесь делаю, но с целью подсчета количества изменений это не влияет на результаты, которые я хочу, а отсутствующие значения не влияют на мои выход.


person m_j    schedule 16.01.2021    source источник
comment
Ваш код интерполяции делает больше, чем вы говорите, поскольку вы также копируете известные значения назад, если значения отсутствуют в начале каждой панели.   -  person Nick Cox    schedule 17.01.2021


Ответы (1)


В этом ответе основное внимание уделяется вопросу, который заключается в подсчете количества изменений в панели. Ваш желаемый результат есть только частично, так как он состоит из индикаторов с 1 для изменения и 0 для того же самого.

Рассмотрим этот код с вашим примером данных:

clear 
input i     region urban year
8431  3      1     1979
8431  3      1     1980
8431  3      1     1981
8431  3      1     1982
8431  3      0     1983
8431  3      0     1984
8431  3      0     1985
8431  3      0     1986
8431  3      0     1987
8431  3      0     1988
8431  3      0     1989
8431  3      1     1990
8431  3      1     1991
8431  3      1     1992
8431  3      1     1993
8431  3      1     1994
8431  3      1     1996
8431  3      0     1998
8431  3      1     2000
8431  3      1     2002
8431  3      1     2004
8431  3      1     2006
8431  2      0     2008
8431  3      1     2010
8431  3      1     2012
end 

bysort i (year) : gen change1 = sum(region != region[_n-1])
by i : replace change1 = change1[_N]

by i : gen change2 = sum(urban != urban[_n-1])
by i : replace change2 = change2[_N]

tabdisp i, c(change?) 

----------------------------------
        i |    change1     change2
----------+-----------------------
     8431 |          3           7
----------------------------------

sum() вычисляет текущую или кумулятивную сумму, и, глядя на последнее значение на каждой панели, вы получаете количество заклинаний или запусков для переменной, причем каждое заклинание или запуск определяется соответствующей переменной, являющейся константой.

Важно подумать о том, что происходит при первом наблюдении за каждой панелью. Это наблюдение 1. Как вы говорите, Stata довольна ссылкой, неявной или явной, на значения в предыдущем наблюдении 0, но всегда возвращает отсутствующее значение. Таким образом, в примере данных region[1] равно 1, region[0] возвращается как отсутствующее, и поэтому region[1] не равно region[0]. Следовательно, даже если бы переменная была полностью постоянной на панели, каждая переменная счетчика, созданная этим кодом, была бы 1. Если вы хотите изменить только внутри панели, вычтите 1 в последнем операторе.

Подробнее о принципах распознавания заклинаний см. в этом столбце.

Я использовал индексы, а не операторы временных рядов из-за пробелов в вашей панели. Я не могу понять ваше упоминание об интерполяции в достаточной степени, чтобы понять, как будут выглядеть данные после интерполяции, и в любом случае пример данных содержит пробелы, и это то, что могут видеть люди, отвечающие на вопросы.

Итак, почему вы получили недостающие значения? Во-первых, ваш код будет выдавать пропущенные значения при первом наблюдении каждой панели, если только первое значение не пропущено. Во-вторых, пропуски могут привести к пропущенным значениям с операторами временных рядов.

Ваш первый блок кода

bysort i: gen urban_lag=l1.urban
bysort i (year): gen urbanchange = 0 if urban==urban_lag & !missing(urban)
replace urbanchange = 1 if urban!=urban_lag & !missing(urban)

зависит от предыдущего

tsset i year 

но с учетом того, что вы сделали это раньше, блок почти уменьшается до

gen urbanchange = urban != l1.urban & !missing(urban) 

Совершенно законно использовать префикс by: с идентификатором панели, а также использовать операторы временных рядов, но это не обязательно. Частью белой магии операторов временных рядов является то, что там, где существуют отдельные панели, отдельные вычисления гарантируются.

person Nick Cox    schedule 16.01.2021
comment
Добавлена ​​информация об интерполяции. Спасибо, что предложили колонку! Мой первоначальный мыслительный процесс заключался в том, чтобы получить индикаторы изменения 0 1, а затем выполнить: by i: egen totchange = total (urbanchange), но ваш код выполняет это за меньшее количество шагов. - person m_j; 17.01.2021