listas - ordenar un vector en r
Compruebe si dos vectores contienen los mismos elementos(no ordenados) en R (5)
Me gustaría comprobar si dos vectores contienen los mismos elementos, incluso si no tienen el mismo orden. Por ejemplo, la función (llamémosla SameElements
) debería satisfacer estos criterios:
SameElements(c(1, 2, 3), c(1, 2, 3)) # TRUE
SameElements(c(1, 2, 3), c(3, 2, 1)) # TRUE
SameElements(c(1, 2, 1), c(1, 2)) # FALSE
SameElements(c(1, 1, 2, 3), c(3, 2, 1)) # FALSE
Edición 1: especificó que la función debería devolver F cuando los vectores contienen los mismos elementos, pero con diferentes frecuencias.
Edición 2: Se limpió la pregunta para omitir la respuesta inicial, ya que ahora está en mi respuesta real.
Aquí está mi solución:
SameElements <- function (a,b){
l <- Map(table,list(a, b)) # Compute frequencies - returns ordered table
Reduce(identical,l) # Check if frequencies are the same for all input vectors
}
SameElements(c(1, 2, 3), c(1, 2, 3)) # TRUE
SameElements(c(1, 2, 3), c(3, 2, 1)) # TRUE
SameElements(c(1, 2, 1), c(1, 2)) # FALSE
SameElements(c(1, 1, 2, 3), c(3, 2, 1)) # FALSE
Como puede ver, funciona con cualquier número de vectores de entrada siempre que los ponga todos en una lista.
Un trazador de líneas:
Reduce(identical,Map(table,listOfVectors))
Básicamente, su problema puede resumirse en esos pasos:
if not same unique values: return FALSE
else if same Frequencies: return TRUE
else return True
En el código R apropiado:
SameElements = function(v1, v2)
{
tab1 = table(v1) ; tab2 = table(v2)
if( !all(names(tab1) == names(tab2)) ) return(FALSE) # Same unique values test
return(all(tab1==tab2)) # Same frequencies test
}
Algunos ejemplos :
v1 = c(1, 2, 3)
v2 = c(3, 2, 1)
SameElements(v1, v2) # TRUE as both uniqueness and frequencies test are verified
v1 = c(1,1, 2,3)
v2 =c(3,2,1)
S
ameElements (v1, v2) # FALSE porque se viola la prueba de frecuencias
PD: i) Puedes reemplazar !all()
por any()
~~~ ii) Para acelerar el código, puede devolver rápidamente FALSE
cuando los dos vectores no lo hacen
~~~ tienen la misma longitud, evitando así el cálculo de frecuencias.
Creo que puedes usar setequal(a,b)
Se actualizaron los controles de setequal
actualizados si dos vectores están compuestos de los mismos elementos pero no comprueba si estos elementos tienen las mismas apariciones en cada vector.
En lugar de una alternativa más limpia, aquí está la solución conocida:
SameElements <- function(a, b) return(identical(sort(a), sort(b)))
SameElements(c(1, 2, 3), c(1, 3, 2)) # TRUE
SameElements(c(1, 2, 3), c(1, 1, 3, 2)) # FALSE
Edición: identical
lugar de all.equal(...) == T
por sugerencia de nrussell.
Usted puede estar interesado en el paquete "comparar". Esta respuesta demuestra la función compare()
, pero para su caso, podría hacerlo bien con compareIgnoreOrder()
(que coincide casi exactamente con el título de su pregunta).
Hay varios argumentos que se pueden agregar como transformaciones que deberían permitirse al intentar comparar los elementos. En los ejemplos a continuación (para guardar algo de escritura), le pedí a la función que permita todas las transformaciones ( allowAll = TRUE
) excepto para cambiar la longitud del vector ( shorten = FALSE
).
library(compare)
compare(A1, A2, allowAll = TRUE, shorten = FALSE)
# TRUE
compare(A1, A3, allowAll = TRUE, shorten = FALSE)
# TRUE
# sorted
compare(A1, A4, allowAll = TRUE, shorten = FALSE)
# FALSE
# sorted
compare(B1, B2, allowAll = TRUE, shorten = FALSE)
# FALSE
# sorted
compare(B1, A4, allowAll = TRUE, shorten = FALSE)
# FALSE
# sorted
compare(A3f, A1, allowAll = TRUE, shorten = FALSE)
# TRUE
# coerced from <numeric> to <factor>
# sorted
Data de muestra:
A1 <- c(1, 2, 3); A2 <- c(1, 2, 3)
A3 <- c(3, 2, 1); A4 <- c(1, 1, 2, 3)
B1 <- c(1, 2, 1); B2 <- c(1, 2)
A3f <- factor(A3)