Как рассчитать разницу показателей между группами с учетом даты

#r #dplyr

#r #dplyr

Вопрос:

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

 test1 = data.frame(my_groups = c("A", "A", "A", "B", "B", "B", "C", "C", "C", "A", "A", "A"),  measure = c(10, 20, 5, 64, 2, 62 ,2, 5, 4, 6, 7, 105),  #distance = c(),  time= as.Date(c("20-09-2020", "25-09-2020", "19-09-2020", "20-05-2020", "20-05-2020", "20-06-2021",   "11-01-2021", "13-01-2021", "13-01-2021", "15-01-2021", "15-01-2021", "19-01-2021"), format = "%d-%m-%Y"))    # test1 %gt;% arrange(my_groups, time)  # my_groups measure time  # 1 A 5 2020-09-19  # 2 A 10 2020-09-20  # 3 A 20 2020-09-25  # 4 A 6 2021-01-15  # 5 A 7 2021-01-15  # 6 A 105 2021-01-19  # 7 B 64 2020-05-20  # 8 B 2 2020-05-20  # 9 B 62 2021-06-20  # 10 C 2 2021-01-11  # 11 C 5 2021-01-13  # 12 C 1 2021-01-13  #desired result  # my_groups diff   # 1 A 100 (105 - 5)  # 2 B 2 (64 - 62)  # 3 C 1 (1 - 2)  

Уравнение внутри скобок desired result просто для того, чтобы показать, откуда diff оно взялось.

Любой намек на то, как я могу это сделать?

Комментарии:

1. разве А не должно быть 105-5 = 100 ?

2. и C 1 — 2 = -1 ?

3. Также.. как бы вы подошли к галстуку, как в C?

4. Для галстуков я возьму минимальную меру. Для этого я подумал о том, чтобы сначала упорядочить фрейм данных

Ответ №1:

Ваши данные образца data.frame не совпадают с выводом на консоль, поэтому результаты будут другими.

Два метода, в зависимости от нескольких факторов.

  1. Предполагая, что порядок контролируется извне,
     test1 %gt;%  group_by(my_groups) %gt;%  slice(c(1, n())) %gt;%  summarize(diff = diff(measure)) # # A tibble: 3 x 2 # my_groups diff # lt;chrgt; lt;dblgt; # 1 A 95 # 2 B -2 # 3 C 2  

    или просто

     test1 %gt;%  group_by(my_groups) %gt;%  summarize(diff = measure[n()] - measure[1])  

    Преимущество этого заключается в том, что это устраняет проблему с подходом 2 ниже (связь which.max ): если вы сами контролируете порядок, вы гарантированно используете первые/последние значения, которые вам нужны.

    ОБРАТИТЕ внимание, что для этой части я предполагаю, что порядок данных, которые вы предоставили нам в своих образцах данных, имеет значение. Я предполагаю, что есть какой-то способ гарантировать, что ваши результаты будут найдены. С вашим последним комментарием мы сможем arrange до подведения итогов и приблизиться к вашим желаемым результатам с помощью

     test1 %gt;%  arrange(time, -measure) %gt;% # this is the "external" sorting I mentioned, so we don't need which.min/.max  group_by(my_groups) %gt;%  summarize(diff = measure[n()] - measure[1]) # # A tibble: 3 x 2 # my_groups diff # lt;chrgt; lt;dblgt; # 1 A 100 # 2 B -2 # 3 C 2  
  2. Без предварительной сортировки мы можем использовать which.min и which.max . Проблема в том, что при возникновении связей он может выбрать не тот, который вам нужен.
     test1 %gt;%  group_by(my_groups) %gt;%  summarize(diff = measure[which.max(time)] - measure[which.min(time)]) # # A tibble: 3 x 2 # my_groups diff # lt;chrgt; lt;dblgt; # 1 A 100 # 2 B -2 # 3 C 3  

Комментарии:

1. ОП должен разъяснить, как обращаться с галстуком. Ваши решения возвращают два разных вывода для C. [однако я не понимаю, почему у вас два разных значения для A]

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

3. работает на меня! Спасибо, @r2evans!

4. @Edo, для протокола, мне не нравится тот факт, что различные методы здесь дают разные результаты. Мы не можем контролировать данные, мы можем работать только над предположениями и, надеюсь, четко фиксировать их. Спасибо за записку.

Ответ №2:

 test1 %gt;%  dplyr::group_by(my_groups) %gt;%  dplyr::mutate(  first = min(time), last = max(time),  ) %gt;%   dplyr::select(-time, -measure) %gt;%  dplyr::distinct() %gt;%  dplyr::mutate(diff = first - last) %gt;%  dplyr::select(-first, -last)  

Комментарии:

1. этот подход вернул разницу в датах