添加和修改列

DT[where, select|update|do, by] 语法用于处理 data.table 的列。

  • where 部分是 i 参数
  • “select | update | do”部分是 j 参数

这两个参数通常按位置而不是按名称传递。

我们的示例数据如下

mtcars = data.table(mtcars, keep.rownames = TRUE)

编辑整个列

使用 j 中的:= 运算符来分配新列:

mtcars[, mpg_sq := mpg^2]

通过设置为 NULL 删除列:

mtcars[, mpg_sq := NULL]

使用:= 运算符的多变量格式添加多个列:

mtcars[, `:=`(mpg_sq = mpg^2, wt_sqrt = sqrt(wt))]
# or 
mtcars[, c("mpg_sq", "wt_sqrt") := .(mpg^2, sqrt(wt))]

如果列是依赖的并且必须按顺序定义,则一种方法是:

mtcars[, c("mpg_sq", "mpg2_hp") := .(temp1 <- mpg^2, temp1/hp)]

LHS := RHS 的右侧是列列表时,使用 .() 语法。

对于动态确定的列名称,请使用括号:

vn = "mpg_sq"
mtcars[, (vn) := mpg^2]

也可以使用 set 修改列,但这很少需要:

set(mtcars, j = "hp_over_wt", v = mtcars$hp/mtcars$wt)

编辑列的子集

使用 i 参数子集到行 where 应该进行编辑:

mtcars[1:3, newvar := "Hello"]
# or
set(mtcars, j = "newvar", i = 1:3, v = "Hello")  

与 data.frame 一样,我们可以使用行号或逻辑测试进行子集化。也可以在 i 中使用 join,但另一个例子中包含更复杂的任务。

编辑列属性

编辑属性的函数(例如 levels<-names<-)实际上用修改后的副本替换对象。即使只在 data.table 中的一列上使用,也会复制和替换整个对象。

要修改没有副本的对象,请使用 setnames 更改 data.table 或 data.frame 和 setattr 的列名以更改任何对象的属性。

# Print a message to the console whenever the data.table is copied
tracemem(mtcars)
mtcars[, cyl2 := factor(cyl)]

# Neither of these statements copy the data.table
setnames(mtcars, old = "cyl2", new = "cyl_fac")
setattr(mtcars$cyl_fac, "levels", c("four", "six", "eight"))

# Each of these statements copies the data.table
names(mtcars)[names(mtcars) == "cyl_fac"] <- "cf"
levels(mtcars$cf) <- c("IV", "VI", "VIII")

请注意,这些更改是通过引用进行的,因此它们是全局的。在一个环境中更改它们会影响所有环境中的对象。

# This function also changes the levels in the global environment
edit_levels <- function(x) setattr(x, "levels", c("low", "med", "high"))
edit_levels(mtcars$cyl_factor)