Saltar al contenido principal
LibreTexts Español

7.6: Clasificación, volteo y fusión de datos

  • Page ID
    151579
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    En esta sección discuto algunas operaciones útiles que siento que están vagamente relacionadas entre sí: ordenar un vector, ordenar un marco de datos, unir dos o más vectores juntos en un marco de datos (o matriz), y voltear un marco de datos (o matriz) de su lado. Todas son tareas bastante sencillas, al menos en comparación con algunos de los problemas de manejo de datos más odiosos que aparecen en la vida real.

    Ordenar un vector numérico o de caracteres

    Una cosa que a menudo quieres hacer es ordenar una variable. Si se trata de una variable numérica, es posible que desee ordenar en orden creciente o decreciente. Si se trata de un vector de caracteres, es posible que desee ordenar alfabéticamente, etc. La función sort () proporciona esta capacidad.

    numbers <- c(2,4,3)
    sort( x = numbers )
    ## [1] 2 3 4

    Puedes pedir R para ordenar en orden decreciente en lugar de aumentar:

    sort( x = numbers, decreasing = TRUE )
    ## [1] 4 3 2

    Y puedes pedirle que ordene los datos de texto en orden alfabético:

    text <- c("aardvark", "zebra", "swing")
    sort( text )
    ## [1] "aardvark" "swing"    "zebra"

    Eso es bastante sencillo. Dicho esto, es importante señalar que estoy pasando por alto algo aquí. Cuando aplicas sort () a un vector de caracteres, no se ordena estrictamente en orden alfabético. R en realidad tiene una noción ligeramente diferente de cómo se ordenan los caracteres (ver Sección 7.8.5 y Tabla 7.3), que está más estrechamente relacionada con cómo las computadoras almacenan datos de texto que con cómo se ordenan las letras en el alfabeto. Sin embargo, ese es un tema que discutiremos más adelante. Por ahora, lo único que debo señalar es que la función sort () no altera la variable original. Más bien, crea una nueva variable ordenada como salida. Entonces, si inspecciono mi variable de texto original:

    text
    ## [1] "aardvark" "zebra"    "swing"

    Puedo ver que se ha mantenido sin cambios.

    Clasificación de un factor

    También puedes ordenar factores, pero la historia aquí es un poco más sutil porque hay dos formas diferentes de ordenar un factor: alfabéticamente (por etiqueta) o por nivel de factor. La función sort () usa esta última. Para ilustrar, veamos los dos ejemplos diferentes. Primero, vamos a crear un factor de la manera habitual:

    fac <- factor( text )
    fac
    ## [1] aardvark zebra    swing   
    ## Levels: aardvark swing zebra

    Ahora vamos a ordenarlo:

    sort(fac)
    ## [1] aardvark swing    zebra   
    ## Levels: aardvark swing zebra

    Esto parece que está ordenado las cosas en orden alfabético, pero eso es sólo porque los niveles de los factores en sí mismos pasan a estar ordenados alfabéticamente. Supongamos que defino deliberadamente los niveles de los factores en un orden no alfabético:

    fac <- factor( text, levels = c("zebra","swing","aardvark") )
    fac
    ## [1] aardvark zebra    swing   
    ## Levels: zebra swing aardvark

    Ahora, ¿qué pasa cuando intentamos ordenar fac esta vez? La respuesta:

    sort(fac)
    ## [1] zebra    swing    aardvark
    ## Levels: zebra swing aardvark

    Ordena los datos en el orden numérico implícito por los niveles de los factores, no el orden alfabético implícito por las etiquetas adjuntas a esos niveles. Normalmente nunca se nota la distinción, porque por defecto los niveles de los factores se asignan en orden alfabético, pero es importante conocer la diferencia:

    Ordenar un marco de datos

    La función sort () no funciona correctamente con los marcos de datos. Si desea ordenar un marco de datos, el consejo estándar que encontrará en línea es usar la función order () (no descrita en este libro) para determinar en qué orden deben ordenarse las filas, y luego usar corchetes para hacer el barajado. No hay nada intrínsecamente malo en este consejo, solo lo encuentro tedioso. Para ello, el paquete lsr incluye una función llamada sortFrame () que puedes usar para hacer la clasificación. El primer argumento de la función se llama (x), y debe corresponder al marco de datos que desea ordenar. Después de eso, todo lo que haces es escribir una lista de los nombres de las variables que quieres usar para hacer la clasificación. Por ejemplo, si escribo esto:

    sortFrame( garden, speaker, line)
    ##            speaker utterance line
    ## case.4 makka-pakka       pip    7
    ## case.5 makka-pakka       onk    9
    ## case.3   tombliboo        ee    5
    ## case.1  upsy-daisy       pip    1
    ## case.2  upsy-daisy       pip    2

    lo que hace R es primero ordenar por hablante (orden de nivel de factor). Cualquier vínculo (es decir, datos del mismo orador) se ordena entonces en orden de línea (aumentando el orden numérico). Puede usar el signo menos para indicar que las variables numéricas deben ordenarse en orden inverso:

    sortFrame( garden, speaker, -line)
    ##            speaker utterance line
    ## case.5 makka-pakka       onk    9
    ## case.4 makka-pakka       pip    7
    ## case.3   tombliboo        ee    5
    ## case.2  upsy-daisy       pip    2
    ## case.1  upsy-daisy       pip    1

    A partir de la escritura actual, la función sortFrame () está en desarrollo. Empecé a introducir funcionalidad para permitirle usar el signo - a variables no numéricas o hacer una distinción entre factores de clasificación alfabéticamente o por nivel de factor. La idea es que deberías poder escribir algo como esto:

    sortFrame( garden, -speaker)

    y que la salida corresponda a una especie de marco de datos del jardín en orden alfabético inverso (o orden de nivel de factor inverso) del hablante. Tal como están las cosas en este momento, esto realmente funcionará y producirá una salida sensata:

    sortFrame( garden, -speaker)
    ##            speaker utterance line
    ## case.1  upsy-daisy       pip    1
    ## case.2  upsy-daisy       pip    2
    ## case.3   tombliboo        ee    5
    ## case.4 makka-pakka       pip    7
    ## case.5 makka-pakka       onk    9

    Sin embargo, no estoy completamente convencido de que haya configurado esto de la manera ideal, así que esto puede cambiar un poco en el futuro.

    Vectores de unión juntos

    Una tarea no infrecuente que podrías encontrarte necesitando emprender es combinar varios vectores. Por ejemplo, supongamos que tenemos los dos vectores numéricos siguientes:

    cake.1 <- c(100, 80, 0, 0, 0)
    cake.2 <- c(100, 100, 90, 30, 10)

    Los números aquí podrían representar la cantidad de cada uno de los dos pasteles que quedan en cinco momentos diferentes. Al parecer el primer pastel es más sabroso, ya que ese se devora más rápido. Ya hemos visto un método para combinar estos vectores: podríamos usar la función data.frame () para convertirlos en un marco de datos con dos variables, así:

    cake.df <- data.frame( cake.1, cake.2 )
    cake.df
    
    ##   cake.1 cake.2
    ## 1    100    100
    ## 2     80    100
    ## 3      0     90
    ## 4      0     30
    ## 5      0     10

    Otros dos métodos a los que quiero referirme brevemente son las funciones rbind () y cbind (), que convertirán los vectores en una matriz. Discutiré las matrices correctamente en la Sección 7.11.1 pero los detalles no importan demasiado para nuestros propósitos actuales. La función cbind () (“column bind”) produce una salida de aspecto muy similar al ejemplo del marco de datos:

    cake.mat1 <- cbind( cake.1, cake.2 )
    cake.mat1
    ##      cake.1 cake.2
    ## [1,]    100    100
    ## [2,]     80    100
    ## [3,]      0     90
    ## [4,]      0     30
    ## [5,]      0     10

    pero sin embargo es importante tener en cuenta que cake.mat1 es una matriz en lugar de un marco de datos, y así tiene algunas diferencias con respecto a la variable cake.df. La función rbind () (“row bind”) produce una salida algo diferente: une los vectores juntos por filas en lugar de columnas, por lo que la salida ahora se ve así:

    cake.mat2 <- rbind( cake.1, cake.2 )
    cake.mat2
    
    ##        [,1] [,2] [,3] [,4] [,5]
    ## cake.1  100   80    0    0    0
    ## cake.2  100  100   90   30   10

    Puedes agregar nombres a una matriz usando las funciones rownames () y colnames (), y también debo señalar que hay una función más elegante en R llamada merge () que admite la fusión más complicada de “database like” de vectores y marcos de datos, pero no voy a entrar en detalles aquí.

    Enlazar múltiples copias del mismo vector

    A veces es muy útil unir múltiples copias del mismo vector. Podrías hacer esto usando las funciones rbind y cbind, usando comands como este

    fibonacci <- c( 1,1,2,3,5,8 )
    rbind( fibonacci, fibonacci, fibonacci )
    ##           [,1] [,2] [,3] [,4] [,5] [,6]
    ## fibonacci    1    1    2    3    5    8
    ## fibonacci    1    1    2    3    5    8
    ## fibonacci    1    1    2    3    5    8

    pero eso puede ser bastante molesto, sobre todo si necesitas muchas copias. Para que esto sea un poco más fácil, el paquete lsr tiene dos funciones adicionales RowCopy y ColCopy que hacen el mismo trabajo, pero todo lo que tienes que hacer es especificar el número de copias que deseas, en lugar de escribir el nombre una y otra vez. Los dos argumentos que necesitas especificar son x, el vector a copiar, y times, indicando cuántas copias se deben crear: 117

    rowCopy( x = fibonacci, times = 3 )
    ##      [,1] [,2] [,3] [,4] [,5] [,6]
    ## [1,]    1    1    2    3    5    8
    ## [2,]    1    1    2    3    5    8
    ## [3,]    1    1    2    3    5    8

    Por supuesto, en la práctica no es necesario nombrar los argumentos todo el tiempo. Por ejemplo, aquí hay un ejemplo usando la función colCopy () con los nombres de los argumentos omitidos:

    colCopy( fibonacci, 3 )
    ##      [,1] [,2] [,3]
    ## [1,]    1    1    1
    ## [2,]    1    1    1
    ## [3,]    2    2    2
    ## [4,]    3    3    3
    ## [5,]    5    5    5
    ## [6,]    8    8    8

    Transposición de una matriz o marco de datos

    load("./rbook-master/data/cakes.Rdata" )
    cakes
    ##        time.1 time.2 time.3 time.4 time.5
    ## cake.1    100     80      0      0      0
    ## cake.2    100    100     90     30     10
    ## cake.3    100     20     20     20     20
    ## cake.4    100    100    100    100    100

    Y solo para asegurarte de que me crees que esto es en realidad una matriz:

    class( cakes )
    ## [1] "matrix"

    Bien, ahora transpongamos la matriz:

    cakes.flipped <- t( cakes )
    cakes.flipped
    ##        cake.1 cake.2 cake.3 cake.4
    ## time.1    100    100    100    100
    ## time.2     80    100     20    100
    ## time.3      0     90     20    100
    ## time.4      0     30     20    100
    ## time.5      0     10     20    100

    La salida aquí sigue siendo una matriz:

    class( cakes.flipped )
    
    ## [1] "matrix"

    En este punto deberías tener dos preguntas: (1) ¿cómo hacemos lo mismo con los marcos de datos? y (2) ¿por qué deberíamos preocuparnos por esto? Empecemos con la pregunta de cómo. Primero, debo señalar que puedes transponer un marco de datos bien usando la función t (), pero eso tiene la consecuencia un poco incómoda de convertir la salida de un marco de datos a una matriz, que no suele ser lo que quieres. Es bastante fácil volver a convertir la salida, claro, 118 pero odio escribir dos comandos cuando puedo hacerlo con uno. Para ello, el paquete lsr tiene una función simple de “conveniencia” llamada tFrame () que hace exactamente lo mismo que t () pero convierte la salida en un marco de datos para usted. Para ilustrar esto, transpongamos el marco de datos itng que usamos anteriormente. Aquí está el marco de datos original:

    itng
    ##        speaker utterance
    ## 1   upsy-daisy       pip
    ## 2   upsy-daisy       pip
    ## 3   upsy-daisy       onk
    ## 4   upsy-daisy       onk
    ## 5    tombliboo        ee
    ## 6    tombliboo        oo
    ## 7  makka-pakka       pip
    ## 8  makka-pakka       pip
    ## 9  makka-pakka       onk
    ## 10 makka-pakka       onk

    y esto es lo que sucede cuando lo transpones usando tFrame ():

    tFrame( itng )
    ##                   V1         V2         V3         V4        V5        V6
    ## speaker   upsy-daisy upsy-daisy upsy-daisy upsy-daisy tombliboo tombliboo
    ## utterance        pip        pip        onk        onk        ee        oo
    ##                    V7          V8          V9         V10
    ## speaker   makka-pakka makka-pakka makka-pakka makka-pakka
    ## utterance         pip         pip         onk         onk

    Un punto importante a reconocer es que transponer un marco de datos no siempre es algo sensato de hacer: de hecho, iría tan lejos como para argumentar que generalmente no es sensato. Depende mucho de si los “casos” de tu marco de datos original tendrían sentido como variables, y pensar en cada una de tus “variables” originales como casos. Creo que eso enfáticamente no es cierto para nuestro marco de datos itng, así que no aconsejaría hacerlo en esta situación.

    Dicho esto, a veces es realmente cierto. Por ejemplo, si hubiéramos almacenado originalmente nuestra variable cakes como un marco de datos en lugar de una matriz, ¡entonces sería absolutamente sensato voltear el marco de datos! 119 Hay algunas situaciones en las que es útil voltear tu marco de datos, así que es bueno saber que puedes hacerlo. En efecto, esa es la razón principal por la que he pasado tanto tiempo hablando de este tema. Muchas herramientas estadísticas hacen la suposición de que las filas de su marco de datos (o matriz) corresponden a observaciones, y las columnas corresponden a las variables. Eso no es irrazonable, claro, ya que esa es una convención bastante estándar. No obstante, piensa en nuestro ejemplo de pasteles aquí. Esta es una situación en la que quizás quieras hacer un análisis de los diferentes pasteles (es decir, pasteles como variables, puntos de tiempo como casos), pero igualmente podrías querer hacer un análisis donde pienses que los tiempos son las cosas de interés (es decir, tiempos como variables, pasteles como casos). Si es así, entonces es útil saber cómo voltear una matriz o un marco de datos.


    This page titled 7.6: Clasificación, volteo y fusión de datos is shared under a CC BY-SA 4.0 license and was authored, remixed, and/or curated by Danielle Navarro via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.