es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Qué filas/columnas son duplicadas de qué otras en las matrices R?

Tengo una matriz con muchas filas y columnas, de la siguiente manera:

x <- matrix(c(1, 1, 3, 3, 55, 55, 1, 3, 3, 1,
              1, 1, 3, 3, 55, 55, 1, 3, 9, 1), ncol = 2)

Mi problema:

Dentro de cada grupo de filas duplicadas (es decir, cada conjunto de filas idénticas), quiero identificar el índice de la primera fila y asignarlo a todas las ocurrencias dentro de ese grupo. Por ejemplo, hay varias filas duplicadas con ‘1’ en ambas columnas (en las filas 1, 2, 7, 10). En cada una de estas filas quiero el índice de la primera fila, es decir, 1.

x

[,1] [,2]

[1,]    1    1 # primera fila de 1-1. Asignar su índice de fila, 1, a todas las filas 1-1

[2,]    1    1

[3,]    3    3 # primera fila de 3-3. Asignar su índice de fila, 3, a todas las filas 3-3

[4,]    3    3

[5,]   55   55 # primera fila de 55-55. Asignar su índice de fila, 5, a todas las filas 55-55

[6,]   55   55

[7,]    1    1

[8,]    3    3

[9,]    3    9 # primera (y única) fila de 3-9; índice de fila 9

[10,]    1    1

Resultado deseado:

1 1 3 3 5 5 1 3 9 1

Mi intento:

Lo mejor que se me ocurrió es un enfoque complicado basado en duplicados y bucles for, que no es eficiente ni elegante. También conozco posibles soluciones para data.frames; aquellas que implican concatenar filas en cadenas también consumen muchos recursos.


Identificar duplicados duplicate <- duplicated(x, MARGIN = 1) Identificar primera ocurrencia de cada duplicado firstDup <- duplicated(x, MARGIN = 1, fromLast = TRUE) & !duplicate indices <- which(firstDup) Inicializar índice para filas únicas index <- seq_len(dim(x)[1]) cf <- duplicate for (i in indices) { # Los duplicados deben ocurrir después de la primera aparición cf[seq_len(i)] <- FALSE dups <- apply(x[cf, , drop = FALSE], 1L, identical, x[i, ]) index[which(cf)[dups]] <- i } index

¿Existe una solución elegante utilizando R base?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una solución más elegante utilizando funciones base de R. Puedes usar match() para obtener el primer índice de cada fila única, y luego usar replace() para reemplazar todas las ocurrencias de cada fila duplicada con ese índice. Aquí está el código:

    # Obtén los índices de la primera ocurrencia de cada fila única
    firstIndex <- match(unique(x), x, nomatch = 0)
    
    # Reemplaza cada fila duplicada con el primer índice
    result <- replace(match(x, unique(x), nomatch = 0),
                      duplicated(x),
                      firstIndex[match(x[duplicated(x), ], unique(x))])
    
    result
    # [1] 1 1 3 3 5 5 1 3 9 1
    

    Este código primero usa match(unique(x), x) para obtener el índice de la primera ocurrencia de cada fila única. El argumento nomatch = 0 asegura que las filas que no tienen coincidencia (es decir, aquellas que solo ocurren una vez) devuelvan 0.

    A continuación, se utiliza match(x, unique(x)) para obtener el índice de la fila única que cada fila en x coincide. Nuevamente, se utiliza nomatch = 0 para asegurarse de que las filas no duplicadas devuelvan 0.

    Finalmente, se utiliza replace() para reemplazar cada fila duplicada con el primer índice de esa fila. Esto se hace indexando en firstIndex[match(x[duplicated(x), ], unique(x))], lo cual devuelve el índice de la primera ocurrencia de cada fila duplicada. La función match() se utiliza para encontrar el índice de cada fila duplicada en unique(x), y duplicated(x) se utiliza para seleccionar solo las filas duplicadas. El vector resultante de índices luego se utiliza para reemplazar las filas duplicadas en el vector original.

    ¡Espero que esto ayude!

Comments are closed.