Как найти минимум по группам на основе условия, используя dplyr? - PullRequest
0 голосов
/ 30 марта 2020

Итак, у меня есть случайный фрейм данных, который можно создать с помощью этого кода

library(dplyr)
dates <- seq(as.Date("2015-01-01"),as.Date("2015-12-31"),1)
weekdays <- weekdays(dates)

res <- data.frame(dates,weekdays)

res$customer <- ifelse(dates > as.Date("2015-02-05"), "Google", "Apple")

res$order_flag <- ifelse(weekdays == "Wednesday", 1, 0)

Я пытаюсь создать флаг, равный единице, впервые order_flag==1 для каждого клиента. Конечный результат здесь будет иметь только два случая, когда этот новый флаг = 1. Я попытался сделать это в dplyr следующим образом:

new_data <- res %>% group_by(customer) %>% mutate(min_date = which.min(order_flag ==1)) 

, но, похоже, это не сработало.

Ответы [ 2 ]

2 голосов
/ 31 марта 2020

Создайте вектор из всех 0 с integer(n()), затем replace element which.max(order_flag == 1) с 1.

res %>% 
  group_by(customer) %>% 
  mutate(min_date = replace(integer(n()), which.max(order_flag == 1), 1))

#  # A tibble: 365 x 5
# # Groups:   customer [2]
#    dates      weekdays  customer order_flag min_date
#    <date>     <fct>     <chr>         <dbl>    <dbl>
#  1 2015-01-01 Thursday  Apple             0        0
#  2 2015-01-02 Friday    Apple             0        0
#  3 2015-01-03 Saturday  Apple             0        0
#  4 2015-01-04 Sunday    Apple             0        0
#  5 2015-01-05 Monday    Apple             0        0
#  6 2015-01-06 Tuesday   Apple             0        0
#  7 2015-01-07 Wednesday Apple             1        1
#  8 2015-01-08 Thursday  Apple             0        0
#  9 2015-01-09 Friday    Apple             0        0
# 10 2015-01-10 Saturday  Apple             0        0
# # ... with 355 more rows

Если у вас есть группы без любого order_flag, равного 1, which.max может иметь странное поведение

which.max(c(FALSE, FALSE, FALSE, FALSE))
# [1] 1

Чтобы предотвратить это, вот еще один вариант, который не имеет такой проблемы.

res %>% 
  group_by(customer) %>% 
  mutate(min_date = order_flag == 1,
         min_date = as.integer(min_date & cumsum(min_date) == 1))
0 голосов
/ 30 марта 2020

использовать ломтик:

new_data <- res %>% group_by(customer) %>% 
  filter(order_flag == 1) %>% 
  slice(1) %>% mutate(first_order= 1) %>% right_join(res)


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...