#r #date #dummy-variable #panel-data
#r #Дата #фиктивная переменная #панель-данные
Вопрос:
Я провожу исследование событий в несбалансированном наборе данных panal. Основная структура заключается в том, что у меня разное количество наблюдений (поставок) для каждой фирмы в разные моменты в течение периода около 15 лет. Меня интересует событие (повышение цены), которое кодируется как фиктивная переменная, если оно происходит, и некоторое фиктивное лидерство и задержки, чтобы проверить, становится ли очевидным влияние повышения цены на мою зависимую переменную вокруг этого события. Например, для некоторых фирм повышение цен происходит при 5 поставках, например, 50 за 15 лет.
Однако теперь я также хочу «смоделировать» одно и то же исследование событий через год после и до, чтобы улучшить вывод. Поэтому я хочу, чтобы R дублировал фиктивное событие для каждой фирмы при доставке, ближайшей к одному году до и после. Даты доставки происходят не ежедневно, а в среднем каждые 25 дней.
Итак, в виде кода данные выглядят примерно так:
df <- data.frame(firm_id = c(1,1,1,1,1,2,2,2,3,3,3,3,3,3,3,3,3,3,4,4,4,4),
delivery_id = c(1,2,6,9,15,3,5,18,4,7,8,10,11,13,17,19,22,12,14,16,20,21),
date=c("2004-06-16", "2004-08-12", "2004-11-22", "2005-07-03", "2007-01-04",
"2004-09-07", "2005-02-01", "2006-01-17",
"2004-10-11", "2005-02-01", "2005-04-27", "2005-06-01", "2005-07-01",
"2006-01-03", "2007-01-06", "2007-03-24", "2007-05-03",
"2005-08-03", "2006-02-19", "2006-06-13", "2007-02-04", "2007-04-26"),
price_increase = c(0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0),
price_increase_year_before = c(1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0),
price_increase_year_afer = c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0))
Создание
firm_id delivery_id date price_increase price_increase_year_before price_increase_year_after
1 1 1 2004-06-16 0 1 0
2 1 2 2004-08-12 0 0 0
3 1 6 2004-11-22 0 0 0
4 1 9 2005-07-03 1 0 0
5 1 15 2007-01-04 0 0 0
6 2 3 2004-09-07 0 0 0
7 2 5 2005-02-01 0 0 0
8 2 18 2006-01-17 0 0 0
9 3 4 2004-10-11 0 0 0
10 3 7 2005-02-01 0 1 0
11 3 8 2005-04-27 0 0 0
12 3 10 2005-06-01 0 0 0
13 3 11 2005-07-01 0 0 0
14 3 13 2006-01-03 1 0 0
15 3 17 2007-01-06 0 0 1
16 3 19 2007-03-24 0 0 0
17 3 22 2007-05-03 0 0 0
18 3 12 2005-08-03 0 0 0
19 4 14 2006-02-19 0 0 0
20 4 16 2006-06-13 0 0 0
21 4 20 2007-02-04 0 0 0
22 4 21 2007-04-26 0 0 0
Где я хочу создать два фиктивных столбца справа на основе price_increase и даты для каждой фирмы. Хотя я бы начал с dyplr group_by
и mutate
подхода и if_else
функции, я понятия не имею, как создать условие, которое возникает TRUE
, когда доставка за один год составляет 1 / -1 месяц, близкий к дате в предыдущем или следующем году, и как выбрать соответствующую доставку. У вас, ребята, есть идея?
Комментарии:
1. Почему есть только один 1 в
price_increase_year_after
? Также данные, которыми вы поделились, кажутся неполными. Можете ли вы это исправить?2. Привет, Ронак, спасибо за ваш комментарий. Причина в том, что через год после повышения цены на
firm_id = 1
следующую доставку (delivery_id = 15
) будет через два года, что выходит за пределы диапазона один год 1 / -1 месяц.
Ответ №1:
Вот возможный подход с использованием dplyr
.
После group_by(firm_id)
filter
и включить группы, в которых произошло повышение цен.
Затем создайте свои две фиктивные переменные, если дата составляет один год ( /- 30 дней) до или после даты, когда значение price_increase
было равно 1. Затем filter
для строк, которые соответствуют этим критериям.
С помощью distinct
вы можете предотвратить кратные или повторяющиеся значения для вашей фиктивной переменной в группе / фирме. В противном случае, если ваши поставки были разделены 25 днями, это казалось теоретической возможностью.
Остальное после этого присоединяется к исходным данным, заменяя NA
на ноль для фиктивных столбцов и сортируя.
library(dplyr)
df$date <- as.Date(df$date)
df %>%
group_by(firm_id) %>%
filter(any(price_increase == 1)) %>%
mutate(
price_increase_year_before = ifelse(
between(date[price_increase == 1] - date, 335, 395), 1, 0),
price_increase_year_after = ifelse(
between(date - date[price_increase == 1], 335, 395), 1, 0),
) %>%
filter(price_increase_year_before == 1 | price_increase_year_after == 1) %>%
distinct(firm_id, price_increase_year_before, price_increase_year_after, .keep_all = TRUE) %>%
right_join(df) %>%
replace_na(list(price_increase_year_before = 0, price_increase_year_after = 0)) %>%
arrange(firm_id, date)
Вывод
firm_id delivery_id date price_increase price_increase_year_before price_increase_year_after
<dbl> <dbl> <date> <dbl> <dbl> <dbl>
1 1 1 2004-06-16 0 1 0
2 1 2 2004-08-12 0 0 0
3 1 6 2004-11-22 0 0 0
4 1 9 2005-07-03 1 0 0
5 1 15 2007-01-04 0 0 0
6 2 3 2004-09-07 0 0 0
7 2 5 2005-02-01 0 0 0
8 2 18 2006-01-17 0 0 0
9 3 4 2004-10-11 0 0 0
10 3 7 2005-02-01 0 1 0
11 3 8 2005-04-27 0 0 0
12 3 10 2005-06-01 0 0 0
13 3 11 2005-07-01 0 0 0
14 3 12 2005-08-03 0 0 0
15 3 13 2006-01-03 1 0 0
16 3 17 2007-01-06 0 0 1
17 3 19 2007-03-24 0 0 0
18 3 22 2007-05-03 0 0 0
19 4 14 2006-02-19 0 0 0
20 4 16 2006-06-13 0 0 0
21 4 20 2007-02-04 0 0 0
22 4 21 2007-04-26 0 0 0
Комментарии:
1. спасибо за ваше решение. Это делает именно то, что я планировал (и вы абсолютно правы с этой
distinct
частью. Я нашел способ, но гораздо менее элегантный, поскольку я не знал, что вы можете вычислить это просто вas.Date
классе. Большое спасибо!