我希望转换数据帧(或数据表),例如
dt <- data.table(a = c(1,2,4), b = c(NA,3,5), d = c(NA,8,NA))
进入具有一列的内容,例如
dt <- data.table(combined = list(list(1,NA,NA),list(2,3,8),list(4,5,NA))
以下工作均无效:
dt[,combined := as.list(a,b,d)]
dt[,combined := do.call(list,list(a,b,d))]
dt[,combined := cbind(a,b,d)]
dt[,combined := lapply(list(a,b,d),list)]
请注意,这与此处的问题data.frame rows to a list不同,后者返回不同形状的对象(我认为它只是一个普通列表,每行都是列表中的项目,而不是列表向量)
答案 0 :(得分:5)
您可以使用purrr::transpose()
,将矢量列表转换为列表列表:
dt[, combined := purrr::transpose(.(a,b,d))]
dt
# a b d combined
#1: 1 NA NA <list>
#2: 2 3 8 <list>
#3: 4 5 NA <list>
combined = list(list(1,NA_real_,NA_real_),list(2,3,8),list(4,5,NA_real_))
identical(dt$combined, combined)
# [1] TRUE
如果您不想使用额外的套餐,可以稍加努力地使用data.table::transpose
:
dt[, combined := lapply(transpose(.(a,b,d)), as.list)]
identical(dt$combined, combined)
# [1] TRUE
让@ David的评论更加明确,并将data.table方法概括为SE版本,它允许您将列名作为字符向量传递并避免硬编码列名,您可以这样做,以便学习更多关于SE vs NSE(你可以参考小插图(&#34; nse&#34;)):
dt[, combined := lapply(transpose(.SD), as.list), .SDcols = c("a","b","d")]
这使得所有子列表都被命名,但这些值对应于组合列表:
identical(lapply(dt$combined, setNames, NULL), combined)
# [1] TRUE
如果您不想使用任何功能:
dt[, combined := .(.(.SD)), by = 1:nrow(dt)]
# because you want to transform each row to a list, normally you can group the data frame
# by the row id, and turn each row into a list, and store the references in a new list
# which will be a column in the resulted data.table
dt$combined
#[[1]]
# a b d
#1: 1 NA NA
#[[2]]
# a b d
#1: 2 3 8
#[[3]]
# a b d
#1: 4 5 NA
或者:dt[, combined := .(.(.(a,b,d))), by = 1:nrow(dt)]
使您更接近确切的所需输出。