使用列表列聚合data.frame

时间:2016-09-12 18:57:07

标签: r

有一列包含data.frame每行中的向量。我想聚合和组合向量。但是,似乎我不能用这种数据做到这一点。你会如何组合这些载体?

"错误:变量的类型(列表)无效' dv'"

#Problem: aggregate data.frame with list-column

#reproducible code
set.seed(1)
some_list <- replicate(40, sample(c(1:8), size=sample(1:6, 1), replace=TRUE))
exdf <- expand.grid(id=c(1:10), content=c(1:4))
exdf$dv <- some_list


#this throws error
aggregate(
formula=dv~id,
data=exdf,
FUN=c
)

2 个答案:

答案 0 :(得分:2)

您可以使用unlistlist进行library(dplyr) df1 <- exdf %>% group_by(id) %>% summarise(dv = list(unlist(dv))) df1 # Source: local data frame [10 x 2] # id dv # <int> <list> #1 1 <int [13]> #2 2 <int [15]> #3 3 <int [13]> #4 4 <int [15]> #5 5 <int [13]> #6 6 <int [15]> #7 7 <int [13]> #8 8 <int [15]> #9 9 <int [13]> #10 10 <int [15]> df1$dv[[1]] # [1] 3 5 2 6 4 7 8 2 6 2 7 3 4 汇总:

data.table

或者library(data.table) setDT(exdf)[, .(list(unlist(dv))), id] # id V1 # 1: 1 3,5,2,6,4,7, # 2: 2 2,8,8,6,6,1, # 3: 3 2,6,4,7,8,2, # 4: 4 7,4,6,4,1,4, # 5: 5 4,7,8,2,6,2, # 6: 6 4,1,4,2,7,6, # 7: 7 7,3,4,3,5,2, # 8: 8 4,2,7,6,2,8, # 9: 9 3,5,2,6,4,7, #10: 10 2,8,8,6,6,1,

HTML

答案 1 :(得分:1)

这里我们使用一些不可读的基础R.如果使用dplyr管道使代码可读,不妨使用group/summarise

data.frame(id = unique(exdf$id),
           dv = cbind(lapply(split(exdf, exdf$id),
                             function(x) unlist(x$dv))))

   id                                                      dv
1   1                   3, 5, 6, 4, 7, 4, 2, 1, 6, 5, 5, 8, 5
2   2    2, 8, 8, 6, 6, 1, 1, 7, 7, 4, 4, 7, 5, 5, 2, 3, 6, 4
3   3                            2, 6, 5, 6, 3, 3, 8, 6, 6, 1
4   4                7, 4, 6, 8, 3, 4, 2, 4, 5, 5, 3, 4, 5, 2
5   5    4, 7, 8, 2, 6, 2, 6, 3, 5, 8, 6, 3, 4, 2, 1, 3, 2, 3
6   6                      4, 1, 7, 1, 8, 6, 4, 7, 8, 4, 1, 3
7   7                      7, 3, 4, 7, 3, 3, 4, 3, 6, 7, 7, 4
8   8                4, 2, 7, 6, 8, 7, 4, 8, 4, 4, 2, 8, 6, 6
9   9 1, 6, 4, 7, 6, 8, 4, 6, 4, 3, 4, 5, 2, 2, 5, 8, 3, 2, 8
10 10    5, 5, 7, 1, 4, 2, 6, 1, 2, 2, 1, 1, 6, 8, 8, 2, 7, 6

如果我们已经开始使用&#39; aggregate&#39;,您可以通过将数字列表更改为字符来执行以下操作。然后使用正则表达式提取这些数字。

exdf$dv <- as.character(exdf$dv)
aggregate(
  formula=dv~id,
  data=exdf,
  FUN = function(x) regmatches(paste0(x, collapse = ""),
                               gregexpr('[0-9]', paste0(x, collapse = ""))))

   id                                                      dv
1   1                   3, 5, 6, 4, 7, 4, 2, 1, 6, 5, 5, 8, 5
2   2    2, 8, 8, 6, 6, 1, 1, 7, 7, 4, 4, 7, 5, 5, 2, 3, 6, 4
3   3                            2, 6, 5, 6, 3, 3, 8, 6, 6, 1
4   4                7, 4, 6, 8, 3, 4, 2, 4, 5, 5, 3, 4, 5, 2
5   5    4, 7, 8, 2, 6, 2, 6, 3, 5, 8, 6, 3, 4, 2, 1, 3, 2, 3
6   6                      4, 1, 7, 1, 8, 6, 4, 7, 8, 4, 1, 3
7   7                      7, 3, 4, 7, 3, 3, 4, 3, 6, 7, 7, 4
8   8                4, 2, 7, 6, 8, 7, 4, 8, 4, 4, 2, 8, 6, 6
9   9 1, 6, 4, 7, 6, 8, 4, 6, 4, 3, 4, 5, 2, 2, 5, 8, 3, 2, 8
10 10    5, 5, 7, 1, 4, 2, 6, 1, 2, 2, 1, 1, 6, 8, 8, 2, 7, 6