2013-07-09 31 views
7

Używam operatora data.table (1.8.9) i := do aktualizacji wartości w jednej tabeli z wartości w innej. Tabela do aktualizacji (dt1) ma wiele kolumn współczynników, a tabela z aktualizacjami (dt2) ma podobne kolumny z wartościami, które mogą nie istnieć w drugiej tabeli. Jeśli kolumny w dt2 są znakami, pojawia się komunikat o błędzie, ale gdy je zilustruję, otrzymuję niepoprawne wartości.Przydzielanie danych przy użyciu czynników

Jak mogę zaktualizować tabelę bez konieczności konwersji wszystkich czynników na znaki?

Oto uproszczony przykład:

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. 

Page 3 data.table help file mówi:

Kiedy LHS jest kolumną czynnik i RHS jest wektorem postać z elementów brakujących od poziomu czynnika , nowy poziom (poziomy) są automatycznie dodawane (przez odniesienie, wydajnie), w przeciwieństwie do metod bazowych.

To sprawia, że ​​wydaje się, że to, co próbowałem, powinno działać, ale oczywiście brakuje mi czegoś. Zastanawiam się, czy jest to związane z tym podobnego problemu:

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

+0

W tej chwili wygląda na niemożliwy. – kohske

Odpowiedz

1

Oto obejście:

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

Zauważ, że z jest kolumną charakter i drugie zadanie działa zgodnie z oczekiwaniami, nie bardzo wiadomo, dlaczego OP nie.

+0

Wielkie dzięki za obejście problemu, @eddi. Pozostawiam pytanie bez odpowiedzi, w nadziei, że ktoś może zasugerować, dlaczego standardowa składnia nie działa. – dnlbrky

Powiązane problemy