Хотя ответ Бена Болкерса является исчерпывающим, я объясню другие причины, по которым следует избегать apply
в data.frames.
apply
преобразует ваш data.frame
в матрицу. Это создаст копию (пустая трата времени и памяти), а также, возможно, вызовет непреднамеренные преобразования типов.
Учитывая, что у вас есть 10 миллионов строк данных, я бы посоветовал вам взглянуть на пакет data.table
, который позволит вам делать что-то эффективно с точки зрения памяти и времени.
Например, используя tracemem
x <- apply(d,1, hypot2)
tracemem[0x2f2f4410 -> 0x2f31b8b8]: as.matrix.data.frame as.matrix apply
Это еще хуже, если вы затем назначите столбцу в d
d$x <- apply(d,1, hypot2)
tracemem[0x2f2f4410 -> 0x2ee71cb8]: as.matrix.data.frame as.matrix apply
tracemem[0x2f2f4410 -> 0x2fa9c878]:
tracemem[0x2fa9c878 -> 0x2fa9c3d8]: $<-.data.frame $<-
tracemem[0x2fa9c3d8 -> 0x2fa9c1b8]: $<-.data.frame $<-
4 экземпляра! -- с 10 миллионами строк это, вероятно, придет и укусит вас в какой-то момент.
Если мы используем with
, copying
не задействовано, если мы назначаем вектору
y <- with(d, sqrt(x^2 + y^2))
Но будет, если мы присвоим столбцу в data.frame d
d$y <- with(d, sqrt(x^2 + y^2))
tracemem[0x2fa9c1b8 -> 0x2faa00d8]:
tracemem[0x2faa00d8 -> 0x2faa0f48]: $<-.data.frame $<-
tracemem[0x2faa0f48 -> 0x2faa0d08]: $<-.data.frame $<-
Теперь, если вы используете data.table
и :=
для назначения по ссылке (без копирования)
library(data.table)
DT <- data.table(d)
tracemem(DT)
[1] "<0x2d67a9a0>"
DT[,y := sqrt(x^2 + y^2)]
Никаких копий!
Возможно, здесь меня поправят, но следует учитывать еще одну проблему с памятью: sqrt(x^2+y^2))
создаст 4 временные переменные (внутренне) x^2
, y^2
, x^2 + y^2
, а затем sqrt(x^2 + y^2))
Следующее будет медленнее, но будет создаваться только две переменные.
DT[, rowid := .I] # previous option: DT[, rowid := seq_len(nrow(DT))]
DT[, y2 := sqrt(x^2 + y^2), by = rowid]
person
mnel
schedule
20.12.2012