如何在不使用 dcast 的情况下将类型列表的列取消嵌套为宽格式

How to unnest column of type list to wide format without using dcast

我有一个 data.table 类型列表的列。我想将此列表列变成宽格式的新列。我可以使用 unlist 首先创建 table 的长格式,然后使用 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 对结果 table 进行排序来修复我丢失列表列的事实只是将新列添加到原始 table,但如果有更直接的方法来进行此操作,那就太好了。

使用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

如果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

然后您可以更改新添加的列的名称。