Saltar al contenido principal
LibreTexts Español

7.7: Remodelación de un Marco de Datos

  • Page ID
    151631
  • \( \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}}\)

    Una de las tareas más molestas que debes realizar de forma regular es la de remodelar un marco de datos. Enmarcados de la manera más general, remodelar los datos significa tomar los datos en cualquier formato que se te den, y convertirlos al formato que necesites. Por supuesto, si vamos a caracterizar el problema de manera tan amplia, entonces aproximadamente la mitad de este capítulo probablemente pueda pensarse como una especie de remodelación. Así que vamos a tener que reducir un poco las cosas. Para ello, voy a hablar de algunas herramientas diferentes que puedes usar para algunas tareas diferentes. En particular, voy a discutir un par de funciones fáciles de usar (pero limitadas) que he incluido en el paquete lsr. En futuras versiones del libro planeo ampliar esta discusión para incluir algunas de las herramientas más poderosas que están disponibles en R, pero aún no he tenido tiempo para hacerlo.

    Datos de formato largo y ancho

    El formato más común en el que podrías obtener datos es como un diseño “caso por variable”, comúnmente conocido como la forma amplia de los datos.

    load("./rbook-master/data/repeated.Rdata")
    who()
    ##    -- Name --         -- Class --   -- Size --
    ##    age                numeric       11        
    ##    age.breaks         numeric       4         
    ##    age.group          factor        11        
    ##    age.group2         factor        11        
    ##    age.group3         factor        11        
    ##    age.labels         character     3         
    ##    cake.1             numeric       5         
    ##    cake.2             numeric       5         
    ##    cake.df            data.frame    5 x 2     
    ##    cake.mat1          matrix        5 x 2     
    ##    cake.mat2          matrix        2 x 5     
    ##    cakes              matrix        4 x 5     
    ##    cakes.flipped      matrix        5 x 4     
    ##    choice             data.frame    4 x 10    
    ##    df                 data.frame    4 x 1     
    ##    drugs              data.frame    10 x 8    
    ##    fac                factor        3         
    ##    fibonacci          numeric       6         
    ##    garden             data.frame    5 x 3     
    ##    is.MP.speaking     logical       5         
    ##    itng               data.frame    10 x 2    
    ##    itng.table         table         3 x 4     
    ##    likert.centred     numeric       10        
    ##    likert.raw         numeric       10        
    ##    makka.pakka        character     4         
    ##    numbers            numeric       3         
    ##    opinion.dir        numeric       10        
    ##    opinion.strength   numeric       10        
    ##    some.data          numeric       18        
    ##    speaker            character     10        
    ##    speech.by.char     list          3         
    ##    text               character     3         
    ##    tombliboo          character     2         
    ##    upsy.daisy         character     4         
    ##    utterance          character     10

    Para tener una idea de lo que estoy hablando, considera un experimento en el que nos interesen los diferentes efectos que el alcohol y la cafeína tienen sobre la capacidad de memoria de trabajo (WMC) de las personas y los tiempos de reacción (RT). Reclutamos a 10 participantes, y medimos su WMC y RT bajo tres condiciones diferentes: una condición de “no droga”, en la que no están bajo la influencia ni de la cafeína ni del alcohol, una condición de “cafeína”, en la que se encuentran bajo la inflexión de la cafeína, y una condición de “alcohol”, en la que... bueno, se puede probablemente adivine. Idealmente, supongo, habría una cuarta condición en la que se administren ambos fármacos, pero en aras de la simplicidad ignoremos eso. El marco de datos de drogas te da una idea de qué tipo de datos podrías observar en un experimento como este:

    drugs
    ##    id gender WMC_alcohol WMC_caffeine WMC_no.drug RT_alcohol RT_caffeine
    ## 1   1 female         3.7          3.7         3.9        488         236
    ## 2   2 female         6.4          7.3         7.9        607         376
    ## 3   3 female         4.6          7.4         7.3        643         226
    ## 4   4   male         6.4          7.8         8.2        684         206
    ## 5   5 female         4.9          5.2         7.0        593         262
    ## 6   6   male         5.4          6.6         7.2        492         230
    ## 7   7   male         7.9          7.9         8.9        690         259
    ## 8   8   male         4.1          5.9         4.5        486         230
    ## 9   9 female         5.2          6.2         7.2        686         273
    ## 10 10 female         6.2          7.4         7.8        645         240
    ##    RT_no.drug
    ## 1         371
    ## 2         349
    ## 3         412
    ## 4         252
    ## 5         439
    ## 6         464
    ## 7         327
    ## 8         305
    ## 9         327
    ## 10        498

    Se trata de un conjunto de datos en “forma amplia”, en el que cada participante corresponde a una sola fila. Tenemos dos variables que son características del sujeto (es decir, su número de identificación y su género) y seis variables que hacen referencia a una de las dos variables medidas (CMM o RT) en una de las tres condiciones de prueba (alcohol, cafeína o ninguna droga). Debido a que todas las condiciones de prueba (es decir, los tres tipos de medicamentos) se aplican a todos los participantes, el tipo de medicamento es un ejemplo de un factor dentro del sujeto.

    Remodelación de datos usando WideToLong ()

    La “forma amplia” de este conjunto de datos es útil para algunas situaciones: a menudo es muy útil que cada fila corresponda a un solo sujeto. Sin embargo, no es la única forma en la que quizás quieras organizar estos datos. Por ejemplo, es posible que desee tener una fila separada para cada “ocasión de prueba”. Es decir, “el participante 1 bajo la influencia del alcohol” sería una fila, y “el participante 1 bajo la influencia de la cafeína” sería otra fila. Esta forma de organizar los datos generalmente se conoce como la forma larga de los datos. No es muy difícil cambiar entre formato ancho y largo, y voy a explicar cómo funciona en un momento; por ahora, solo echemos un vistazo a cómo es la forma larga de este conjunto de datos:

    drugs.2 <- wideToLong( data = drugs, within = "drug" )
    head(drugs.2)
    ##   id gender    drug WMC  RT
    ## 1  1 female alcohol 3.7 488
    ## 2  2 female alcohol 6.4 607
    ## 3  3 female alcohol 4.6 643
    ## 4  4   male alcohol 6.4 684
    ## 5  5 female alcohol 4.9 593
    ## 6  6   male alcohol 5.4 492

    El marco de datos drogas.2 que acabamos de crear tiene 30 filas: cada uno de los 10 participantes aparece en tres filas separadas, una correspondiente a cada una de las tres condiciones de prueba. Y en lugar de tener una variable como WMC_cafeína que indica que estábamos midiendo “WMC” en la condición de “cafeína”, esta información ahora se registra en dos variables separadas, una llamada droga y otra llamada WMC. Obviamente, las formas largas y amplias de los datos contienen la misma información, pero representan formas bastante diferentes de organizar esa información. A veces te encuentras necesitando analizar datos de forma amplia, y a veces encuentras que necesitas una forma larga. Entonces es realmente útil saber cómo cambiar entre los dos.

    En el ejemplo que di anteriormente, utilicé una función llamada WideToLong () para hacer la transformación. La función WideToLong () es parte del paquete lsr. La clave para entender esta función es que se basa en los nombres de las variables para hacer todo el trabajo. Observe que los nombres de las variables en el marco de datos de medicamentos siguen un esquema muy claro. Siempre que tengas una variable con un nombre como WMC_Cafeína sabes que la variable que se mide es “WMC”, y que la condición específica en la que se está midiendo es la condición de “cafeína”. De igual manera, usted sabe que RT_NO.drug se refiere a la variable “RT” medida en el padecimiento “sin fármaco”. La variable medida viene primero (por ejemplo, WMC), seguida de un carácter separador (en este caso el separador es un subrayado, _), y luego el nombre de la condición en la que se está midiendo (por ejemplo, cafeína). Hay dos prefijos diferentes (es decir, las cadenas antes del separador, WMC, RT) lo que significa que hay dos variables separadas que se están midiendo. Hay tres sufijos diferentes (es decir, las cadenas después del separtador, cafeína, alcohol, no.droga) lo que significa que hay tres niveles diferentes del factor dentro del sujeto. Finalmente, observe que la cadena separadora (i.e., _) no aparece en ninguna parte de dos de las variables (id, género), lo que indica que se trata de variables entre sujetos, es decir, variables que no varían dentro de participante ( ej., el género de una persona es el mismo independientemente de si está bajo la influencia del alcohol, la cafeína, etc.).

    Debido a que el esquema de nomenclatura de variables aquí es tan informativo, es muy posible remodelar el marco de datos sin ninguna entrada adicional del usuario. Por ejemplo, en este caso en particular, podría simplemente escribir lo siguiente:

    wideToLong( drugs )
    ##    id gender   within WMC  RT
    ## 1   1 female  alcohol 3.7 488
    ## 2   2 female  alcohol 6.4 607
    ## 3   3 female  alcohol 4.6 643
    ## 4   4   male  alcohol 6.4 684
    ## 5   5 female  alcohol 4.9 593
    ## 6   6   male  alcohol 5.4 492
    ## 7   7   male  alcohol 7.9 690
    ## 8   8   male  alcohol 4.1 486
    ## 9   9 female  alcohol 5.2 686
    ## 10 10 female  alcohol 6.2 645
    ## 11  1 female caffeine 3.7 236
    ## 12  2 female caffeine 7.3 376
    ## 13  3 female caffeine 7.4 226
    ## 14  4   male caffeine 7.8 206
    ## 15  5 female caffeine 5.2 262
    ## 16  6   male caffeine 6.6 230
    ## 17  7   male caffeine 7.9 259
    ## 18  8   male caffeine 5.9 230
    ## 19  9 female caffeine 6.2 273
    ## 20 10 female caffeine 7.4 240
    ## 21  1 female  no.drug 3.9 371
    ## 22  2 female  no.drug 7.9 349
    ## 23  3 female  no.drug 7.3 412
    ## 24  4   male  no.drug 8.2 252
    ## 25  5 female  no.drug 7.0 439
    ## 26  6   male  no.drug 7.2 464
    ## 27  7   male  no.drug 8.9 327
    ## 28  8   male  no.drug 4.5 305
    ## 29  9 female  no.drug 7.2 327
    ## 30 10 female  no.drug 7.8 498

    Esto es bastante bueno, en realidad. El único pensamiento que se ha equivocado aquí es que no sabe qué nombre asignar al factor dentro del sujeto, así que instaed de llamarlo algo sensato como droga, ha usado el nombre inimaginativo dentro. Si desea asegurarse de que la función WideToLong () aplique un nombre sensible, debe especificar el argumento within, que es solo una cadena de caracteres que especifica el nombre del factor dentro del sujeto. Entonces, cuando usé este comando antes,

    drugs.2 <- wideToLong( data = drugs, within = "drug" )

    todo lo que estaba haciendo era decirle a R que usara drogas como el nombre del factor dentro del sujeto.

    Ahora, como estaba insinuando antes, la función WideToLong () es muy inflexible. Requiere que todos los nombres de las variables sigan este esquema de nomenclatura que señalé anteriormente. Si no sigues este esquema de nomenclatura no funcionará. 120 La única flexibilidad que he incluido aquí es que puedes cambiar el carácter separador especificando el argumento sep. Por ejemplo, si estuvieras usando nombres de variables de la forma WMC/Cafeína, por ejemplo, podrías especificar que sep=”/”, usando un comando como este

    drugs.2 <- wideToLong( data = drugs, within = "drug", sep = "/" )

    y seguiría funcionando.

    Remodelación de datos usando LongToWide ()

    Para convertir datos de formato largo a formato ancho, el paquete lsr también incluye una función llamada longToWide (). Recordemos desde antes que la forma larga de los datos (es decir, el marco de datos fármacos.2) contiene variables llamadas id, género, droga, WMC y RT. Para convertir de forma larga a forma ancha, todo lo que necesita hacer es indicar cuáles de estas variables se miden por separado para cada condición (es decir, WMC y RT), y qué variable es el factor dentro del sujeto que especifica la condición (es decir, fármaco). Esto se hace a través de una fórmula de dos caras, en la que las variables medidas están en el lado izquierdo, y el factor dentro del sujeto está en el lado derecho de la mano. En este caso, la fórmula sería WMC + RT ~ fármaco. Entonces el comando que usaríamos podría verse así:

    longToWide( data=drugs.2, formula= WMC+RT ~ drug )
    ##    id gender WMC_alcohol RT_alcohol WMC_caffeine RT_caffeine WMC_no.drug
    ## 1   1 female         3.7        488          3.7         236         3.9
    ## 2   2 female         6.4        607          7.3         376         7.9
    ## 3   3 female         4.6        643          7.4         226         7.3
    ## 4   4   male         6.4        684          7.8         206         8.2
    ## 5   5 female         4.9        593          5.2         262         7.0
    ## 6   6   male         5.4        492          6.6         230         7.2
    ## 7   7   male         7.9        690          7.9         259         8.9
    ## 8   8   male         4.1        486          5.9         230         4.5
    ## 9   9 female         5.2        686          6.2         273         7.2
    ## 10 10 female         6.2        645          7.4         240         7.8
    ##    RT_no.drug
    ## 1         371
    ## 2         349
    ## 3         412
    ## 4         252
    ## 5         439
    ## 6         464
    ## 7         327
    ## 8         305
    ## 9         327
    ## 10        498

    o, si optamos por omitir los nombres de los argumentos, podríamos simplificarlo a esto:

    longToWide( drugs.2, WMC+RT ~ drug )
    
    ##    id gender WMC_alcohol RT_alcohol WMC_caffeine RT_caffeine WMC_no.drug
    ## 1   1 female         3.7        488          3.7         236         3.9
    ## 2   2 female         6.4        607          7.3         376         7.9
    ## 3   3 female         4.6        643          7.4         226         7.3
    ## 4   4   male         6.4        684          7.8         206         8.2
    ## 5   5 female         4.9        593          5.2         262         7.0
    ## 6   6   male         5.4        492          6.6         230         7.2
    ## 7   7   male         7.9        690          7.9         259         8.9
    ## 8   8   male         4.1        486          5.9         230         4.5
    ## 9   9 female         5.2        686          6.2         273         7.2
    ## 10 10 female         6.2        645          7.4         240         7.8
    ##    RT_no.drug
    ## 1         371
    ## 2         349
    ## 3         412
    ## 4         252
    ## 5         439
    ## 6         464
    ## 7         327
    ## 8         305
    ## 9         327
    ## 10        498

    Tenga en cuenta que, al igual que la función WideToLong (), la función longToWide () le permite anular el carácter separador predeterminado. Por ejemplo, si el comando que usé había sido

    longToWide( drugs.2, WMC+RT ~ drug, sep="/" )
    ##    id gender WMC/alcohol RT/alcohol WMC/caffeine RT/caffeine WMC/no.drug
    ## 1   1 female         3.7        488          3.7         236         3.9
    ## 2   2 female         6.4        607          7.3         376         7.9
    ## 3   3 female         4.6        643          7.4         226         7.3
    ## 4   4   male         6.4        684          7.8         206         8.2
    ## 5   5 female         4.9        593          5.2         262         7.0
    ## 6   6   male         5.4        492          6.6         230         7.2
    ## 7   7   male         7.9        690          7.9         259         8.9
    ## 8   8   male         4.1        486          5.9         230         4.5
    ## 9   9 female         5.2        686          6.2         273         7.2
    ## 10 10 female         6.2        645          7.4         240         7.8
    ##    RT/no.drug
    ## 1         371
    ## 2         349
    ## 3         412
    ## 4         252
    ## 5         439
    ## 6         464
    ## 7         327
    ## 8         305
    ## 9         327
    ## 10        498

    la salida contendría variables con nombres como Rt/alcohol en lugar de RT_Alcohol.

    Remodelación con múltiples factores dentro del sujeto

    Como mencioné anteriormente, las funciones WideToLong () y LongToWide () son bastante limitadas en cuanto a lo que pueden hacer. Sin embargo, manejan una gama de situaciones más amplia que la señalada anteriormente. Considera el siguiente experimento psicológico bastante simple. Me interesan los efectos de la práctica en algún problema sencillo de toma de decisiones. Realmente no importa cuál sea el problema, aparte de señalar que me interesan dos variables de resultado distintas. En primer lugar, me importa la precisión de las personas, medida por la proporción de decisiones que las personas toman correctamente, denotada PC. En segundo lugar, me importa la velocidad de la gente, medida por el tiempo medio de respuesta que se tarda en tomar esas decisiones, denotado MRT. Eso es estándar en los experimentos psicológicos: la compensación de velocidad-precisión es bastante omnipresente, por lo que generalmente necesitamos preocuparnos por ambas variables.

    Para ver los efectos de la práctica a largo plazo, pruebo a cada participante en dos días, día1 y día2, donde por el bien del argumento asumiré que el día1 y el día2 tienen aproximadamente una semana de diferencia. Para observar los efectos de la práctica a corto plazo, las pruebas durante cada día se rompen en dos “bloques”, bloque1 y bloque2, que están separados por unos 20 minutos. Este no es el experimento más complicado del mundo, pero sigue siendo un poco más complicado que el anterior. Esta vez tenemos dos factores dentro del sujeto (es decir, día y bloqueo) y tenemos dos variables medidas para cada condición (es decir, PC y MRT). El marco de datos de elección muestra cómo podría ser la amplia forma de este tipo de datos:

    choice
    ##   id gender MRT/block1/day1 MRT/block1/day2 MRT/block2/day1
    ## 1  1   male             415             400             455
    ## 2  2   male             500             490             532
    ## 3  3 female             478             468             499
    ## 4  4 female             550             502             602
    ##   MRT/block2/day2 PC/block1/day1 PC/block1/day2 PC/block2/day1
    ## 1             450             79             88             82
    ## 2             518             83             92             86
    ## 3             474             91             98             90
    ## 4             588             75             89             78
    ##   PC/block2/day2
    ## 1             93
    ## 2             97
    ## 3            100
    ## 4             95

    Observe que en esta ocasión tenemos nombres de variables de la forma MRT/BLOCK1/día2. Como antes, la primera parte del nombre se refiere a la variable medida (tiempo de respuesta), pero ahora hay dos sufijos, uno que indica que la prueba se realizó en el bloque 1, y la otra que indica que se realizó el día 2. Y sólo para complicar las cosas, usa/como el carácter separador en lugar de _. Aun así, remodelar este conjunto de datos es bastante fácil. El comando para hacerlo es,

    choice.2 <- wideToLong( choice, within=c("block","day"), sep="/" )

    que es prácticamente el mismo comando que usamos la última vez. La única diferencia aquí es que, debido a que hay dos factores dentro del sujeto, el argumento within es un vector que contiene dos nombres. Cuando miramos el marco de datos de formato largo que esto crea, obtenemos esto:

    choice.2
    ##    id gender MRT  PC  block  day
    ## 1   1   male 415  79 block1 day1
    ## 2   2   male 500  83 block1 day1
    ## 3   3 female 478  91 block1 day1
    ## 4   4 female 550  75 block1 day1
    ## 5   1   male 400  88 block1 day2
    ## 6   2   male 490  92 block1 day2
    ## 7   3 female 468  98 block1 day2
    ## 8   4 female 502  89 block1 day2
    ## 9   1   male 455  82 block2 day1
    ## 10  2   male 532  86 block2 day1
    ## 11  3 female 499  90 block2 day1
    ## 12  4 female 602  78 block2 day1
    ## 13  1   male 450  93 block2 day2
    ## 14  2   male 518  97 block2 day2
    ## 15  3 female 474 100 block2 day2
    ## 16  4 female 588  95 block2 day2

    En este marco de datos de formato largo tenemos dos variables entre sujetos (id y género), dos variables que definen nuestras manipulaciones dentro del sujeto (bloque y día), y dos más contienen las medidas que tomamos (MRT y PC).

    Convertir esto de nuevo a forma ancha es igualmente sencillo. Usamos la función longToWide (), pero esta vez necesitamos alterar la fórmula para decirle que tenemos dos factores dentro del sujeto. El comando es ahora

    longToWide( choice.2, MRT+PC ~ block+day, sep="/" ) 
    ##   id gender MRT/block1/day1 PC/block1/day1 MRT/block1/day2 PC/block1/day2
    ## 1  1   male             415             79             400             88
    ## 2  2   male             500             83             490             92
    ## 3  3 female             478             91             468             98
    ## 4  4 female             550             75             502             89
    ##   MRT/block2/day1 PC/block2/day1 MRT/block2/day2 PC/block2/day2
    ## 1             455             82             450             93
    ## 2             532             86             518             97
    ## 3             499             90             474            100
    ## 4             602             78             588             95

    y esto produce un conjunto de datos de formato amplio que contiene las mismas variables que el marco de datos de elección original.

    ¿Qué otras opciones hay?

    La ventaja del enfoque descrito en la sección anterior es que resuelve un problema bastante específico (pero uno comúnmente encontrado) con un mínimo de alboroto. La desventaja es que las herramientas tienen un alcance bastante limitado. Permiten cambiar sus datos de un lado a otro entre dos formatos diferentes que son muy comunes en el análisis de datos cotidianos. Sin embargo, hay una serie de otras herramientas que puedes usar si es necesario. Justo dentro de los paquetes principales distribuidos con R se encuentra la función reshape (), así como las funciones stack () y unstack (), todas las cuales pueden ser útiles bajo ciertas circunstancias. Y por supuesto hay miles de paquetes en CRAN que puedes usar para ayudarte con diferentes tareas. Un paquete popular para este propósito es el paquete reshape, escrito por Hadley Wickham (??? para más detalles ver Wickham2007). Hay dos funciones clave en este paquete, llamadas melt () y cast () que son bastante útiles para resolver muchos problemas de remodelación. En una versión futura de este libro pretendo discutir melt () y cast () con bastante detalle.


    This page titled 7.7: Remodelación de un Marco 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.