问题描述
我有一个data.table
,其列的类型为list。我想将此列表列转换为宽格式的新列。我可以使用unlist
首先创建长格式的表格,然后使用dcast
将其转换为宽格式(尽管我在此过程中使用了原始列表列,因为dcast
表示Columns specified in formula can not be of type list
示例:
dt = data.table(
list_col = list(c(404,444),c(404,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对结果表进行排序并将新列添加到原始表中来修复丢失列表列的事实,但这确实是如果此操作有更简单的方法,那就很好。
解决方法
使用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
然后,您可以更改新添加的列的名称。