首页 > 解决方案 > 避免 data.table 强制 j 中的列表返回一列

问题描述

假设我有以下data.table

library(data.table)

set.seed(20200210)

data <- data.table(
  x = 1:3,
  y = list(
    data.table(a=4:6, b=runif(3)),
    data.table(a=7:10, b=runif(4)),
    data.table(a=11:15, b=runif(5))
  )
)

data[]
##     x            y
##  1: 1 <data.table>
##  2: 2 <data.table>
##  3: 3 <data.table>

当我们查看y'sdata.tables时,我们得到以下内容

data[, y]
##  [[1]]
##     a         b
##  1: 4 0.1019356
##  2: 5 0.5566203
##  3: 6 0.7020533
##  
##  [[2]]
##      a         b
##  1:  7 0.6080464
##  2:  8 0.4421555
##  3:  9 0.5070702
##  4: 10 0.8181770
##  
##  [[3]]
##      a         b
##  1: 11 0.8444425
##  2: 12 0.5701193
##  3: 13 0.8412783
##  4: 14 0.5692414
##  5: 15 0.8402453

到目前为止,一切正常。我接下来要做的是a+b对每个执行操作并使用语法data.table检索结果。直觉上,我会写以下listdata.table

data[, lapply(y, function(z){
  z[, a+b]
})]
##           V1        V2       V3
##  1: 4.101936  7.608046 11.84444
##  2: 5.556620  8.442156 12.57012
##  3: 6.702053  9.507070 13.84128
##  4: 4.101936 10.818177 14.56924
##  5: 5.556620  7.608046 15.84025
##  Warning messages:
##  1: In as.data.table.list(jval, .named = NULL) :
##    Item 1 has 3 rows but longest item has 5; recycled with remainder.
##  2: In as.data.table.list(jval, .named = NULL) :
##    Item 2 has 4 rows but longest item has 5; recycled with remainder.

但它不会工作。我的理解是,由于 mylapply将返回 alist并且它在内部定义,因此即使结果长度不同data.table[],它也会强制返回为一列。data.table对我来说,这种行为是不可取的。我认为只有在长度匹配时才应将结果简化为一列。

但是,以下内容实际上会起作用

lapply(data$y, function(z){
  z[, a+b]
})
##  [[1]]
##  [1] 4.101936 5.556620 6.702053
##  
##  [[2]]
##  [1]  7.608046  8.442156  9.507070 10.818177
##  
##  [[3]]
##  [1] 11.84444 12.57012 13.84128 14.56924 15.84025

data.table但如果可以访问该data对象,我宁愿使用语法。

有什么提示吗?

标签: rdata.table

解决方案


它试图转换为单列,但list元素的长度不同。我们可以把它包装在一个list

data[, lapply(y, function(z) list(z[,  a + b]))]

或者,如果我们需要与输入中相同的结构,请在lapply

out <- data[, list(lapply(y, function(z) z[, .(a +b)]))]
out
#           V1
#1: <data.table>
#2: <data.table>
#3: <data.table>

或者也可以

data[, .(lapply(y, function(z) z[, a +b]))]
#                                             V1
#1:                   4.101936,5.556620,6.702053
#2:       7.608046, 8.442156, 9.507070,10.818177
#3: 11.84444,12.57012,13.84128,14.56924,15.84025

推荐阅读