Как перевести столбец списка типов в широкий формат без использования dcast

#r #data.table #unnest

#r #данные.таблица #отменить

Вопрос:

У меня есть data.table со столбцом списка типов. Я хотел бы превратить этот столбец списка в новые столбцы в широком формате. Я могу использовать unlist , чтобы сначала создать длинный формат таблицы, а затем использовать dcast для приведения ее к широкому формату (хотя я использую исходный столбец списка в процессе, потому что dcast говорится, что Columns specified in formula can not be of type list

Пример:

У меня есть data.table вот так:

 dt = data.table(
  list_col = list(c(404, 444), c(404, 444), c(444,484), c(444, 484), c(364, 404)),
  other_col = c('A', 'B', 'D', 'E', 'A'))
  

Я могу сделать:

 # create a row id
dt[, row_id := .I]

# cast to wide
dcast(
  # replicate the data table, so that rows are matched properly when unlisting
  dt[
    rep(dt[,.I], lengths(list_col))
    ][
      ,
      # unlist the list column
      unlist_col := unlist(dt$list_col)
      ][
        ,
        # crate a row id per group so that we know how to cast to wide
        group_row_id := rowid(row_id)
        ][],
  # here i lose the original list_col, because i can't put the column of type list to the formula
  other_col   row_id ~ group_row_id, value.var = 'unlist_col')
  

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

Ответ №1:

Используя data.table::transpose() :

 dt[, c("col1", "col2") := transpose(list_col)]

#    list_col other_col col1 col2
# 1:  404,444         A  404  444
# 2:  404,444         B  404  444
# 3:  444,484         D  444  484
# 4:  444,484         E  444  484
# 5:  364,404         A  364  404
  

Ответ №2:

Если у вас одинаковое количество элементов в list_col, вы можете попробовать следующий код:

 > dt = cbind(dt, t(matrix(unlist(dt$list_col), ncol=nrow(dt))))
> dt
   list_col other_col  V1  V2
1:  404,444         A 404 444
2:  404,444         B 404 444
3:  444,484         D 444 484
4:  444,484         E 444 484
5:  364,404         A 364 404
  

Затем вы можете изменить названия вновь добавленных столбцов.