添加和修改列
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)