RaukR 2026 • Data Science With R
Marcin Kierczak
18-Aug-2026

Everything works and produces seemingly valid output that is WRONG!
IMHO those are the hardest 💀 to debug!
[1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[1] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
[1] 0
[1] -1.110223e-16
When comparing floating point numbers, instead of this:
double.eps double.neg.eps double.xmin double.xmax double.base
2.220446e-16 1.110223e-16 2.225074e-308 1.797693e+308 2.000000e+00
double.digits
5.300000e+01
try()tryCatch[1] "log10 of 10 is 1"
[1] "A warning occured: NaNs produced"
[1] "An error occured: non-numeric argument to mathematical function"
[1] "log10 of 42 is 1.6232492903979"
stop() function that:
error.print statements
Hint: Last empty line brings you back to the environments menu.
Error in `log10()`:
! non-numeric argument to mathematical function
> traceback()
2: f(x) at #2
1: g("test")
traceback() shows what were the function calls and what parameters were passed to them when the error occurred.
proc.time()Profiling is the process of identifying memory and time bottlenecks 🍾 in your code.
user time – CPU time charged for the execution of user instructions of the calling process,system time – CPU time charged for execution by the system on behalf of the calling process,elapsed time – total CPU time elapsed for the currently running R process.system.time() user system elapsed
0.071 0.004 0.075
user system elapsed
0.178 0.000 0.178
bench::mark()or mark() from bench package:
# A tibble: 3 × 6
expression min median `itr/sec` mem_alloc `gc/sec`
<bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
1 dat[dat$x > 500, ] 78.1µs 88.3µs 11036. 378KB 49.6
2 dat[which(dat$x > 500), ] 71.1µs 77.1µs 12911. 260KB 40.2
3 subset(dat, x > 500) 99.9µs 112.2µs 8822. 511KB 52.4
These 4 functions fill a large vector with values supplied by function f.
1 – loop without memory allocation.
But it is maybe better to use…
vectorization!
3 – vectorized loop without memory allocation.
We can include the memory profiling, using, e.g. Rprof() function.
[1] 0.78279579 0.05264464 0.50698257 0.90737045 0.31946093 0.79888663
[1] 0.6872827 0.6428758 0.9454728 0.1888565 0.3335069 0.7415906
[1] 0.8361113 0.7188930 0.9121614 0.4654298 0.5075432 0.2536313
[1] 0.8306435 0.5007408 0.8382084 0.6722948 0.5235330 0.3564790
[1] 0.7162534 0.5847373 0.5167241 0.5347672 0.2806981 0.8517943
We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be deluded into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified.
– Donald Knuth

source: https://xkcd.com/1319

source: https://xkcd.com/1205/
data.table or tibble instead of data.frame*apply when possiblefutures or mirai for multicore/parallel executionBLAS for linear algebra,bigmemory package,Check where the objects are in the memory:
What happens if we modify a value in one of the matrices?
No memory allocation
With memory allocation
[1] "0x718fb2828 --> 0x718fb2828"
[1] "0x718fb2828 --> 0x718fb2828"
[1] "0x718fb2828 --> 0x718fb2828"
Error in `if (x %in% droids) ...`:
! the condition has length > 1
The base::Vectorize way:
Anakin Vader R2-D2 AZI-3 Luke
FALSE FALSE TRUE TRUE FALSE
vapply way:
gpuRA = matrix(rnorm(1000^2), nrow=1000) # stored: RAM, computed: CPU
B = matrix(rnorm(1000^2), nrow=1000)
gpuA = gpuMatrix(A, type = "float") # stored: RAM, computed: GPU
gpuB = gpuMatrix(B, type = "float")
vclA = vclMatrix(A, type = "float") # stored: GPU, computed: GPU
vclB = vclMatrix(B, type = "float")
bch <- microbenchmark(
cpu_ram = A %*% B,
gpu_ram = gpuA %*% gpuB,
gpu_vcl = vclA %*% vclB,
times = 10L) More on Charles Determan’s Blog.
future