#r #group-by #dplyr #lag
#r #группировать по #dplyr #задержка
Вопрос:
Ниже вы можете увидеть образец моего набора данных.
Fac Date Type Change StartDT EndDT
AAA 1/1/2019 General 0 1/1/2019 1/2/2019
AAA 1/2/2019 General 0 1/1/2019 1/2/2019
AAA 1/3/2019 Special 1 1/3/2019 1/4/2019
AAA 1/4/2019 Special 1 1/3/2019 1/4/2019
AAA 1/5/2019 Intensive 2 1/5/2019 1/5/2019
BBB 1/1/2019 General 0 1/1/2019 1/4/2019
BBB 1/2/2019 General 0 1/1/2019 1/4/2019
BBB 1/3/2019 General 0 1/1/2019 1/4/2019
BBB 1/4/2019 General 0 1/1/2019 1/4/2019
BBB 1/5/2019 Reserve 1 1/5/2019 1/6/2019
BBB 1/6/2019 Reserve 1 1/5/2019 1/6/2019
Я хотел бы создать переменную для отслеживания изменений в моей переменной типа (change). Раньше я работал в Stata, и логика для этого заключается в том, чтобы сначала отследить, изменилось ли значение по сравнению с предыдущей записью (0/1) для каждой панели / группы, а затем получить текущую сумму этого значения.
bysort Facility (Date): gen byte era = sum(Type != Type[_n-1] amp; _n > 1)
Как я могу это сделать в R? Также после создания переменной изменения мне нужно будет сгенерировать начальную и конечную (минимальную, максимальную) даты для каждого Fac и изменения («era»).
Я был бы признателен за любую помощь! Заранее спасибо! Марвин
Комментарии:
1. Пожалуйста, объясните, почему здесь изменение = 2
AAA 1/5/2019 Intensive 2 1/5/2019 1/5/2019
2. Потому что оно перешло из специального в интенсивное. Любое изменение в этой переменной должно отслеживаться. Итак, если тип объекта AAA снова изменится, нам нужно будет записать это, и это будет 3.
Ответ №1:
Вот одно из решений, использующее dplyr:
dat =
tibble(
fac = c(rep("A", 10), rep("B", 10)),
type = sample(1:3, 20, replace = TRUE)
)
dat %>%
group_by(fac) %>%
mutate(
change = case_when(
type != lag(type) ~ TRUE,
TRUE ~ FALSE
),
n_change = cumsum(change)
)
Для вашего кода вы могли бы затем добавить:
group_by(Fac, n_change) %>%
mutate(
min_start_date = min(StartDT),
max_start_date = max(EndDT)
)
Ответ №2:
Рассмотрите возможность перебора последовательности номеров строк с sapply
, чтобы проверить соответствие между значениями типа текущей строки и предыдущей. И использовать ave
для встроенной агрегации итогов по группе Fac:
dat <- within(dat, {
# CONVERT DATES
Date <- with(dat, as.Date(Date, format="%m/%d/%Y"))
StartDT <- with(dat, as.Date(StartDT, format="%m/%d/%Y"))
EndDT <- with(dat, as.Date(StartDT, format="%m/%d/%Y"))
# CALCULATE TYPE CHANGES
type_delta <- c(NA, sapply(2:nrow(dat), function(i)
ifelse(dat$Type[i] != dat$Type[i-1], 1, 0)
)
)
era <- ave(type_delta, Fac, FUN=function(x) sum(x, na.rm=TRUE))
})
dat
# Fac Date Type Change StartDT EndDT era type_delta
# 1 AAA 2019-01-01 General 0 2019-01-01 2019-01-01 2 NA
# 2 AAA 2019-01-02 General 0 2019-01-01 2019-01-01 2 0
# 3 AAA 2019-01-03 Special 1 2019-01-03 2019-01-03 2 1
# 4 AAA 2019-01-04 Special 1 2019-01-03 2019-01-03 2 0
# 5 AAA 2019-01-05 Intensive 2 2019-01-05 2019-01-05 2 1
# 6 BBB 2019-01-01 General 0 2019-01-01 2019-01-01 2 1
# 7 BBB 2019-01-02 General 0 2019-01-01 2019-01-01 2 0
# 8 BBB 2019-01-03 General 0 2019-01-01 2019-01-01 2 0
# 9 BBB 2019-01-04 General 0 2019-01-01 2019-01-01 2 0
# 10 BBB 2019-01-05 Reserve 1 2019-01-05 2019-01-05 2 1
# 11 BBB 2019-01-06 Reserve 1 2019-01-05 2019-01-05 2 0
Ответ №3:
Огромное спасибо @Parfait и @user2363777 за всю помощь! Это потрясающе. Я использовал решение user2363777, поскольку я больше знаком с dplyr. Для последнего блока кода я просто включил функцию ungroup() в конце. Тогда я просто сохраняю одну запись на объект и эпоху.
Fac Era Type StartDT EndDT
AAA 0 General 1/1/2019 1/2/2019
AAA 1 Special 1/3/2019 1/4/2019
AAA 2 Intensive 1/5/2019 1/5/2019
BBB 0 General 1/1/2019 1/4/2019
BBB 1 Reserve 1/5/2019 1/6/2019
Моя конечная цель — сгенерировать график, который отображает изменения в типах объектов с течением времени (изменение категориальной переменной с течением времени). Я собираюсь исследовать, как я могу отобразить это на графике. Возможно, я скоро опубликую что-нибудь по этому поводу. Спасибо!!