SORU
19 NİSAN 2012, PERŞEMBE


Bir veri tam olarak anlamak.tablo için bir referans (vs bir kopyasını) başka bir veri.tablo

Küçük bir sorun veri referans ile özelliklerini anlamakta güçlük çekiyorum.tablo. Bazı işlemler '' başvurusu, ve ben tam olarak ne olduğunu anlamak istiyorum. sonu görünüyor

Başka bir veri tablosu oluşturmak.(<- yeni tablo da değişmiş. o halde güncelleme ile tablo Başına bu beklenir,:

?veri.::tablo kopyalama ve 44**

İşte size bir örnek:

library(data.table)

DT <- data.table(a=c(1,2), b=c(11,12))
print(DT)
#      a  b
# [1,] 1 11
# [2,] 2 12

newDT <- DT        # reference, not copy
newDT[1, a := 100] # modify new DT

print(DT)          # DT is modified too.
#        a  b
# [1,] 100 11
# [2,]   2 12

Ben bir sigara eklerseniz ancak: = < arasında değişiklik göre;- görevlendirme := satır yukarıda, DT şimdi artık değiştirilmiş

DT = data.table(a=c(1,2), b=c(11,12))
newDT <- DT        
newDT$b[2] <- 200  # new operation
newDT[1, a := 100]

print(DT)
#      a  b
# [1,] 1 11
# [2,] 2 12

newDT$b[2] <- 200 hat bir şekilde görünüyor o kadar 'tatili' başvurusu. Bu şekilde bir kopyasını çağırır tahmin ediyorum, ama R, benim kod olası hataları tanıtmak istemiyorum sağlamak için bu işlemler tedavi olduğunu tam olarak anlamak istiyorum.

Çok fazla eğer birisi bana bunu açıklayabilir olursa memnun olurum.

CEVAP
19 NİSAN 2012, PERŞEMBE


Evet, bir kopyasını yapar R <- (ya da = ->) kullanarak subassignmenttümnesne. tracemem(DT) ve aşağıdaki gibi .Internal(inspect(DT)) kullanarak izleyebilirsiniz. data.table * * 16* set() geçti ne olursa olsun onlar için referans oluşturur. Eğer bu nesne daha önce kopyalanan varsa (bir subassigning <- copy(DT) açık) referans tarafından değiştirilmiş alır kopyalayın.

> 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..

a değişik olmasa da a bile vektörü (farklı hex değeri vektör yeni kopyasını gösterir) kopyalandı nasıl dikkat edin. b bile, sadece değiştirilmesi gereken öğeleri değiştirmek yerine kopyalanmıştır. Önemli := set() data.table tanıtıldı neden büyük veri ve önlemek için.

Şimdi, bizim newDT kopyalanan referans tarafından modifiye :

> 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 ..

3 hex değerleri (sütun puan ve 2 her sütun vektörü) değişmeden kalır dikkat edin. Gerçekten hiç kopya ile başvuru tarafından modifiye edildi.

Ya da, başvuruyla DT orijinal değiştirebilirsiniz :

> 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..

Bu hex değerleri DT yukarıda gördüğümüz özgün değerleri aynıdır. Tip 32* *daha fazla örnek tracemem data.frame karşılaştırma için.

35 ** eğer Btw, DT[2,b:=600] bir kopya rapor görürsünüz. print yöntemi yapan ilk 10 satırı bir kopyasıdır. invisible() ile sarılmış veya işlevi veya bir komut dosyası içinde çağrıldığında, print yöntem değil.

Tüm bu; yani, := set(), hatta işlevlerde yazma kopyası değil de içindeki fonksiyonları geçerlidir. Eğer yerel bir kopyasını değiştirmeniz gerekirse, o zaman fonksiyonun başındaki x=copy(x) Ara. Ama, büyük veri için data.table unutma (küçük veriler için daha hızlı programlama avantaj). Biz kasıtlı olarak büyük nesneler (hiç) kopyalamak istemiyorum. Sonuç olarak başparmak 3* normal çalışma belleği faktör kural için izin gerek yok. Sadece çalışma belleği bir sütun gibi büyük (1/Çalışma belleği bir faktör yerine ncol 3 yani) ihtiyacı için çalışıyoruz.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • ElChakotay Andrich

    ElChakotay A

    10 EKİM 2013
  • Mega64

    Mega64

    24 ŞUBAT 2006