2013-05-25 71 views
4

嗨,仍然試圖找出data.table。如果我有一個如下所示的data.table值,那麼用另一個data.table中的值替換值的最有效方法是什麼?R data.table替換另一個data.table的值的索引

set.seed(123456) 

a=data.table(
    date_id = rep(seq(as.Date('2013-01-01'),as.Date('2013-04-10'),'days'),5), 
    px =rnorm(500,mean=50,sd=5), 
    vol=rnorm(500,mean=500000,sd=150000), 
    id=rep(letters[1:5],each=100) 
) 

b=data.table(
    date_id=rep(seq(as.Date('2013-01-01'),length.out=600,by='days'),5), 
    id=rep(letters[1:5],each=600), 
    px=NA_real_, 
    vol=NA_real_ 
) 

setkeyv(a,c('date_id','id')) 
setkeyv(b,c('date_id','id')) 

我想要做的是與那些在這裏date_idid比賽我有點狼狽這種替換B中的PX和VOL - 我會假設沿着威力東西線要走的路,但我認爲這不會在實踐中起作用。

b[which(b$date_id %in% a$date_id & b$id %in% a$id),list(px:=a$px,vol:=a$vol)] 

編輯

我嘗試以下

t = a[b,roll=T] 
t[!is.na(px),list(px.1:=px,vol.1=vol),by=list(date_id,id)] 

,並得到了錯誤消息

Error in `:=`(px.1, px) : 
    := is defined for use in j only, and (currently) only once; i.e., DT[i,col:=1L] and DT[,newcol:=sum(colB),by=colA] are ok, but not DT[i,col]:=1L, not DT[i]$col:=1L and not DT[,{newcol1:=1L;newcol2:=2L}]. Please see help(":="). Check is.data.table(DT) is TRUE. 
+1

我覺得* *做到這一點的方法是用一個快速滾動加入。這將基於關鍵字'b < - b [a,roll = T]將列連接到表',如果不需要它們,您可以放棄原來的'NA'列,儘管可能有更好的方法一步到位。 –

+0

謝謝@ SimonO101,在實踐中,b是一個非常大的數組,每天都會逐步填充。我需要保留其餘的值,因爲它們在b –

+0

如果您每天都在更新某些東西,是不是應該使用數據庫管理系統?有些包(我認爲)允許你從R:postgresql和RMySQL訪問你的數據庫。 – Frank

回答

8

如果您要替換b中的值,則可以使用前綴i.。從NEWS regarding version 1.7.10

The prefix i. can now be used in j to refer to join inherited columns of i that are otherwise masked by columns in x with the same name.

b[a, `:=`(px = i.px, vol = i.vol)] 
+0

雖然這是一個非常聰明,很棒的答案,我會採取更長的路線並執行此操作:'merge(a,b,by = c(「date_id」,「id」),all = TRUE)'然後重命名並檢查結果。 – geneorama

2

不喜歡你的聲音從你的描述需要roll,它好像你想要這樣做,而不是當你得到你的錯誤:

t[!is.na(px),`:=`(px.1=px,vol.1=vol),by=list(date_id,id)] 
+0

感謝您的答覆@eddi –