R - Как сохранить типы данных и заголовки при преобразовании списка списков во фрейм данных - PullRequest
0 голосов
/ 12 марта 2020

Я работаю со списком receipts списков. Каждая запись в receipts содержит список, представляющий квитанцию. Структура квитанции является последовательной и выглядит следующим образом.

> str(receipts[[1]])
List of 6
 $ receipt_type  : chr "SALESPERSON_ACTIVITY"
 $ timestamp     : POSIXct[1:1], format: "2020-01-01 09:29:00"
 $ receipt_number: int 1195
 $ POS           : int 1
 $ KNo           : int 12
 $ shift_number  : int 9

receipt_number может также содержать значения NA.

Я хотел бы преобразовать этот список в кадр данных с соответствующими столбцами (receipt_type, timestamp, receipt_number и др. c ..). В настоящее время я использую это

receipts_as_df <- as.data.frame(matrix(unlist(receipts), byrow=TRUE, ncol=length(receipts[[1]])))

Это помещает данные в кадр данных. К сожалению, unlist удаляет всю информацию о типах данных (я думаю, что все приведено к character). Кроме того, имена столбцов также теряются. Таким образом, у меня есть фрейм данных со всеми данными, но типы и имена столбцов теряются.

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

Пример: В настоящее время фрейм данных выглядит следующим образом

> head(receipts_as_df)
                        V1         V2   V3 V4 V5 V6
1     SALESPERSON_ACTIVITY 1577867340 1195  1 12  9
2 CASH_REGISTER_MONITORING 1577867340 <NA>  1 12  9
3      PAYOUT_NOTIFICATION 1577867340 1196  1 12  9
4             TSE_ACTIVITY 1577869080 <NA>  1 12  9
5   BUSINESS_MODE_ACTIVITY 1577869080 <NA>  1 12  9
6             ZERO_RECEIPT 1577869140 1197  1 12  9

1 Ответ

1 голос
/ 12 марта 2020

Base R, требуется немного больше работы:

receipts <- replicate(3, list(
  receipt_type   = "SALESPERSON_ACTIVITY",
  timestamp      = as.POSIXct("2020-01-01 09:29:00", tz = "UTC"),
  receipt_number = 1195,
  POS            = 1,
  KNo            = 12,
  shift_number   = 9
), simplify = FALSE)

out <- do.call(rbind.data.frame, c(receipts, list(stringsAsFactors = FALSE)))
out
#            receipt_type  timestamp receipt_number POS KNo shift_number
# 2  SALESPERSON_ACTIVITY 1577870940           1195   1  12            9
# 21 SALESPERSON_ACTIVITY 1577870940           1195   1  12            9
# 3  SALESPERSON_ACTIVITY 1577870940           1195   1  12            9
str(out)
# 'data.frame': 3 obs. of  6 variables:
#  $ receipt_type  : chr  "SALESPERSON_ACTIVITY" "SALESPERSON_ACTIVITY" "SALESPERSON_ACTIVITY"
#  $ timestamp     : num  1.58e+09 1.58e+09 1.58e+09
#  $ receipt_number: num  1195 1195 1195
#  $ POS           : num  1 1 1
#  $ KNo           : num  12 12 12
#  $ shift_number  : num  9 9 9
out$timestamp <- as.POSIXct(out$timestamp, origin = "1970-01-01")
out
#            receipt_type           timestamp receipt_number POS KNo shift_number
# 2  SALESPERSON_ACTIVITY 2020-01-01 01:29:00           1195   1  12            9
# 21 SALESPERSON_ACTIVITY 2020-01-01 01:29:00           1195   1  12            9
# 3  SALESPERSON_ACTIVITY 2020-01-01 01:29:00           1195   1  12            9

dplyr и data.table без дополнительной работы:

dplyr::bind_rows(receipts)
# # A tibble: 3 x 6
#   receipt_type         timestamp           receipt_number   POS   KNo shift_number
#   <chr>                <dttm>                       <dbl> <dbl> <dbl>        <dbl>
# 1 SALESPERSON_ACTIVITY 2020-01-01 09:29:00           1195     1    12            9
# 2 SALESPERSON_ACTIVITY 2020-01-01 09:29:00           1195     1    12            9
# 3 SALESPERSON_ACTIVITY 2020-01-01 09:29:00           1195     1    12            9
data.table::rbindlist(receipts)
#            receipt_type           timestamp receipt_number POS KNo shift_number
# 1: SALESPERSON_ACTIVITY 2020-01-01 09:29:00           1195   1  12            9
# 2: SALESPERSON_ACTIVITY 2020-01-01 09:29:00           1195   1  12            9
# 3: SALESPERSON_ACTIVITY 2020-01-01 09:29:00           1195   1  12            9
...