Ben Bolkersの回答は包括的ですが、apply
data.framesで避けるべき他の理由を説明します。
apply
data.frame
をマトリックスに変換します。これにより、コピー(時間とメモリの浪費)が作成されるだけでなく、意図しない型変換が発生する可能性があります。
1000万行のデータがあることを考えると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部!--1000万行で、それはおそらくいつか来てあなたを噛むでしょう。
を使用する場合、ベクトルに割り当てる場合は関係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)]
コピーはありません!
おそらくここで修正されますが、考慮すべきもう1つのメモリの問題は、sqrt(x^2+y^2))
4つの一時変数を(内部的に)作成 しx^2
、次にy^2
x^2 + y^2
sqrt(x^2 + y^2))
以下は遅くなりますが、作成される変数は2つだけです。
DT[, rowid := .I] # previous option: DT[, rowid := seq_len(nrow(DT))]
DT[, y2 := sqrt(x^2 + y^2), by = rowid]