If you are using data.table
, the below code is faster
library(data.table)
setDT(dat)[x<0,x:=NA]
Benchmarks
Using data.table_1.9.5
and dplyr_0.3.0.9000
library(microbenchmark)
set.seed(285)
dat <- data.frame(x=sample(-5:5, 1e7, replace=TRUE), y=rnorm(1e7))
dtbl1 <- function() {as.data.table(dat)[x<0,x:=NA]}
dplr1 <- function() {dat %>% mutate(x = replace(x, x<0, NA))}
microbenchmark(dtbl1(), dplr1(), unit='relative', times=20L)
#Unit: relative
#expr min lq mean median uq max neval cld
#dtbl1() 1.00000 1.000000 1.000000 1.000000 1.000000 1.000000 20 a
#dplr1() 2.06654 2.064405 1.927762 1.795962 1.881821 1.885655 20 b
Updated Benchmarks
Using data.table_1.9.5
and dplyr_0.4.0
. I used a slightly bigger dataset and replaced as.data.table
with setDT
(Included @Sven Hohenstein's faster function as well.)
set.seed(285)
dat <- data.frame(x=sample(-5:5, 1e8, replace=TRUE), y=rnorm(1e8))
dat1 <- copy(dat)
dtbl1 <- function() {setDT(dat)[x<0,x:=NA]}
dplr1 <- function() {dat1 %>% mutate(x = replace(x, x<0, NA))}
dplr2 <- function() {dat1 %>% mutate(x = NA ^ (x < 0) * x)}
microbenchmark(dtbl1(), dplr1(), dplr2(), unit='relative', times=20L)
#Unit: relative
# expr min lq mean median uq max neval cld
#dtbl1() 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 20 a
#dplr1() 2.523945 2.542412 2.536255 2.579379 2.518336 2.486757 20 b
#dplr2() 1.139216 1.089992 1.088753 1.058653 1.093906 1.100690 20 a
Updated Benchmarks2
At the request of @docendo discimus, benchmarking again his "new" version of dplyr
using data.table_1.9.5
and dplyr_0.4.0
.
NOTE: Because there is a change in @docendo discimus code, I changed 0
to 0L
for the data.table`
set.seed(285)
dat <- data.frame(x=sample(-5:5, 1e8, replace=TRUE), y=rnorm(1e8))
dat1 <- copy(dat)
dtbl1 <- function() {setDT(dat)[x<0L, x:= NA]}
dplr1 <- function() {dat1 %>% mutate(x = replace(x, which(x<0L), NA))}
dplr2 <- function() {dat1 %>% mutate(x = NA ^ (x < 0) * x)}
microbenchmark(dtbl1(), dplr1(), dplr2(), unit='relative', times=20L)
#Unit: relative
#expr min lq mean median uq max neval cld
#dtbl1() 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 20 a
#dplr1() 2.186055 2.183432 2.142293 2.222458 2.194450 1.442444 20 b
#dplr2() 2.919854 2.925795 2.852528 2.942700 2.954657 1.904249 20 c
data
set.seed(24)
dat <- data.frame(x=sample(-5:5, 25, replace=TRUE), y=rnorm(25))