#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
не совпадают с выводом на консоль, поэтому результаты будут другими.
Два метода, в зависимости от нескольких факторов.
- Предполагая, что порядок контролируется извне,
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
- Без предварительной сортировки мы можем использовать
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. этот подход вернул разницу в датах