data.table
的基本属性是
“只要
j
返回一个列表,列表中的每个元素就会成为结果data.table中的一列。”
这显示为例如在?data.table
的示例中:
library(data.table)
DT[, c(.N, lapply(.SD, sum)), by=x]
此处整数.N
c
与lapply
生成的列表相关联,整体结果为列表,即.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.,
?以下是一个小例子,其中所有变量的list
和max(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
的下一个示例提供了线索。
.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
(如上所示)是保证使用显式.()
的例外,总是为了安全起见吗?还有其他陷阱我忽略了吗?
答案 0 :(得分:3)
首先,感谢@Frank指出.N
名称的行为可能是一个错误。虽然这是一个小问题(posted one though),但我确实认为这是list
j
中使用.N
更为笼统的原因。
我对.N
及其名称进行了一些简单的测试,这表明存在一些潜在的不一致性。 FWIW,我想我也可以在这里分享它们(评论太久了)。
.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)lapply
与list(.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
list(.N)
2a:.N
与lapply
list(.N)
2b:.N
与lapply
和by
一起使用时需要# 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