为什么在dplyr中将新名称重新指定给dataframe会更快?

为什么在dplyr中将新名称重新指定给dataframe会更快?,r,performance,data.table,dplyr,tidyverse,R,Performance,Data.table,Dplyr,Tidyverse,我对dplyr和data.table在我的data.frame上创建一个新变量并决定比较方法所花费的时间感到不满意 令我惊讶的是,将dplyr::mutate的结果重新分配到新的data.frame似乎比不这样做要快 为什么会这样 library(data.table) library(tidyverse) dt <- fread(".... data.csv") #load 200MB datafile dt1 <- copy(dt) dt2 <- copy(dt) d

我对dplyr和data.table在我的data.frame上创建一个新变量并决定比较方法所花费的时间感到不满意

令我惊讶的是,将dplyr::mutate的结果重新分配到新的data.frame似乎比不这样做要快

为什么会这样

library(data.table)
library(tidyverse)


dt <- fread(".... data.csv") #load 200MB datafile

dt1 <- copy(dt)
dt2 <- copy(dt)
dt3 <- copy(dt)

a <- Sys.time()
dt1[, MONTH := month(as.Date(DATE))]
b <- Sys.time(); datatabletook <- b-a

c <- Sys.time()
dt_dplyr <- dt2 %>%
  mutate(MONTH = month(as.Date(DATE)))
d <- Sys.time(); dplyr_reassign_took <- d - c 

e <- Sys.time()
dt3 %>%
  mutate(MONTH = month(as.Date(DATE)))
f <- Sys.time(); dplyrtook <- f - e

datatabletook        = 17sec
dplyrtook            = 47sec
dplyr_reassign_took  = 17sec

有两种方法可以:

使用Sys.time方式,您将每一行发送到控制台,并且可能会看到为每一行打印的一些返回值,正如@Axeman所建议的。对于{…},只有一个返回值—大括号内的最后一个结果和system.time将禁止打印它

如果打印成本足够高,但不是您想要测量的内容的一部分,那么它可能会产生影响

有充分的理由选择系统时间而不是系统时间进行基准测试;来自@MattDowle的评论:

i它首先从定时中排除gc,以从随机gc中分离,并且

它包括用户和系统时间以及经过的挂钟时间

Sys.time方式将受到在Chrome中阅读电子邮件或使用Excel的影响。测试运行时,只要您使用结果的用户和Sys部分,system.time方式就不会受到影响


dt1@Frank-根据您的建议编辑了问题。相同/相似的结果。好的,有趣/意外的结果。我想把它作为一个可复制的例子是有帮助的。也许问题不在于作业,而在于打印到控制台需要额外的时间?没有复制,这有点像猜谜游戏。另外,dt是一个data.table,所以有一些转换正在进行吗?为了检查它是否是打印,您可以使用system.time包装,而不是使用双Sys.time thing.system.time{…}也更好,因为i它首先从定时中排除gc,以与随机gc隔离,ii它包括用户和系统时间以及经过的挂钟时间。Sys.time方式将受到在Chrome中阅读电子邮件或使用Excel的影响。测试运行时,只要您使用结果的用户和Sys部分,system.time方式就不会受到影响。
.t0 <- Sys.time()
    ...
.t1 <- Sys.time()
.t1 - t0    

 # or

 system.time({
     ...
 })