R 如何在data.table中将多个列有效地分组到一个列表列中

R 如何在data.table中将多个列有效地分组到一个列表列中,r,data.table,R,Data.table,您好,我有一个包含多个列的表,我想将它们全部“分组”到一列列表中,每一行将包含同一行上“分组”列的所有值的列表 是否有一种使用data.table执行此操作的快速方法 我怎样才能“解组” 示例(慢) 这里有一个用于base R中的data.frame的解决方案,但我相信它也适用于data.table: df <- data.frame(IDX = 1:101, x_1 = 1:101, x_2 = 101:201, x_3 = 201:301, y_1 = 1:101, y_2 = 1

您好,我有一个包含多个列的表,我想将它们全部“分组”到一列列表中,每一行将包含同一行上“分组”列的所有值的列表

  • 是否有一种使用data.table执行此操作的快速方法
  • 我怎样才能“解组”
示例(慢)


这里有一个用于
base R
中的
data.frame
的解决方案,但我相信它也适用于
data.table

df <- data.frame(IDX = 1:101, x_1 = 1:101, x_2 = 101:201, x_3 = 201:301, y_1 = 1:101, y_2 = 101:201)

res <- data.table(df[,1], Reduce(rbind,apply(df[,-1], 1, function(v) {
  data.table(x = list(as.numeric(v[grep("x",names(v))])), y = list(as.numeric(v[grep("y",names(v))])))
})))
数据:

以致

> head(res)
  IDX         x     y
1   1 1,101,201 1,101
2   2 2,102,202 2,102
3   3 3,103,203 3,103
4   4 4,104,204 4,104
5   5 5,105,205 5,105
6   6 6,106,206 6,106
> res
     IDX           x       y
  1:   1   1,101,201   1,101
  2:   2   2,102,202   2,102
  3:   3   3,103,203   3,103
  4:   4   4,104,204   4,104
  5:   5   5,105,205   5,105
 ---                        
 97:  97  97,197,297  97,197
 98:  98  98,198,298  98,198
 99:  99  99,199,299  99,199
100: 100 100,200,300 100,200
101: 101 101,201,301 101,201
数据:


dt这里有一个解决方案,用于
base R
中的
data.frame
,但我相信它也适用于
data.table

df <- data.frame(IDX = 1:101, x_1 = 1:101, x_2 = 101:201, x_3 = 201:301, y_1 = 1:101, y_2 = 101:201)

res <- data.table(df[,1], Reduce(rbind,apply(df[,-1], 1, function(v) {
  data.table(x = list(as.numeric(v[grep("x",names(v))])), y = list(as.numeric(v[grep("y",names(v))])))
})))
数据:

以致

> head(res)
  IDX         x     y
1   1 1,101,201 1,101
2   2 2,102,202 2,102
3   3 3,103,203 3,103
4   4 4,104,204 4,104
5   5 5,105,205 5,105
6   6 6,106,206 6,106
> res
     IDX           x       y
  1:   1   1,101,201   1,101
  2:   2   2,102,202   2,102
  3:   3   3,103,203   3,103
  4:   4   4,104,204   4,104
  5:   5   5,105,205   5,105
 ---                        
 97:  97  97,197,297  97,197
 98:  98  98,198,298  98,198
 99:  99  99,199,299  99,199
100: 100 100,200,300 100,200
101: 101 101,201,301 101,201
数据:


dt您可以执行以下操作。虽然所有变量都保存在该解决方案中,但您当然可以只为列
IDX,X和Y
的最终
DT
子集,即
DT[,(IDX,X,Y)]

代码

xcols = colnames(DT)[colnames(DT) %like% 'x']
ycols = colnames(DT)[colnames(DT) %like% 'y']

DT[, X := lapply(IDX, function(x){
  lapply(xcols, function(y) DT[x, get(y)])
})]

DT[, Y := lapply(IDX, function(x){
  lapply(ycols, function(y) DT[x, get(y)])
})]
输出

> dput(head(DT))

structure(list(x_1 = 1:6, x_2 = 101:106, x_3 = 201:206, y_1 = 1:6, 
               y_2 = 101:106, IDX = 1:6, 
               X = list(list(1L, 101L, 201L), list(2L, 102L, 202L), list(3L, 103L, 203L), list(4L, 104L, 204L), list(5L, 105L, 205L), list(6L, 106L, 206L)), 
               Y = list(list(1L, 101L), list(2L, 102L), list(3L, 103L), list(4L, 104L), list(5L, 105L), list(6L, 106L))), row.names = c(NA, -6L), 
               class = c("data.table", "data.frame"), 
              .Names = c("x_1", "x_2", "x_3", "y_1", "y_2", "IDX", "X", "Y"))

您可以执行以下操作。虽然所有变量都保存在该解决方案中,但您当然可以只为列
IDX,X和Y
的最终
DT
子集,即
DT[,(IDX,X,Y)]

代码

xcols = colnames(DT)[colnames(DT) %like% 'x']
ycols = colnames(DT)[colnames(DT) %like% 'y']

DT[, X := lapply(IDX, function(x){
  lapply(xcols, function(y) DT[x, get(y)])
})]

DT[, Y := lapply(IDX, function(x){
  lapply(ycols, function(y) DT[x, get(y)])
})]
输出

> dput(head(DT))

structure(list(x_1 = 1:6, x_2 = 101:106, x_3 = 201:206, y_1 = 1:6, 
               y_2 = 101:106, IDX = 1:6, 
               X = list(list(1L, 101L, 201L), list(2L, 102L, 202L), list(3L, 103L, 203L), list(4L, 104L, 204L), list(5L, 105L, 205L), list(6L, 106L, 206L)), 
               Y = list(list(1L, 101L), list(2L, 102L), list(3L, 103L), list(4L, 104L), list(5L, 105L), list(6L, 106L))), row.names = c(NA, -6L), 
               class = c("data.table", "data.frame"), 
              .Names = c("x_1", "x_2", "x_3", "y_1", "y_2", "IDX", "X", "Y"))

这里有一种方法依赖于将矩阵按行拆分的
asplit()

DT[, X := asplit(as.matrix(.SD), 1), .SDcols = grep('x', names(DT))]
DT[, Y := asplit(as.matrix(.SD), 1), .SDcols = grep('y', names(DT))]

它的性能可能与@ThomasIsCoding

类似。这里有一种方法依赖于将矩阵按行拆分的
asplit()

DT[, X := asplit(as.matrix(.SD), 1), .SDcols = grep('x', names(DT))]
DT[, Y := asplit(as.matrix(.SD), 1), .SDcols = grep('y', names(DT))]

它可能具有与@ThomasIsCoding

@statquant类似的性能。例如,您是说,
x
字段中的
列表中的“1101201”
?如果数据是真实大小,恐怕这会非常慢:(@statquant是的,这是真的。由于
apply()的原因,使用大数据集时我会非常慢)
…我将尝试找到其他solution@statquant您可以在
更新2
中尝试该解决方案,这可能非常有用faster@statquant您的意思是,例如,“1101201”作为字段
x
中的
列表
?如果数据是真实大小,恐怕速度会非常慢:(@statquant是的,这是真的。由于
apply()的原因,我在处理大数据集时会非常慢)
…我将尝试找到其他solution@statquant您可以在
更新2
中尝试该解决方案,该解决方案可能会更快。该解决方案的最终用途是什么?嵌套和取消测试总是会影响性能。该解决方案的最终用途是什么?嵌套和取消测试总是会影响性能。