Подсчет разных групп в одном утверждении в г - PullRequest
1 голос
/ 22 февраля 2020

Предположим, у меня есть этот фрейм данных df

df <- data.frame("City" = c("Boston", "Boston","Boston", "Boston","Boston", "Boston",
                        "Boston", "Boston", "Boston", "New York", "New York", "New York" ),
             "Store_ID" = c("00002", "00002", "00002", "00002", "00004", "00004",
                            "00004", "00004", "00004", "00011", "00011", "00011"),
             "Customer_ID" = c("10001", "10001", "10001", "23847", "17823", "17823",
                               "17823", "17823", "17823", "24232", "24232", "27381"),
             "Product_ID" = c ("00013", "00013", "00058", "00013", "00899", "00847",
                               "00065", "00065", "00065", "00096", "00085", "00175"),
             "Payment" = c("Cash", "Cash", "Cash", "Card", "Card", "Card", "Card", 
                           "Card", "Card", "Card", "Card", "Cash"))

Допустим, я хочу знать, сколько продуктов было продано в каждом городе; тогда я бы использовал этот код

df2 <- df %>% group_by(City) %>% summarise(Quantity = (n))

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

df2 <- df %>% group_by(City, Store_ID) %>% summarise(Quantity = (n))

Однако это дополнительно разбивает фрейм данных, и теперь я не вижу общего количества продуктов, проданных в каждом городе. Можно ли создать новый фрейм данных, который содержит количество различных групп, но сгруппирован только по более всеобъемлющей переменной, такой как Город или Магазин.

Пример вывода, который я ищу только для Store00002, будет выглядеть так:

Store  Total_Sales   Customer10001_purchases    Customer23847_purchases   Cash% (ratio of items paid in cash)
00002           4                         3                          1      0.75

Возможно ли сделать это через dplyr? Я также открыт для любых других предложений. Очень ценю помощь!

Ответы [ 2 ]

4 голосов
/ 22 февраля 2020

Если вы хотите сохранить исходные данные и просто добавить суммы, используйте mutate вместо суммирования. Так что это может выглядеть примерно так:

df1 <- df %>% 
  group_by(City) %>% 
  mutate(sales_city = n())%>% 
  ungroup() %>% 
  group_by(City, Store_ID) %>% 
  mutate(sales_store = n()) %>% 
  ungroup() %>% 
  group_by(City,Store_ID, Customer_ID) %>% 
  mutate(sales_by_customer = n()) %>% 
  ungroup() %>% 
  select(-Product_ID, -Payment) %>% 
  distinct()

Обратите внимание, что я использовал ваши примеры количества продуктов, продаваемых по городам и магазинам. Однако у вашего окончательного фрейма данных было еще несколько столбцов, поэтому я добавил еще один пример того, как он может выглядеть. Являются ли эти (n () везде) точной статистикой, которую вы хотите получить - это то, что вам решать.

Это даст следующий результат:

  City     Store_ID Customer_ID sales_city sales_store sales_by_customer
1 Boston   00002    10001                9           4                 3
2 Boston   00002    23847                9           4                 1
3 Boston   00004    17823                9           5                 5
4 New York 00011    24232                3           3                 2
5 New York 00011    27381                3           3                 1

Я не думаю, что вам нужна разгруппировка каждый раз, как вы делаете подобную группировку. Но всегда безопаснее просто включить его.

0 голосов
/ 22 февраля 2020

Ваш требуемый вывод имеет три набора информации:

  1. Общий объем продаж,
  2. Индивидуальные покупки клиентов (в широком формате),
  3. Пропорция (отношение?) около 1041 * продаж.

Я полагаю, что для этого требуются три отдельных «запроса» к данным, с результатами, объединенными в Store_ID (или City, если хотите, но мой код делает это для Store_ID).

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

Я сделаю это по одному шагу за раз:


SALES <- df %>% 
  group_by(Store_ID) %>%
  summarise(Total_sales = n())

Редактировать : Новый запрос для включения магазинов, у которых не было продаж sh:

CASH <- df %>%
  group_by(Store_ID, Payment) %>%
  summarise(n = n()) %>%
  pivot_wider(names_from=Payment, values_from=n, 
              values_fill = list(n = 0)) %>%
  mutate(`Cash%` = Cash/(Card+Cash)) %>%
  select(-Card, -Cash)

Старый запрос, игнорирующих магазины без Ca sh продаж:

CASH_wrong <- df %>% 
  group_by(Store_ID, Payment) %>%
  summarise(n = n()) %>%
  mutate(`Cash%` = n/sum(n)) %>%
  filter(Payment=="Cash") %>%
  select(-n, -Payment)

CUSTOMERS <- df %>% 
  group_by(Store_ID, Customer_ID) %>%
  summarise(Total_sales = n()) %>%
  pivot_wider(names_from = Customer_ID, values_from=Total_sales, names_prefix="customer")

Объедините все 3 в Store_ID, чтобы получить желаемый результат.

inner_join(SALES, CUSTOMERS, by="Store_ID") %>%
  inner_join(CASH, by="Store_ID") %>%
  filter(Store_ID=="00002") %>%  # Choose the store here.
  select_if(!is.na(.))

# A tibble: 1 x 6
  Store_ID Total_sales customer10001 customer23847 `Cash%`
  <fct>          <int>         <int>         <int>   <dbl>
1 00002              4             3             1    0.75

inner_join(SALES, CUSTOMERS, by="Store_ID") %>%
  inner_join(CASH, by="Store_ID") %>%
  filter(Store_ID=="00004") %>%  # Choose the store here.
  select_if(!is.na(.))

# A tibble: 1 x 4
  Store_ID Total_sales customer17823 `Cash%`
  <fct>          <int>         <int>   <dbl>
1 00004              5             5       0
...