我正在从博客文章中学习data.table属性.我试图理解"摘要表(简短和窄)"下的部分,首先是将data.frame(mtcars)强制转换为data.table:
> data <- as.data.table(mtcars)
> data <- data[,.(gear,cyl)]
> head(data)
gear cyl
1: 4 6
2: 4 6
3: 4 4
4: 3 6
5: 3 8
6: 3 6
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好.
现在我试过这个 data[, gearsL := list(list(unique(gear))), by=cyl]
> head(data)
gear cyl gearsL
1: 4 6 4,3,5
2: 4 6 4,3,5
3: 4 4 4,3,5
4: 3 6 4,3,5
5: 3 8 3,5
6: 3 6 4,3,5
Run Code Online (Sandbox Code Playgroud)
我能够理解唯一(齿轮)但无法理解什么列表(列表(唯一(齿轮))正在做什么.
data.table - 与任何data.frame一样 - 是列向量的指针列表.
当创建新列,我们写j的DT[i,j,by],这样它的计算结果列的列表:
DT[, (newcol_names) := list(newcol_A, newcol_B)]
Run Code Online (Sandbox Code Playgroud)
这就是list()OP示例中最外层的一个list列.
Run Code Online (Sandbox Code Playgroud)data[,gearsL := list(list(unique(gear))), by=cyl]
.()为清楚起见,这可以并且应该使用别名来编写:
data[, gearsL := .(list(unique(gear))), by=cyl]
Run Code Online (Sandbox Code Playgroud)
这就是你需要知道的全部内容,但我在下面做了一些阐述.
细节.创建新列时,我们通常可以跳过list()/ .():
DT = data.table(id=1:3)
DT[, E := c(4,5,6)]
DT[, R := 3]
# this works as if we had typed
# R := c(3,3,3)
Run Code Online (Sandbox Code Playgroud)
请注意,E枚举每个值,同时R在所有行上回收单个值.下一个例子:
DT[, Elist := list(hist(rpois(1,1)), hist(rpois(2,2)), hist(rpois(3,3)))]
Run Code Online (Sandbox Code Playgroud)
正如我们所做的那样E,我们列举了Elist这里的价值观.这仍然使用快捷方式; list()在这里只是因为列本身是一个list,正如所证实的那样
sapply(DT, class)
# id E R Elist
# "integer" "numeric" "numeric" "list"
Run Code Online (Sandbox Code Playgroud)
在一种特殊情况下跳过list()/ .()失败的便捷快捷方式:当我们创建一个list回收其值的列时:
DT[, Rlist := list(c("a","b"))]
# based on the pattern for column R, this should work as if we typed
# Rlist := list(c("a","b"), c("a","b"), c("a","b"))
Run Code Online (Sandbox Code Playgroud)
它不起作用,因为解析器将其视为C2 := .( c("a", "b") )并且认为我们只是忽略了为每一行创建一个具有一个值的完整枚举,就像Elist这样.要获得所需的结果,请跳过快捷方式并将矢量包装在list()/中.():
DT[, Rlist := .(list(c("a","b")))]
# id E R Elist Rlist
# 1: 1 4 3 <histogram> a,b
# 2: 2 5 3 <histogram> a,b
# 3: 3 6 3 <histogram> a,b
Run Code Online (Sandbox Code Playgroud)
OP的例子就是这种情况,其中outer list()/ .()是必需的.