使用data.table的`:=`创建依赖新列报错,能否实现dplyr类似功能?
在data.table中创建依赖前序新列的解决方案
嗨,刚从dplyr转data.table遇到这个问题太正常啦!你遇到的报错不是:=不能实现这个功能,而是data.table和dplyr在处理多列创建时的执行逻辑不一样。
问题原因
dplyr的mutate()是按顺序执行的——每创建一个新列,后面的表达式就能直接引用它,因为每一步都更新了当前的数据上下文。但data.table在同一次:=调用里,所有右侧的表达式都是基于原始数据表计算的,这时候column.1还没被添加到表中,自然会报“找不到对象”的错误。
你的这段代码确实不可行:
x[, `:=`(column.1 = a / b, column.2 = column.1 / 2)]
三种可行的解决方法
下面用示例数据给你演示:
library(data.table) x <- data.table(a = c(4, 6, 8), b = c(2, 3, 4))
方法1:分两次调用:=
最简单的方式,先创建第一个新列,再基于它创建第二个:
x[, column.1 := a / b] x[, column.2 := column.1 / 2]
方法2:使用data.table的链式调用
利用data.table支持链式操作的特性,把两次调用连起来,代码更紧凑:
x[, column.1 := a / b][, column.2 := column.1 / 2]
方法3:在同一调用中用临时变量复用计算结果
如果想在一次:=调用里完成,可以先把column.1的计算结果存在临时变量中,再用它生成column.2:
x[, c("column.1", "column.2") := { tmp <- a / b list(tmp, tmp / 2) }]
这种方法的好处是避免重复计算a/b,效率更高,尤其是处理大数据集的时候。
对比dplyr的写法
你熟悉的dplyr写法是这样的:
library(dplyr) x %>% mutate(column.1 = a / b, column.2 = column.1 / 2)
两者逻辑差异的核心就是:dplyr的mutate是逐步更新数据上下文,而data.table同一次:=调用是基于原始数据批量计算。
内容的提问来源于stack exchange,提问作者uncool
相关产品推荐
相关产品推荐

