2013-07-09 8 views
7

data.table(1.8.9)演算子と:=演算子を使用して、あるテーブルの値を別のテーブルの値から更新しています。更新されるテーブル(dt1)には多くのファクタ列があり、更新(dt2)のあるテーブルには他のテーブルに存在しない可能性のある類似の列があります。 dt2の列が文字の場合はエラーメッセージが表示されますが、それらを因数分解すると誤った値が返されます。data.table代入を含む代入

最初にすべての要因を文字に変換せずにテーブルを更新するにはどうすればよいですか?

library(data.table) 

set.seed(3957) 

## Create some sample data 
## Note column y is a factor 
dt1<-data.table(x=1:10,y=factor(sample(letters,10))) 
dt1 

##  x y 
## 1: 1 m 
## 2: 2 z 
## 3: 3 t 
## 4: 4 b 
## 5: 5 l 
## 6: 6 a 
## 7: 7 s 
## 8: 8 y 
## 9: 9 q 
## 10: 10 i 

setkey(dt1,x) 

set.seed(9068) 

## Create a second table that will be used to update the first one. 
## Note column y is not a factor 
dt2<-data.table(x=sample(1:10,5),y=sample(letters,5)) 
dt2 

## x y 
## 1: 2 q 
## 2: 7 k 
## 3: 3 u 
## 4: 6 n 
## 5: 8 t 

## Join the first and second tables on x and attempt to update column y 
## where there is a match 
dt1[dt2,y:=i.y] 

## Error in `[.data.table`(dt1, dt2, `:=`(y, i.y)) : 
## Type of RHS ('character') must match LHS ('integer'). To check and 
## coerce would impact performance too much for the fastest cases. Either 
## change the type of the target column, or coerce the RHS of := yourself 
## (e.g. by using 1L instead of 1) 

## Create a third table that is the same as the second, except y 
## is also a factor 
dt3<-copy(dt2)[,y:=factor(y)] 

## Join the first and third tables on x and attempt to update column y 
## where there is a match 
dt1[dt3,y:=i.y] 
dt1 

##  x y 
## 1: 1 m 
## 2: 2 i 
## 3: 3 m 
## 4: 4 b 
## 5: 5 l 
## 6: 6 b 
## 7: 7 a 
## 8: 8 l 
## 9: 9 q 
## 10: 10 i 

## No error message this time, but it is using the levels and not the labels 
## from dt3. For example, row 2 should be q but it is i. 

ページdata.table help fileの3氏:ここ

は簡略化した例である

LHSが要因列があるとRHSは因子レベルから不足している項目 と文字ベクトルであります新しいレベルは、基本メソッドとは異なり、自動的に が追加されます(効率的に参照されます)。

これは、私が試したことがうまくいくように見えますが、明らかに何か不足しています。これは、この同様の問題に関連している場合、私は疑問に思う:

rbindlist two data.tables where one has factor and other has character type for a column

+0

現時点では不可能です。 – kohske

答えて

1

ここでは、回避策です:zが文字列であると予想されるように、第2の割り当てが動作することを

dt1[dt2, z := i.y][!is.na(z), y := z][, z := NULL] 

注意、ないなぜ実際に確認してくださいがOPはしません。

+0

回避策@eddiに感謝します。標準の構文がなぜ機能しないのかを誰かが示唆してくれることを期待して、質問を未回答のままにしておきます。 – dnlbrky