Ответ 1
is.na
(являющийся примитивным) имеет относительно немного меньшие накладные расходы и обычно довольно быстро. Таким образом, вы можете просто пропустить столбцы и использовать set
для замены NA with
0`.
Использование <-
для назначения приведет к копированию всех столбцов, и это не является идиоматическим способом, используя data.table
.
Сначала я проиллюстрирую, как это сделать, а затем покажу, как медленно это может получить на огромные данные (из-за копии):
Один из способов сделать это эффективно:
for (i in seq_along(tt)) set(tt, i=which(is.na(tt[[i]])), j=i, value=0)
Здесь вы получите предупреждение о том, что "0" принуждается к символу в соответствии с типом столбца. Вы можете игнорировать его.
Почему вы не должны использовать <-
здесь:
# by reference - idiomatic way
set.seed(45)
tt <- data.table(matrix(sample(c(NA, rnorm(10)), 1e7*3, TRUE), ncol=3))
tracemem(tt)
# modifies value by reference - no copy
system.time({
for (i in seq_along(tt))
set(tt, i=which(is.na(tt[[i]])), j=i, value=0)
})
# user system elapsed
# 0.284 0.083 0.386
# by copy - NOT the idiomatic way
set.seed(45)
tt <- data.table(matrix(sample(c(NA, rnorm(10)), 1e7*3, TRUE), ncol=3))
tracemem(tt)
# makes copy
system.time({tt[is.na(tt)] <- 0})
# a bunch of "tracemem" output showing the copies being made
# user system elapsed
# 4.110 0.976 5.187