2016-05-08 2 views
0

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

Чтобы проиллюстрировать пример, мои данные живет в виде:

person | subscription | obs_date | sub_start_date | sub_end_date | num_concurrent_subs 
-------------------------------------------------------------------------------------- 
1  | 1   | 09/01/10 | 09/01/10  | 09/01/11  | 1 
1  | 1   | 10/01/10 | 09/01/10  | 09/01/11  | 2 
1  | 1   | 11/01/10 | 09/01/10  | 09/01/11  | 2 
1  | 2   | 10/01/10 | 10/01/10  | 09/01/11  | 2 
1  | 2   | 11/01/10 | 10/01/10  | 09/01/11  | 2 
1  | 3   | 11/01/14 | 09/01/14  | .   | 1 
1  | 3   | 11/01/16 | 09/01/14  | .   | 1 
1  | 4   | 11/01/15 | 10/01/15  | 11/01/15  | 3 
1  | 5   | 11/01/15 | 10/01/15  | 11/01/15  | 3 

И так далее, и так далее для каждого человека. Я хочу создать num_concurrent_subs, как указано выше.

То есть, для каждого человека, посмотрите на каждое наблюдение и найдите, сколько подписчиков оно попадает в диапазон sub_start_date до sub_end_date.

Я читал немного о функции Stata count и считаю, что я близок к решению, но я не уверен, как проверить его на разные подписки.

+0

Строго 'count' - это команда, а не функция. В командах и функциях Stata есть разные виды животных. –

ответ

1

Вы можете сделать это, отделив информацию о подписке от данных транзакции и преобразуя данные подписки в длинную форму, с одним наблюдением за датой начала и другой для конечной даты. Затем вы рекомбинируете данные транзакции и порядок с помощью одной переменной даты. Для отслеживания начала и окончания каждой подписки используется переменная onoff. Что-то вроде:

* Example generated by -dataex-. To install: ssc install dataex 
clear 
input byte(person subscription) str8(obs_date sub_start_date sub_end_date) byte num_concurrent_subs 
1 1 "09/01/10" "09/01/10" "09/01/11" 1 
1 1 "10/01/10" "09/01/10" "09/01/11" 2 
1 1 "11/01/10" "09/01/10" "09/01/11" 2 
1 2 "10/01/10" "10/01/10" "09/01/11" 2 
1 2 "11/01/10" "10/01/10" "09/01/11" 2 
1 3 "11/01/14" "09/01/14" "."  1 
1 3 "11/01/16" "09/01/14" "."  1 
1 4 "11/01/15" "10/01/15" "11/01/15" 3 
1 5 "11/01/15" "10/01/15" "11/01/15" 3 
end 

* should always have an observation identifier 
gen obsid = _n 

* convert string to Stata numeric dates 
gen odate = daily(obs_date,"MD20Y") 
gen substart = daily(sub_start_date,"MD20Y") 
gen subend = daily(sub_end_date,"MD20Y") 
format %td odate substart subend 
save "main_data.dta", replace 

* reduce to subscription info with one obs for the start and one obs 
* for the end of each subscription. use an onoff variable to tract 
* start and end events 
keep person subscription substart subend 
bysort person subscription substart subend: keep if _n == 1 
expand 2 
bysort person subscription: gen adate = cond(_n == 1, substart, subend) 
by person subscription: gen onoff = cond(_n == 1, 1, -1) 
replace onoff = 0 if mi(adate) 
format %td adate 

append using "main_data.dta" 

* include obs date in adate and nothing happens on the observation date 
replace adate = odate if !mi(obsid) 
replace onoff = 0 if !mi(obsid) 

* order by person adate, put on event first, then obs events, then off events 
gsort person adate -onoff 
by person: gen concur = sum(onoff) 

* return to original obs 
keep if !mi(obsid) 
sort obsid 
+0

Обсуждение трюка 'expand 2' на http://www.stata-journal.com/sjpdf.html?articlenum=dm0068 –

1

Вот еще один способ сделать это, используя rangejoin (от SSC). Чтобы установить его, наберите в окне командной строки STATA в:

ssc install rangejoin 

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

* Example generated by -dataex-. To install: ssc install dataex 
clear 
input byte(person subscription) str8(obs_date sub_start_date sub_end_date) byte num_concurrent_subs 
1 1 "09/01/10" "09/01/10" "09/01/11" 1 
1 1 "10/01/10" "09/01/10" "09/01/11" 2 
1 1 "11/01/10" "09/01/10" "09/01/11" 2 
1 2 "10/01/10" "10/01/10" "09/01/11" 2 
1 2 "11/01/10" "10/01/10" "09/01/11" 2 
1 3 "11/01/14" "09/01/14" "."  1 
1 3 "11/01/16" "09/01/14" "."  1 
1 4 "11/01/15" "10/01/15" "11/01/15" 3 
1 5 "11/01/15" "10/01/15" "11/01/15" 3 
end 

* should always have an observation identifier 
gen obsid = _n 

* convert string to Stata numeric dates 
gen odate = daily(obs_date,"MD20Y") 
gen substart = daily(sub_start_date,"MD20Y") 
gen subend = daily(sub_end_date,"MD20Y") 
format %td odate substart subend 
save "main_data.dta", replace 

* reduce to subscription start and end date per person 
bysort person subscription substart subend: keep if _n == 1 
keep person substart subend 

* missing values will exclude obs so use a date in the future 
replace subend = mdy(1,1,2099) if mi(subend) 

* pair each subscription with an obs date 
rangejoin odate substart subend using "main_data.dta", by(person) 

* the number of current subcription is the number of pairings 
bysort obsid: gen current = _N 

* return to original obs 
by obsid: keep if _n == 1 
sort obsid 
drop substart subend 
rename (substart_U subend_U) (substart subend) 
Смежные вопросы