第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

準(zhǔn)確地理解data.table何時是對另一個data.table的引用

準(zhǔn)確地理解data.table何時是對另一個data.table的引用

瀟瀟雨雨 2019-06-05 11:15:00
我很難理解data.table..有些操作似乎“打破”了引用,我想確切地了解發(fā)生了什么。關(guān)于創(chuàng)建data.table從另一個data.table(經(jīng)<-,然后通過以下方法更新表:=,原來的表也被修改了。這是預(yù)期的,如下所示:?data.table::copy和StackOverflow:pass-by-reference-the-operator-in-the-data-table-package下面是一個例子:library(data.table)DT <- data.table(a=c(1,2), b=c(11,12))print(DT)#      a  b# [1,] 1 11# [2,] 2 12newDT <- DT         # reference, not copynewDT[1, a := 100] # modify new DTprint(DT)           # DT is modified too.#        a  b# [1,] 100 11# [2,]   2 12但是,如果我插入一個非-:=之間的基礎(chǔ)修改<-任務(wù)和:=上面的線,DT現(xiàn)在不再修改:DT = data.table(a=c(1,2), b=c(11,12))newDT <- DT         newDT$b[2] <- 200  # new operationnewDT[1, a := 100]print(DT)#      a  b# [1,] 1 11# [2,] 2 12所以看起來newDT$b[2] <- 200行在某種程度上破壞了引用。我猜想這會以某種方式調(diào)用一個副本,但我想完全了解R是如何處理這些操作的,以確保我不會在代碼中引入潛在的bug。如果有人能向我解釋這件事,我會非常感激的。
查看完整描述

2 回答

?
肥皂起泡泡

TA貢獻(xiàn)1829條經(jīng)驗 獲得超6個贊

是的,它是在R中使用的<-(或=或->)的副本。整體對象。您可以使用tracemem(DT)和.Internal(inspect(DT)),如下所示。這個data.table特征:=和set()通過引用將它們傳遞給任何對象。因此,如果該對象以前被復(fù)制(通過subas簽名)<-或顯式copy(DT))然后是通過引用修改的副本。


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向量被復(fù)制(不同的十六進(jìn)制值表示向量的新副本),盡管a沒有改變。甚至整個b被復(fù)制,而不僅僅是更改需要更改的元素。對于大型數(shù)據(jù)來說,這是很重要的避免,以及為什么:=和set()被介紹給data.table.


現(xiàn)在,用我們的拷貝newDT我們可以參考修改:


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個十六進(jìn)制值(列點的向量,以及2列中的每一列)都保持不變。因此,它確實是通過引用而修改的,根本沒有副本。


或者,我們可以修改原始DT引用:


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

這些十六進(jìn)制值與我們看到的原始值相同。DT上面。類型example(copy)有關(guān)更多示例,請使用tracemem以及與.的比較data.frame.


順便說一下,如果你tracemem(DT)然后DT[2,b:=600]你會看到一份報告。的前10行的副本。print方法可以。用invisible()或在函數(shù)或腳本中調(diào)用時,print方法不被調(diào)用。


所有這一切也適用于內(nèi)部功能;即,:=和set()不要在寫時復(fù)制,即使在函數(shù)中也是如此。如果需要修改本地副本,請調(diào)用x=copy(x)在函數(shù)開始的時候。但是,記住data.table適用于大數(shù)據(jù)(以及小數(shù)據(jù)的快速編程優(yōu)勢)。我們故意不想復(fù)制大對象(永遠(yuǎn))。因此,我們不需要考慮通常的3*工作記憶因素的經(jīng)驗法則。我們試著只需要一個列那么大的工作記憶(即工作記憶系數(shù)為1/nol,而不是3)。


查看完整回答
反對 回復(fù) 2019-06-05
?
繁花如伊

TA貢獻(xiàn)2012條經(jīng)驗 獲得超12個贊

簡單總結(jié)一下。

<-帶著data.table就像基本;也就是說,在完成以下操作之前,將不進(jìn)行復(fù)制。<-(例如更改列名或更改元素,如DT[i,j]<-v)。然后,它獲取整個對象的副本,就像基一樣。這就是所謂的抄寫。我想,應(yīng)該更好地稱為“仿冒”!當(dāng)您使用“特殊”時,它不會復(fù)制。:=運算符,或set*data.table..如果您有大量數(shù)據(jù),您可能希望使用它們。:=set*不會復(fù)制data.table甚至在職能范圍內(nèi)。

給定此示例數(shù)據(jù):

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

以下只是“綁定”另一個名稱DT2綁定到當(dāng)前綁定到名稱的相同數(shù)據(jù)對象。DT :

DT2 <- DT

這永遠(yuǎn)不會復(fù)制,也不會在基礎(chǔ)上復(fù)制。它只是標(biāo)記數(shù)據(jù)對象,以便R知道兩個不同的名稱(DT2DT)指向同一個對象。所以R需要復(fù)制對象,如果兩者都是副簽名以后的事。

那是完美的data.table也是。這個:=不是為了這么做。因此,下面是一個故意的錯誤,因為:=不只是用于綁定對象名稱:

DT2 := DT    # not what := is for, not defined, gives a nice error

:=是為了次簽署參考一下。但你不像你在基地里那樣使用它:

DT[3,"foo"] := newvalue    # not like this

你就這樣用它:

DT[3,foo:=newvalue]    # like this

改變了DT參考一下。假設(shè)您添加了一個新列new通過引用數(shù)據(jù)對象,沒有必要這樣做:

DT <- DT[,new:=1L]

因為RHS已經(jīng)改變了DT參考一下。額外的DT <-就是誤解了什么:=的確如此。你可以把它寫在那里,但它是多余的。

DT因引用而更改:=,即使在職能范圍內(nèi):

f <- function(X){
    X[,new2:=2L]
    return("something else")}f(DT)   # will change DTDT2 <- DT
f(DT)   # will change both DT and DT2 (they're the same data object)

data.table是用于大型數(shù)據(jù)集的,請記住。如果你有20 GBdata.table在記憶中,你需要一個方法來做到這一點。這是一個非常慎重的設(shè)計決策data.table.

當(dāng)然可以復(fù)制。您只需要告訴data.table,您肯定要復(fù)制您的20 GB數(shù)據(jù)集,方法是使用copy()職能:

DT3 <- copy(DT)   # rather than DT3 <- DTDT3[,new3:=3L]     # now, this just changes DT3 because it's a copy, not DT too.

為了避免復(fù)制,不要使用基類型分配或更新:

DT$new4 <- 1L                 # will make a copy so use :=attr(DT,"sorted") <- "a"      # will make a copy use setattr()

如果您希望確保您正在通過引用進(jìn)行更新,請使用.Internal(inspect(x))然后看看成分的內(nèi)存地址值(見MatthewDowle的答案)。

寫字:=在……里面j這樣你就可以參考按組..可以按組按引用添加新列。所以這就是為什么:=在里面是這樣做的[...] :

DT[, newcol:=mean(x), by=group]


查看完整回答
反對 回復(fù) 2019-06-05
  • 2 回答
  • 0 關(guān)注
  • 822 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號