Tidy R способ сохранить коллекцию или вектор для каждой строки в data.frame? - PullRequest
0 голосов
/ 27 февраля 2020

Как правильно хранить коллекцию (например, c(...)) для каждой записи / строки data.frame?

Пример

Предположим, у нас есть customers в датафрейм, и хотите добавить коллекцию покупок каждого клиента в блок данных клиента.


customers <- data.frame(customer_number=c(1,2,3), stringsAsFactors = F)

#   customer_number
# 1               1
# 2               2
# 3               3


transactions <- data.frame(customer_number=c(3,3,1,1,3),
                           item=c("milkshake", "burger", "apple", "fries", "water"),
                           stringsAsFactors = F)

#   customer_number      item
# 1               3 milkshake
# 2               3    burger
# 3               1     apple
# 4               1     fries
# 5               3     water

Клиент 1 купил вещи c('apple', 'fries'), клиент 2 ничего не купил, а клиент 3 купил вещи c('milkshake', 'burger', 'water')

Как лучше всего сохранить эти данные в таблице customers, то есть строго по одной строке на клиента?

Примечания

  • В основном пытается сохранить коллекцию (например, c(...)) для каждой строки data.frame.
  • Я решил сохранить коллекцию в виде строки, разделенной запятыми, что не кажется слишком разумным
  • Я подумал о создании большего количества строк (фактически left_join (транзакции, клиент), но данные имеют гораздо больше смысла, когда они сохраняются как один клиент на строку (поскольку все другие 20+ столбцов данных соответствуют этой структуре).
  • Следующим шагом будет анализ полученных результатов. data.frame (или структура данных), поэтому подход должен соответствовать этому варианту использования (преобразование в строки для этого не работает)

Ответы [ 2 ]

2 голосов
/ 27 февраля 2020

Мы можем хранить item как list.

library(dplyr)

transactions %>%
  group_by(customer_number) %>%
  summarise(item = list(item)) %>%
  right_join(customers, by = 'customer_number')

#  customer_number  item     
#            <dbl> <list>   
#1               1 <chr [2]>
#2               2 <NULL>   
#3               3 <chr [3]>

Тем не менее, я не нахожу неправильным хранение его как строки, разделенной запятыми, а также summarise(item = toString(item)), мы всегда можем привести ее в порядок, используя separate_rows позже, когда это необходимо.

1 голос
/ 28 февраля 2020

В devel-версии dplyr мы можем condense столбец и затем выполнить объединение

library(dplyr)
transactions %>% 
     group_by(customer_number) %>% 
     condense(item) %>% 
     right_join(customers)
# A tibble: 3 x 2
# Rowwise:  customer_number
#  customer_number item     
#*           <dbl> <list>   
#1               1 <chr [2]>
#2               3 <chr [3]>
#3               2 <NULL>   
...