2017-01-23 161 views
1

我期待把一个数据框(或数据表),如如何将多个列转换为r中的列表类型列表?

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

@akrun,问题与您所链接的问题不同。我想要一个列表类型列的数据框,而不仅仅是一个列表。 (链接的答案返回一个列表,只需检查'dim(xy.list)') –

+0

这不是我。有人张贴可能的重复,我愚蠢的标签。这就是我所做的 – akrun

回答

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 

为了使@大卫的评论更加明确,并且推广了SE版本的data.table方法,它允许您将列名作为字符向量传递并避免了硬编码列名,您可以这样做,以了解更多关于SE和NSE的信息(可以参考到小品( “NSE”)):

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)]它使您更接近确切的期望输出。

+2

我认为这个答案的大部分听众不知道SE是什么;可能想要解释或提供参考。 – Frank

+0

伟大的答案@Psidom,谢谢! –

相关问题