当j的整体结果是列表时,我们是否需要将j的单个元素转换为列表?

时间:2017-05-15 12:49:00

标签: r data.table

背景

data.table的基本属性是

  

“只要j返回一个列表,列表中的每个元素就会成为结果data.table中的一列。”

这显示为例如在?data.table的示例中:

library(data.table)
DT[, c(.N, lapply(.SD, sum)), by=x]

此处整数.N clapply生成的列表相关联,整体结果为列表,即.N 隐式强制转换为列表元素(根据?c

中描述的强制层次结构

引起我注意的是?data.table.SD中使用的示例,与上文相比,j的“非列表”部分明确< / em>转换为列表:

DT[, c(.(y=max(y)), lapply(.SD, min)), by=rleid(v), .SDcols=v:b]

对于我来说,为什么在此示例中将y=max(y)生成的单个数字转换为列表(.())时无论如何都会转换为列表元素,跟随{带有列表的{1}} oncatenation(c)。

不需要显式lapply(.SD.,

以下是一个小例子,其中所有变量的listmax(y)由分组变量计算。在将sum中的“非列表”结果显式转换为列表时,以及不执行此操作时,str结构和计算结果确实相同:

j

因此,在这些示例中,将dt <- data.table(grp = rep(c("a", "b"), 2:3), x = 1:5, y = 2:6) # - structure of j dt[ , str(c(.(ymax = max(y)), lapply(.SD, sum))), by = grp] dt[ , str(c(ymax = max(y), lapply(.SD, sum))), by = grp] # - result of j dt[ , c(.(ymax = max(y)), lapply(.SD, sum)), by = grp] dt[ , c(ymax = max(y), lapply(.SD, sum)), by = grp] # ...both give the same result: 的非列表部分显式转换为列表似乎是多余的。真的需要吗?或许j的下一个示例提供了线索。

{h1> .N需要明确的list

在这种情况下,.N的'非列表'部分是j,否则.N与上述相同。

j的{​​{1}}结构相同,无论是否str明确转换为j中的列表:

.N

~~&gt; 请注意,根据j,在这两种情况下,“dt[ , str(c(.(n = .N), lapply(.SD, sum))), by = grp] dt[ , str(c(n = .N, lapply(.SD, sum))), by = grp] # List of 3 # $ n: int 2 # $ x: int 3 # $ y: int 5 # List of 3 # $ n: int 3 # $ x: int 12 # $ y: int 15 变量”都具有在str中设置的名称, N”。

但是,如果.N中的j未明确“.N”,则list的名称仍为默认“N”(请参阅​​j )在结果中:

.N

问题

当然,我的问题不是试图避免输入三个字符?.N,而是要了解{/ 1}}可以/应该如何指定的基本原理。

默认名称dt[ , c(.(n = .N), lapply(.SD, sum)), by = grp] # grp n x y # 1: a 2 3 5 # 2: b 3 12 15 dt[ , c(n = .N, lapply(.SD, sum)), by = grp] # grp N x y # 1: a 2 3 5 # 2: b 3 12 15 (如上所示)是保证使用显式.()的例外,总是为了安全起见吗?还有其他陷阱我忽略了吗?

1 个答案:

答案 0 :(得分:3)

首先,感谢@Frank指出.N名称的行为可能是一个错误。虽然这是一个小问题(posted one though),但我确实认为这是list j中使用.N更为笼统的原因。

我对.N及其名称进行了一些简单的测试,这表明存在一些潜在的不一致性。 FWIW,我想我也可以在这里分享它们(评论太久了)。

1:结果中的.N名称

1a:.N已自动发布&#39; N&#39;何时(1)仅使用.N,(2)by使用.N,或(3)lapply使用by.N。< / p>

1b:.N是自动发布的&#39; V1&#39;而不是&#39; N&#39;使用(1)lapplylist(.N),或(2)lapply# 1a: .N is autonamed 'N' # .N only dt[ , .(.N)] # N # 1: 5 # .N + by dt[ , .(.N), by = grp] # grp N # 1: a 2 # 2: b 3 # .N + lapply + by dt[ , c(.N, lapply(.SD, max)), by = grp] # grp N x y # 1: a 2 2 3 # 2: b 3 5 6 # 1b: .N is autonamed V1, instead of N # .N + lapply dt[ , c(.N, lapply(.SD, max))] # V1 grp x y # 1: 5 b 5 6 # list(.N) + lapply d[ , c(.(.N), lapply(.SD, max))] # V1 grp x y # 1: 5 2 5 10

.N

2:重命名list(.N)

2a:.Nlapply

一起使用时不需要list(.N)

2b:.Nlapplyby一起使用时需要# 2a: list(.N) not needed # .N + lapply dt[ , c(n = .N, lapply(.SD, max))] # n grp x y # 1: 5 b 5 6 # 2b: list(.N) needed # .N + lapply + by dt[ , c(.(n = .N), lapply(.SD, max)), by = grp] # grp n x y # 1: a 2 2 3 # 2: b 3 5 6

/public