Actualizar subconjunto de data.table basado en join

Tengo dos tablas de datos, DT1 y DT2:

set.seed(1) DT1<-data.table(id1=rep(1:3,2),id2=sample(letters,6), v1=rnorm(6), key="id2") DT1 ## id1 id2 v1 ## 1: 2 e 0.7383247 ## 2: 1 g 1.5952808 ## 3: 2 j 0.3295078 ## 4: 3 n -0.8204684 ## 5: 3 s 0.5757814 ## 6: 1 u 0.4874291 DT2<-data.table(id2=c("n","u"), v1=0, key="id2") DT2 ## id2 v1 ## 1: n 0 ## 2: u 0 

Me gustaría actualizar DT1 basado en una unión con DT2, pero solo para un subconjunto de DT1. Por ejemplo, para DT1[id1==3] , esperaría que el valor de v1 en la fila 4 se actualice como en el siguiente resultado:

 DT1 ## id1 id2 v1 ## 1: 2 e 0.7383247 ## 2: 1 g 1.5952808 ## 3: 2 j 0.3295078 ## 4: 3 n 0 ## 5: 3 s 0.5757814 ## 6: 1 u 0.4874291 

Sé cómo actualizar una tabla (utilizando el operador := asignación), cómo unir las tablas ( DT1[DT2] ) y cómo subconjuntar una tabla ( DT1[id1==3] ). Sin embargo, no estoy seguro de cómo hacer las tres cosas a la vez.

EDITAR: Tenga en cuenta que el ejemplo original solo intenta actualizar una columna, pero mis datos reales requieren la actualización de muchas columnas. Considere los escenarios adicionales en DT1b y DT2b:

 set.seed(2) DT1b<-DT1[,v2:=rnorm(6)] # Copy DT1 and add a new column setkey(DT1b,id2) DT1b ## id1 id2 v1 v2 ## 1: 2 e 0.7383247 -0.89691455 ## 2: 1 g 1.5952808 0.18484918 ## 3: 2 j 0.3295078 1.58784533 ## 4: 3 n -0.8204684 -1.13037567 ## 5: 3 s 0.5757814 -0.08025176 ## 6: 1 u 0.4874291 0.13242028 DT2b<-rbindlist(list(DT2,data.table(id2="e",v1=0))) # Copy DT2 and add a new row DT2b[,v2:=-1] # Add a new column to DT2b setkey(DT2b,id2) DT2b ## id2 v1 v2 ## 1: e 0 -1 ## 2: n 0 -1 ## 3: u 0 -1 

En base a las útiles respuestas de @nmel y @BlueMagister, se me ocurrió esta solución para el escenario actualizado:

 DT1b[DT2b[DT1b[id1 %in% c(1,2)],nomatch=0],c("v1","v2"):=list(i.v1,i.v2)] DT1b ## id1 id2 v1 v2 ## 1: 2 e 0.0000000 -1.00000000 ## 2: 1 g 1.5952808 0.18484918 ## 3: 2 j 0.3295078 1.58784533 ## 4: 3 n -0.8204684 -1.13037567 ## 5: 3 s 0.5757814 -0.08025176 ## 6: 1 u 0.0000000 -1.00000000 

La forma más fácil en que puedo pensar es también mediante la clave id1 . p.ej

 setkey(DT1, id2,id1) DT2[, id1 := 3] setkey(DT2, id2, id1) # use i.v1 to reference v1 from the i component DT1[DT2, v1 := i.v1 ] DT1 id1 id2 v1 1: 2 e 0.7383247 2: 1 g 1.5952808 3: 2 j 0.3295078 4: 3 n 0.0000000 5: 3 s 0.5757814 6: 1 u 0.4874291 

Esto es similar a la solución de mnel pero usa ifelse lugar de una segunda clave.

 DT1[DT2, v1 := ifelse(id1==3, i.v1, v1),nomatch=0] 
    Intereting Posts