在data.table的j参数中使用"list"

cry*_*nic 5 r data.table

我正在从博客文章中学习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)

我能够理解唯一(齿轮)但无法理解什么列表(列表(唯一(齿轮))正在做什么.

Fra*_*ank 9

data.table - 与任何data.frame一样 - 是列向量的指针列表.

当创建新列,我们写jDT[i,j,by],这样它的计算结果列的列表:

DT[, (newcol_names) := list(newcol_A, newcol_B)]
Run Code Online (Sandbox Code Playgroud)

这就是list()OP示例中最外层的一个list列.

data[,gearsL := list(list(unique(gear))), by=cyl]
Run Code Online (Sandbox Code Playgroud)

.()为清楚起见,这可以并且应该使用别名来编写:

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()/ .()是必需的.

  • 我怀疑这个问题值得这么详细,但是,呃,它已经写好了. (3认同)