Ya, subassignment di R menggunakan <-
(atau =
atau ->
) yang membuat salinan seluruh objek. Anda dapat melacaknya menggunakan tracemem(DT)
dan .Internal(inspect(DT))
, seperti di bawah ini. The data.table
fitur :=
dan set()
menetapkan dengan mengacu apapun keberatan mereka berlalu. Jadi, jika objek itu sebelumnya disalin (oleh subassigning <-
atau eksplisit copy(DT)
) maka itu adalah salinan yang akan dimodifikasi oleh referensi.
DT <- data.table(a = c(1, 2), b = c(11, 12))
newDT <- DT
.Internal(inspect(DT))
# @0000000003B7E2A0 19 VECSXP g0c7 [OBJ,NAM(2),ATT] (len=2, tl=100)
# @00000000040C2288 14 REALSXP g0c2 [NAM(2)] (len=2, tl=0) 1,2
# @00000000040C2250 14 REALSXP g0c2 [NAM(2)] (len=2, tl=0) 11,12
# ATTRIB: # ..snip..
.Internal(inspect(newDT)) # precisely the same object at this point
# @0000000003B7E2A0 19 VECSXP g0c7 [OBJ,NAM(2),ATT] (len=2, tl=100)
# @00000000040C2288 14 REALSXP g0c2 [NAM(2)] (len=2, tl=0) 1,2
# @00000000040C2250 14 REALSXP g0c2 [NAM(2)] (len=2, tl=0) 11,12
# ATTRIB: # ..snip..
tracemem(newDT)
# [1] "<0x0000000003b7e2a0"
newDT$b[2] <- 200
# tracemem[0000000003B7E2A0 -> 00000000040ED948]:
# tracemem[00000000040ED948 -> 00000000040ED830]: .Call copy $<-.data.table $<-
.Internal(inspect(DT))
# @0000000003B7E2A0 19 VECSXP g0c7 [OBJ,NAM(2),TR,ATT] (len=2, tl=100)
# @00000000040C2288 14 REALSXP g0c2 [NAM(2)] (len=2, tl=0) 1,2
# @00000000040C2250 14 REALSXP g0c2 [NAM(2)] (len=2, tl=0) 11,12
# ATTRIB: # ..snip..
.Internal(inspect(newDT))
# @0000000003D97A58 19 VECSXP g0c7 [OBJ,NAM(2),ATT] (len=2, tl=100)
# @00000000040ED7F8 14 REALSXP g0c2 [NAM(2)] (len=2, tl=0) 1,2
# @00000000040ED8D8 14 REALSXP g0c2 [NAM(2)] (len=2, tl=0) 11,200
# ATTRIB: # ..snip..
Perhatikan bagaimana bahkan a
vektor disalin (nilai heks yang berbeda menunjukkan salinan vektor baru), meskipun a
tidak diubah. Bahkan keseluruhan b
sudah disalin, bukan hanya mengubah elemen yang perlu diubah. Itu penting untuk dihindari untuk data besar, dan mengapa :=
dan set()
diperkenalkan data.table
.
Sekarang, dengan salinan newDT
kami, kami dapat memodifikasinya dengan referensi:
newDT
# a b
# [1,] 1 11
# [2,] 2 200
newDT[2, b := 400]
# a b # See FAQ 2.21 for why this prints newDT
# [1,] 1 11
# [2,] 2 400
.Internal(inspect(newDT))
# @0000000003D97A58 19 VECSXP g0c7 [OBJ,NAM(2),ATT] (len=2, tl=100)
# @00000000040ED7F8 14 REALSXP g0c2 [NAM(2)] (len=2, tl=0) 1,2
# @00000000040ED8D8 14 REALSXP g0c2 [NAM(2)] (len=2, tl=0) 11,400
# ATTRIB: # ..snip ..
Perhatikan bahwa semua 3 nilai hex (vektor titik kolom, dan masing-masing dari 2 kolom) tetap tidak berubah. Jadi itu benar-benar dimodifikasi dengan referensi tanpa salinan sama sekali.
Atau, kita dapat memodifikasi yang asli DT
dengan referensi:
DT[2, b := 600]
# a b
# [1,] 1 11
# [2,] 2 600
.Internal(inspect(DT))
# @0000000003B7E2A0 19 VECSXP g0c7 [OBJ,NAM(2),ATT] (len=2, tl=100)
# @00000000040C2288 14 REALSXP g0c2 [NAM(2)] (len=2, tl=0) 1,2
# @00000000040C2250 14 REALSXP g0c2 [NAM(2)] (len=2, tl=0) 11,600
# ATTRIB: # ..snip..
Nilai hex tersebut sama dengan nilai asli yang kami lihat di DT
atas. Ketik example(copy)
untuk lebih banyak contoh menggunakan tracemem
dan membandingkan data.frame
.
Btw, jika Anda tracemem(DT)
maka DT[2,b:=600]
Anda akan melihat satu salinan dilaporkan. Itu adalah salinan dari 10 baris pertama yang dilakukan oleh print
metode ini. Ketika dibungkus dengan invisible()
atau ketika dipanggil dalam suatu fungsi atau skrip, print
metode tersebut tidak dipanggil.
Semua ini berlaku di dalam fungsi juga; yaitu, :=
dan set()
jangan salin saat menulis, bahkan dalam fungsi. Jika Anda perlu memodifikasi salinan lokal, hubungi x=copy(x)
di awal fungsi. Tetapi, yang diingat data.table
adalah untuk data besar (juga keunggulan pemrograman lebih cepat untuk data kecil). Kami sengaja tidak ingin menyalin objek besar (pernah). Akibatnya, kita tidak perlu mengizinkan aturan praktis faktor memori 3 * yang biasa digunakan. Kami mencoba hanya perlu memori yang bekerja sebesar satu kolom (yaitu faktor memori kerja 1 / ncol daripada 3).
<-
alih-alih=
untuk penugasan dasar di R (misalnya oleh Google: google.github.io/styleguide/Rguide.xml#assignment ). Tetapi ini berarti bahwa manipulasi data.tabel tidak akan berfungsi dengan cara yang sama seperti manipulasi bingkai data dan karenanya jauh dari penggantian drop-in ke bingkai data.