data.table
Se une y se fusiona
Buscar..
Introducción
?`[.data.table`
para los documentos oficiales.
Sintaxis
- x [i, on, j]
# join: data.table x & data.table o lista i - x [! i, on, j]
# anti-join
Observaciones
Trabajar con tablas con llave
Si x
& i
tiene una clave o x
se teclea para coincidir con las primeras columnas de i
, entonces el on
puede omitirse como x[i]
.
Desambiguación de nombres de columnas en común.
En j
de x[i, on, j]
, las columnas de i
pueden referirse con i.*
Prefijos.
Agrupación en subconjuntos
En j
de x[i, on, j, by=.EACHI]
, j
se calcula para cada fila de i
.
Este es el único valor de by
valor de usar. Para cualquier otro valor, las columnas de i
no están disponibles.
Actualizar valores en una unión
Cuando los datos están "ordenados" , a menudo se organizan en varias tablas. Para combinar los datos para el análisis, necesitamos "actualizar" una tabla con valores de otra.
Por ejemplo, podríamos tener datos de ventas para actuaciones, donde los atributos del ejecutante (su presupuesto) y de la ubicación (su población) se almacenan en tablas separadas:
set.seed(1)
mainDT = data.table(
p_id = rep(LETTERS[1:2], c(2,4)),
geo_id = sample(rep(state.abb[c(1,25,50)], 3:1)),
sales = sample(100, 6)
)
pDT = data.table(id = LETTERS[1:2], budget = c(60, 75))
geoDT = data.table(id = state.abb[c(1,50)], pop = c(100, 200))
mainDT # sales data
# p_id geo_id sales
# 1: A AL 95
# 2: A WY 66
# 3: B AL 62
# 4: B MO 6
# 5: B AL 20
# 6: B MO 17
pDT # performer attributes
# id budget
# 1: A 60
# 2: B 75
geoDT # location attributes
# id pop
# 1: AL 100
# 2: WY 200
Cuando estemos listos para hacer un análisis, necesitamos tomar variables de estas otras tablas:
DT = copy(mainDT)
DT[pDT, on=.(p_id = id), budget := i.budget]
DT[geoDT, on=.(geo_id = id), pop := i.pop]
# p_id geo_id sales budget pop
# 1: A AL 95 60 100
# 2: A WY 66 60 200
# 3: B AL 62 75 100
# 4: B MO 6 75 NA
# 5: B AL 20 75 100
# 6: B MO 17 75 NA
Se toma una copy
para evitar contaminar los datos sin procesar, pero podríamos trabajar directamente en mainDT
.
Ventajas de usar tablas separadas.
Las ventajas de esta estructura se tratan en el documento sobre datos ordenados, pero en este contexto:
Rastreo de datos faltantes. Sólo las filas que coinciden en la combinación reciben una asignación. No tenemos datos para
geo_id == "MO"
arriba, por lo que sus variables sonNA
en nuestra tabla final. Si vemos datos faltantes como este de forma inesperada, podemos rastrearlos hasta la observación faltante en la tablageoDT
e investigar desde allí si tenemos un problema de datos que se pueda solucionar.Comprensibilidad Al construir nuestro modelo estadístico, podría ser importante tener en cuenta que el
budget
es constante para cada actor. En general, la comprensión de la estructura de los datos paga dividendos.Tamaño de la memoria. Puede haber un gran número de atributos de ubicación y de ejecutante que no terminan en el modelo estadístico. De esta manera, no necesitamos incluirlos en la tabla (posiblemente masiva) utilizada para el análisis.
Columnas determinantes programáticamente
Si hay muchas columnas en pDT
, pero solo queremos seleccionar algunas, podemos usar
p_cols = "budget"
DT[pDT, on=.(p_id = id), (p_cols) := mget(sprintf("i.%s", p_cols))]
Los paréntesis alrededor de (p_cols) :=
son esenciales, como se indica en el documento al crear columnas .
Equi-unirse
# example data
a = data.table(id = c(1L, 1L, 2L, 3L, NA_integer_), x = 11:15)
# id x
# 1: 1 11
# 2: 1 12
# 3: 2 13
# 4: 3 14
# 5: NA 15
b = data.table(id = 1:2, y = -(1:2))
# id y
# 1: 1 -1
# 2: 2 -2
Intuición
Piense en x[i]
como seleccionar un subconjunto de x
para cada fila de i
. Esta sintaxis refleja el subconjunto de matriz en la base R y es consistente con el primer argumento que significa "dónde", en DT[where, select|update|do, by]
.
Uno podría preguntarse por qué vale la pena aprender esta nueva sintaxis, ya que merge(x,i)
aún funciona con data.tables. La respuesta corta es que normalmente queremos fusionarnos y luego hacer algo más. La sintaxis x[i]
captura de manera concisa este patrón de uso y también permite un cálculo más eficiente. Para una explicación más detallada, lea las preguntas frecuentes 1.12 y 2.14 .
Manejo de filas de múltiples partidos
De forma predeterminada, se devuelve cada fila de a
coincidencia con cada fila de b
:
a[b, on="id"]
# id x y
# 1: 1 11 -1
# 2: 1 12 -1
# 3: 2 13 -2
Esto puede ser ajustado con mult
:
a[b, on="id", mult="first"]
# id x y
# 1: 1 11 -1
# 2: 2 13 -2
Manejando filas incomparables
De forma predeterminada, las filas no coincidentes de a
muestran en el resultado:
b[a, on="id"]
# id y x
# 1: 1 -1 11
# 2: 1 -1 12
# 3: 2 -2 13
# 4: 3 NA 14
# 5: NA NA 15
Para ocultar estos, use nomatch
:
b[a, on="id", nomatch=0]
# id y x
# 1: 1 -1 11
# 2: 1 -1 12
# 3: 2 -2 13
Tenga en cuenta que x[i]
intentará hacer coincidir las NA en i
.
Contando partidos devueltos
Para contar el número de coincidencias para cada fila de i
, use .N
y by=.EACHI
.
b[a, on="id", .N, by=.EACHI]
# id N
# 1: 1 1
# 2: 1 1
# 3: 2 1
# 4: 3 0
# 5: NA 0