Tengo los siguientes 2 data.frames:
a1 <- data.frame(a = 1:5, b=letters[1:5])
a2 <- data.frame(a = 1:3, b=letters[1:3])
Quiero encontrar la fila a1 que a2 no tiene.
¿Existe una función integrada para este tipo de operación?
(PD: escribí una solución para ello, simplemente tengo curiosidad por saber si alguien ya hizo un código más elaborado)
Aquí está mi solución:
a1 <- data.frame(a = 1:5, b=letters[1:5])
a2 <- data.frame(a = 1:3, b=letters[1:3])
rows.in.a1.that.are.not.in.a2 <- function(a1,a2)
{
a1.vec <- apply(a1, 1, paste, collapse = "")
a2.vec <- apply(a2, 1, paste, collapse = "")
a1.without.a2.rows <- a1[!a1.vec %in% a2.vec,]
return(a1.without.a2.rows)
}
rows.in.a1.that.are.not.in.a2(a1,a2)
a2 <- data.frame(a = c(1:3, 1), b = c(letters[1:3], "c"))
. Dejaa1
lo mismo. Ahora prueba la comparación. No me resulta claro, incluso al leer las opciones, cuál es la forma correcta de enumerar solo elementos comunes.SQLDF
proporciona una buena soluciónY las filas que están en ambos marcos de datos:
La nueva versión de
dplyr
tiene una funciónanti_join
, para exactamente este tipo de comparacionesY
semi_join
para filtrar filas ena1
que también están ena2
fuente
anti_join
ysemi_join
!En dplyr :
Básicamente,
setdiff(bigFrame, smallFrame)
te da los registros adicionales en la primera tabla.En el SQLverse esto se llama un
Para obtener buenas descripciones de todas las opciones de unión y establecer temas, este es uno de los mejores resúmenes que he visto hasta la fecha: http://www.vertabelo.com/blog/technical-articles/sql-joins
Pero volviendo a esta pregunta, estos son los resultados del
setdiff()
código cuando se utilizan los datos del OP:O incluso
anti_join(a1,a2)
obtendrá los mismos resultados.Para más información: https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf
fuente
a1
que no están ena2
, ¿no quieres usar algo comosemi_join(a1, a2, by = c('a','b'))
? En la respuesta de "Rickard", veo quesemi_join
se sugirió.setdiff()
función base que funciona en dos vectores: stat.ethz.ch/R-manual/R-devel/library/base/html/sets.html . ¿Tal vez ha cargado la biblioteca lubridate después de dplyr y está sugiriéndola como la fuente en la lista completa?Ciertamente no es eficiente para este propósito en particular, pero lo que hago a menudo en estas situaciones es insertar variables indicadoras en cada marco de datos y luego fusionarlas:
los valores faltantes en included_a1 indicarán qué filas faltan en a1. de manera similar para a2.
Un problema con su solución es que los pedidos de columna deben coincidir. Otro problema es que es fácil imaginar situaciones en las que las filas están codificadas de la misma manera cuando en realidad son diferentes. La ventaja de usar merge es que obtiene de forma gratuita todas las comprobaciones de errores necesarias para una buena solución.
fuente
included_a1
? : - /Escribí un paquete ( https://github.com/alexsanjoseph/compareDF ) ya que tuve el mismo problema.
Un ejemplo más complicado:
El paquete también tiene un comando html_output para una verificación rápida
fuente
The two data frames have different columns!
Puede usar el
daff
paquete (que envuelve ladaff.js
biblioteca usando elV8
paquete ):produce el siguiente objeto de diferencia:
El formato de diferencias se describe en el formato de diferencias de resaltador Coopy para tablas y debe explicarse bastante por sí mismo. Las líneas con
+++
en la primera columna@@
son las que son nuevasa1
y no están presentes ena2
.El objeto de diferencia se puede usar para
patch_data()
almacenar la diferencia con fines de documentación usandowrite_diff()
o para visualizar la diferencia usandorender_diff()
:genera una salida HTML ordenada:
fuente
Usando el
diffobj
paquete:fuente
Adapté la
merge
función para obtener esta funcionalidad. En marcos de datos más grandes, utiliza menos memoria que la solución de fusión completa. Y puedo jugar con los nombres de las columnas clave.Otra solución es usar la biblioteca
prob
.fuente
Sus datos de ejemplo no tienen duplicados, pero su solución los maneja automáticamente. Esto significa que potencialmente algunas de las respuestas no coincidirán con los resultados de su función en caso de duplicados.
Aquí está mi solución, cuya dirección se duplica de la misma manera que la suya. ¡También escala muy bien!
Necesita data.table 1.9.8+
fuente
Tal vez sea demasiado simplista, pero utilicé esta solución y la encuentro muy útil cuando tengo una clave principal que puedo usar para comparar conjuntos de datos. Espero que pueda ayudar.
fuente
Otra solución más basada en match_df en plyr. Aquí está el match_df de plyr:
Podemos modificarlo para negar:
Luego:
fuente
Utilizando
subset
:fuente
El siguiente código usa ambos
data.table
yfastmatch
para aumentar la velocidad.fuente