2013-10-03 4 views
2

У меня есть два набора данных. FIRST - это список продуктов и их ежедневные цены от поставщика, а SECOND - это список дат начала и окончания (а также другие важные данные для анализа). Как я могу рассказать Stata, чтобы вытащить цену в начале, а затем в конце дня с FIRST в SECOND на указанные даты. Обратите внимание: если нет точной даты сопоставления, я бы хотел, чтобы она получила доступную последнюю дату. Например, если у SECOND есть дата 1/1/2013, а у FIRST есть цены на ... 12/30/2012, 12/31/2012, 1/2/2013, ... он возьмет 12/31/2012 цена.Объединение данных для индивидуального анализа

Обычно я делаю это с помощью Excel, но у меня есть миллионы наблюдений, и это невозможно.

Я поставил пример FIRST и SECOND, а также то, что оптимальным решением было бы дать в качестве выхода POST_SECOND

FIRST 
Product   Price    Date 
    1    3    1/1/2010 
    1    3    1/3/2010 
    1    4    1/4/2010 
    1    2    1/8/2010 
    2    1    1/1/2010 
    2    5    2/5/2010 
    3    7    12/26/2009 
    3    2    1/1/2010 
    3    6    4/3/2010 

SECOND 
Product   Start Date   End Date 
    1    1/3/2010   1/4/2010 
    2    1/1/2010   1/1/2010 
    3    12/26/2009   4/3/2010 

POST_SECOND 
Product   Start Date   End Date  Price_Start  Price_End 
    1    1/3/2010   1/4/2010   3    4 
    2    1/1/2010   1/1/2010   1    1 
    3    12/26/2009   4/3/2010   7    6 
+0

@SOConnell Объединение данных в один и внесение переменных индикатора, но это становится очень грязным и плохо работает – CJ12

ответ

1

Вот слияния/сохранить/сортировки/коллапс * решение, которое основывается на использовании последняя дата. Я немного изменил данные примера.

/* Make Fake Data & Convert Dates to Date Format */ 
clear 
input byte Product   byte Price   str12 str_date 
    1    3    "1/1/2010" 
    1    3    "1/3/2010" 
    1    4    "1/4/2010" 
    1    2    "1/8/2010" 
    2    1    "1/1/2010" 
    2    5    "2/5/2010" 
    3    7    "12/26/2009" 
    3    7    "12/28/2009" 
    3    2    "1/1/2010" 
    3    6    "4/3/2010" 
    4    8    "12/30/2012" 
    4    9    "12/31/2012" 
    4    10    "1/2/2013" 
    4    10    "1/3/2013" 
end 

gen Date = date(str_date,"MDY") 
format Date %td 
drop str_date  
save "First.dta", replace 

clear 
input byte Product   str12 str_Start_Date  str12 str_End_Date 
    1    "1/3/2010"   "1/4/2010" 
    2    "1/1/2010"   "1/1/2010" 
    3    "12/27/2009"   "4/3/2010" 
    4    "1/1/2013"   "1/2/2013" 
end 

gen Start_Date = date(str_Start_Date,"MDY") 
gen End_Date = date(str_End_Date,"MDY") 
format Start_Date End_Date %td 
drop str_* 
save "Second.dta", replace 

/* Data Transformation */ 
use "First.dta", clear 
merge m:1 Product using "Second.dta", nogen 

bys Product: egen ads = min(abs(Start_Date-Date)) 
bys Product: egen ade = min(abs(End_Date - Date)) 
keep if (ads==abs(Date - Start_Date) & Date <= Start_Date) | (ade==abs(Date - End_Date) & Date <= End_Date) 
sort Product Date 
collapse (first) Price_Start = Price (last) Price_End = Price, by(Product Start_Date End_Date) 
list, clean noobs 

* Некоторые люди reshapers. Другие - коллапсоры. Часто оба могут выполнить свою работу, но я думаю, что в этом случае коллапс будет проще.

+0

Это хорошо работает, но что, если, как в последней части вопроса, если: «Обратите внимание, если есть нет точной даты сопоставления Я бы хотел, чтобы она захватила последнюю доступную дату. Например, если 'SECOND' имеет дату 1/1/2013, а' FIRST' имеет цены на ... 12/30/2012, 12/31/2012, 1/2/2013, ... он захватит цену 12/31/2012 ». Когда я изменяю «Start_Date» продукта 3 на '12/27/2009', ваше решение не работает. – CJ12

+0

Я разнесся по этой части. Взгляните на мое обновленное решение. Он делает то, что вы хотите? –

0

В Stata я никогда не мог получить что-то вроде этого, чтобы хорошо работать за один шаг (что-то, что вы можете сделать в SAS через SQL-вызов). В любом случае, я думаю, вам было бы лучше создать промежуточный файл с FIRST.dta, а затем слияние этого 2x на каждой из ваших StartDate и EndDate переменных в SECOND.dta.

Скажите, что у вас есть данные для корректировки цен с 1 января 2010 года по 31 декабря 2013 года (с различными интервалами, указанными выше). Я предполагаю, что все переменные даты уже находятся в date format в FIRST.dta & SECOND.dta, и имена переменных в SECOND не содержат пробелов.

tempfile prod prices 

use FIRST.dta, clear 
keep Product 
duplicates drop 
save `prod' 

clear 
set obs 1096 
g Date=date("12-31-2009","MDY")+_n 
format date %td 
cross using `prod' 

merge 1:1 Product Date using FIRST.dta, assert(1 3) nogen 
gsort +Product +Date /*this ensures the data are sorted properly for the next step */ 
replace price=price[_n-1] if price==. & Product==Product[_n-1] 
save `prices' 

use SECOND.dta, clear 
foreach i in Start End { 
rename `i'Date Date 
merge 1:1 Product Date using `prices', assert(2 3) keep(3) nogen 
rename Price Price_`i' 
rename Date `i'Date 
} 

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

Смежные вопросы