Управляйте значениями в разных столбцах, выполняя операции построчно - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть некоторые данные, содержащие информацию о бронировании номера в отеле, которая выглядит следующим образом:

   user_id h_name h_capacity check_in_date check_out_date
         1     A1          2    2019-01-01     2019-01-05
         2     A1          2    2019-01-02     2019-01-05
         3     A1          2    2019-01-02     2019-01-03
         4     A2          3    2019-01-02     2019-01-04
         5     A2          3    2019-01-04     2019-01-05

user_id: идентификатор клиента

h_name: название отеля

h_capacity: максимальное количество номеров в отеле.

check_in_date & check_out_date: не требует пояснений.

Моя цель - выяснить, какие отелипроверка людей на предмет их предписанной вместимости.

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

    <...> 2019-01-01 2019-01-02 2019-01-03 2019-01-04 2019-01-05
    <...>          0          0          0          0          0
    <...>          0          0          0          0          0
    <...>          0          0          0          0          0
    <...>          0          0          0          0          0
    <...>          0          0          0          0          0

<...> представляет столбцы, которые присутствуют в первом кадре данных, показанном вверху.

После выполнения вышесказанного я хочу вставить цифру 1 в столбцы дат, в которые пользователь проживает в отеле. Результат будет выглядеть следующим образом:

    <...> 2019-01-01 2019-01-02 2019-01-03 2019-01-04 2019-01-05
    <...>          1          1          1          1          1
    <...>          0          1          1          1          1
    <...>          0          1          1          0          0
    <...>          0          1          1          1          0
    <...>          0          0          0          1          1

<...> представляет столбцы, которые присутствуют в образце, показанном вверху.

И в конце я бы просто использовал суммирование для h_name, чтобы получить общее количество занятых коек в день.

Проблема в том, что я не могу заполнить фрейм данных, как показано выше, значением 1 в столбцах дат, когда человек занял комнату. Это включает в себя заполнение значения в разные столбцы для каждой строки, что означает, что для пользователя мне нужно будет вставить 1 в столбцы, представляющие даты, в которые они останавливались в отеле. Я не мог понятьМы нашли оптимальное решение для этого и в итоге использовали цикл for, выполнение которого заняло 32 минуты.

Я скромно требую оптимального решения для этого.(Обратите внимание: данные имеют 500 тыс. Строк)

1 Ответ

3 голосов
/ 24 апреля 2019

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

library(tidyverse)

hotel_data %>% 
  gather(check_in, date, check_in_date, check_out_date) %>% 
  group_by(h_name, h_capacity, user_id) %>% 
  complete(date = seq.Date(first(date), last(date), by = "day"), 
           fill = list(check_in = "stay")) %>% 
  group_by(h_name, date) %>% 
  mutate(people = n()) %>% 
  filter(people > h_capacity)

# A tibble: 6 x 6
# Groups:   h_name, date [2]
#   h_name h_capacity user_id date       check_in       people
#   <chr>       <dbl>   <dbl> <date>     <chr>           <int>
# 1 A1              2       1 2019-01-02 stay                3
# 2 A1              2       1 2019-01-03 stay                3
# 3 A1              2       2 2019-01-02 check_in_date       3
# 4 A1              2       2 2019-01-03 stay                3
# 5 A1              2       3 2019-01-02 check_in_date       3
# 6 A1              2       3 2019-01-03 check_out_date      3

Объяснение
Сначала я преобразую ваши данные в длинный формат с помощью gather, после чего легко заполнить пропущенные значения даты для каждой группы (отель и пользователь) с помощью complete. Затем, группируя только по отелю и дате, я считаю количество людей и фильтрую по тем, которые превышают вместимость.

Данные

hotel_data <- structure(list(user_id = c(1, 2, 3, 4, 5), 
                             h_name = c("A1", "A1", "A1", "A2", "A2"), 
                             h_capacity = c(2, 2, 2, 3, 3), 
                             check_in_date = structure(c(17897, 17898, 17898, 17898, 17900), class = "Date"), 
                             check_out_date = structure(c(17901, 17901, 17899, 17900, 17901), class = "Date")), 
                        class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -5L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...