防止 data.table 将不同长度的向量列表强制转换为 data.table

问题描述 投票:0回答:1

data.table 中的(合理的)默认值似乎是尽可能保留列表中向量的矩形性质,根据需要重复单元素项,然后将结果强制到 data.table 中。

假设你有一个数据表

foo

foo <- data.table(
  a = c(1, 2, 3),
  b = c(TRUE, TRUE, FALSE)
)

你想要的是返回一个非 data.table 命名(不规则)列表,如下所示:

list(
  a = foo[(b), a],
  n = foo[(b), .N]
)

#$a
#[1] 1 2
#n
#[1] 2

我一直在以不同的方式处理列表列表,但我无法阻止 data.table 将 j 中返回的内容强制到 data.table 中(如果它能够这样做的话)。例如,这个:

foo[(b), {
  .(a = a,
    n = .N) 
}]

返回包含两行、列名称

a
n
的 data.table。

将其嵌套在另一个列表中可以将列表作为一列返回,并且没有名称:

foo[(b),
  .(.("a" = a,
      "n" = .N))
]

#     V1
# 1: 1,2
# 2:   2

无论如何,我觉得我错过了一些东西,但我已经没有办法搜索和阅读文档了。

我也有兴趣知道在对结果列表进行索引时拐点可能在哪里,因为也许这并不重要。如果列表中有一个长度为 1000 万的向量,旁边还有 100 个长度为 1 的向量,我认为不规则列表在内存方面比 data.table 更高效。但除了内存问题之外,这两个选项之一的计算效率是否更高:

bar_list$singleInt

# vs

bar_dt[1, singleInt]
r data.table
1个回答
0
投票
foo[(b), .(.("a" = a, "n" = .N)) ]
#        V1
#    <list>
# 1:    1,2
# 2:      2

它有

V1
作为名称,因为外部
.(..)
意味着返回一个新的列表/表,但由于您没有命名任何立即内部参数,因此它会自行命名。您可以使用

更改该行为
foo[(b), .(quux = .("a" = a, "n" = .N)) ]
#      quux
#    <list>
# 1:    1,2
# 2:      2

我还在我的 R 实例中设置了(默认情况下)

options(datatable.print.class=TRUE)
,这使我们可以看到这是一个列表列(正如您可能已经怀疑的那样)。这是一个列表,因为摘要中有 inner
.(.)

不幸的是,

data.table
默认将
list
参数中的任何
j=
返回转换为
data.table
(为了方便起见,请意识到
.(.)
list(.)
的同义词)。如果您想要一个参差不齐的列表,那么您需要超出正常的
data.table
语义。

with(foo[(b),],  list("a" = a, "n" = length(a)))
# $a
# [1] 1 2
# $n
# [1] 2

请注意,我们不能再使用

.N
特殊符号,尽管在这里使用
length(a)
非常便宜。

© www.soinside.com 2019 - 2024. All rights reserved.