En esta clase vamos a aprender a usar algunos paquetes para limpiar datos y estructurar información en R. En las clases anteriores vimos algunas características que deben tener los datos limpios:
library(dplyr)
library(tidyr)
library(readxl)
Antes de comenzar, hay que cambiar el directorio de trabajo y seleccionar el folder en donde tenemos nuestros archivos. Esto se hace con el comando setwd().
Ahora podemos importar los archivos de varias formas. Podemos hacerlo desde el menú de arriba, usando: File -> Import Dataset y seleccionando el tipo de archivo que queremos importar.
También podemos hacerlo escribiendo el código. Es siempre recomendable asignar el archivo que importamos a un objeto con el símbolo <-. Inicialmente vamos a importar unos archivos .xlsx, por lo que usamos el paquete readxl, que ya instalamos.
Los archivos que vamos a usar inicialmente son:
#Recuerden cambiar el directorio de trabajo
setwd("/Users/Camila/Documents/Curso periodismo datos/2017/Clases/Limpieza_R")
morosidad16 <- read_xlsx("morosidad16.xlsx")
morosidad17<- read_xlsx("morosidad17.xlsx")
Antes de comenzar a limpiar o analizar los datos tenemos que explorar los datos. Para estos primeros ejercicios vamos a usar las bases de datos de morosidad con la CCSS.
Ambas bases de datos tienen las siguientes variables:
id: cédula del deudor ya sea cédula física o jurídica.nombre: Nombre de la persona física o jurídica.deuda16 y deuda17 : monto de la deuda en colones.situación: situación en la que se encuentra la deudalugar.pago: sucursal donde se tiene que cancelar la deudaEstado: Estado de la deudaCómo primer paso vamos a unir ambas bases de datos.
Para unir bases de datos necesitamos una o más variables en común entre las dos bases de datos. Existen varias funciones para unir bases de datos. Una de ellas es merge, que sirve para unir columnas de dos bases de datos diferentes. Para unir bases es clave hacerse la pregunta: ¿Queremos conservar todas las variables o solo las que hacen match?. De acuerdo a la respuesta, así va a depender la fórmula que usemos.
La sintaxis de merge() es simple:
merge(base1, base2, by.x="nombre variable base 1", by.y="nombre variable base 2")
En el caso en el que la variable se llame igual en las dos bases: merge(base1, base2, by="nombre variable")
En esos ejemplos, el comando une solamente los casos en común entre las dos bases.
Si queremos que se unan todos los casos, usamos la opción all=TRUE: merge(base1, base2, by="nombre variable", all=TRUE)
Pueden ver este documento donde se muestra cómo funciona esta función con detalle. link
Para este ejercicio queremos unir las dos bases de morosidad en una sola, dejando todas las observaciones de ambas bases, entonces usamos el comando:
morosidad<-merge(morosidad17, morosidad16, by= "id", all=TRUE)
Ahora podemos convertirla base a una tibble para facilitar la lectura
morosidad <-tbl_df(morosidad)
Ahora que tenemos una nueva base de datos, podemos explorar sus contenidos. Usemos las siguientes funciones:
Si queremos imprimir la base de datos, nada más ponemos el nombre del objeto:
morosidad
## # A tibble: 78,703 x 10
## id nombre.x deuda17
## <dbl> <chr> <dbl>
## 1 0 VAN ADELBERGEN ISOLDA 265838
## 2 15452 BLAISE BLAISE CHRISTOPHE 83414
## 3 34382 INDUSTRIAS ELECTRONICAS COSTARRICENSES SA 7808
## 4 47329 VANNUCCI VANNUCCI ALBERTO 620534
## 5 50075 MARIA SELENIA CAYETANA CARVAJAL VENEGAS 506818
## 6 149005 ROSARIO CONEJO FÑCRUZ MARY GUASCH C 8240
## 7 469611 SAM SAM BRIAN WALTER HUBERT 526936
## 8 611086 MULLER MULLER JEAN-CLAUDE 103397
## 9 776002 RODRIGUEZ RODRIGUEZ VICTOR MANUEL 63089
## 10 1070043 MARKS RUIZ HENRY JAMES 1451873
## # ... with 78,693 more rows, and 7 more variables: situacion.x <chr>,
## # lugar.pago.x <chr>, Estado <chr>, nombre.y <chr>, deuda16 <dbl>,
## # situacion.y <chr>, lugar.pago.y <chr>
dim() Esta función nos permite ver la dimensión de la base de datos, en este caso tenemos 10 variables y 78.703 observaciones
dim(morosidad)
## [1] 78703 10
head() Nos permite ver las primeras filas de la base de datos. Incluso podemos seleccionar la cantidad de filas que queremos ver por ejemplo head(base, n=20), lo cual nos muestra las primeras 20 filas. También podemos ver que nos muestra el tipo de variable.
head(morosidad)
## # A tibble: 6 x 10
## id nombre.x deuda17
## <dbl> <chr> <dbl>
## 1 0 VAN ADELBERGEN ISOLDA 265838
## 2 15452 BLAISE BLAISE CHRISTOPHE 83414
## 3 34382 INDUSTRIAS ELECTRONICAS COSTARRICENSES SA 7808
## 4 47329 VANNUCCI VANNUCCI ALBERTO 620534
## 5 50075 MARIA SELENIA CAYETANA CARVAJAL VENEGAS 506818
## 6 149005 ROSARIO CONEJO FÑCRUZ MARY GUASCH C 8240
## # ... with 7 more variables: situacion.x <chr>, lugar.pago.x <chr>,
## # Estado <chr>, nombre.y <chr>, deuda16 <dbl>, situacion.y <chr>,
## # lugar.pago.y <chr>
tail() Nos permite ver las últimas filas. Tiene la misma sintaxis que head()
tail(morosidad)
## # A tibble: 6 x 10
## id nombre.x deuda17
## <dbl> <chr> <dbl>
## 1 14400964459 PAUL ROBERT OKEEFE NOINDICAOTRO 6838595
## 2 14528400520 INDUSTRIAS DON RICHARD S A 429487
## 3 18400600004 FERRETERIA EL PROGRESO S A 206436
## 4 31010287878 SOLUCIONES MODERNAS Y DE SEGURIDAD SOMOS S.A. 255875
## 5 31011413537 <NA> NA
## 6 31021120501 SUPER MERCADO EL KACIQUE LTDA 875409
## # ... with 7 more variables: situacion.x <chr>, lugar.pago.x <chr>,
## # Estado <chr>, nombre.y <chr>, deuda16 <dbl>, situacion.y <chr>,
## # lugar.pago.y <chr>
glimpse() nos permite exploarar las variables. Nos dice, al lado de cada variable cuál es el tipo. Por ejemplo nos dice que nombre.x es caracter y que deuda17 es “double”, el cual es un formato numérico.
glimpse(morosidad)
## Observations: 78,703
## Variables: 10
## $ id <dbl> 0, 15452, 34382, 47329, 50075, 149005, 469611, 61...
## $ nombre.x <chr> "VAN ADELBERGEN ISOLDA", "BLAISE BLAISE CHRISTOPH...
## $ deuda17 <dbl> 265838, 83414, 7808, 620534, 506818, 8240, 526936...
## $ situacion.x <chr> "DIFICIL COBRO", "COBRO ADMINISTRATIVO", "COBRO A...
## $ lugar.pago.x <chr> "SUCURSAL DESAMPARADOS", "SUCURSAL SANTA CRUZ", "...
## $ Estado <chr> "Inactivo", "Inactivo", "Inactivo", "Inactivo", "...
## $ nombre.y <chr> "VAN ADELBERGEN ISOLDA", "BLAISE BLAISE CHRISTOP...
## $ deuda16 <dbl> 133761, 42569, 4000, 313886, NA, NA, 264303, 5254...
## $ situacion.y <chr> "COBRO ADMINISTRATIVO", "COBRO ADMINISTRATIVO", "...
## $ lugar.pago.y <chr> "SUCURSAL DESAMPARADOS", "SUCURSAL SANTA CRUZ", "...
Uno de los paquetes que más funciona para manipular datos de forma fácil es dplyr. Este paquete tiene, entre otras, cinco funciones para manipular datos: select() filter() arrange()``mutate() summarize().
Veámos cómo se usa
Select nos permite seleccionar columnas. La sintaxis sería: select(dataframe, col1, col2) conde col1, col2, se refiere a los nombres de las columnas que queramos seleccionar.
Por ejemplo supongamos que queremos seleccionar únicamente las columnas de id y deuda:
select(morosidad, id, deuda17, deuda16)
## # A tibble: 78,703 x 3
## id deuda17 deuda16
## <dbl> <dbl> <dbl>
## 1 0 265838 133761
## 2 15452 83414 42569
## 3 34382 7808 4000
## 4 47329 620534 313886
## 5 50075 506818 NA
## 6 149005 8240 NA
## 7 469611 526936 264303
## 8 611086 103397 52546
## 9 776002 63089 NA
## 10 1070043 1451873 799625
## # ... with 78,693 more rows
También podemos seleccionar todas las columnas menos algunas, esto lo hacemos poniendo - antes del nombre de la columna que no queremos seleccionar. Por ejemplo, si queremos todas las columnas menos Estado:
select(morosidad, -Estado)
## # A tibble: 78,703 x 9
## id nombre.x deuda17
## <dbl> <chr> <dbl>
## 1 0 VAN ADELBERGEN ISOLDA 265838
## 2 15452 BLAISE BLAISE CHRISTOPHE 83414
## 3 34382 INDUSTRIAS ELECTRONICAS COSTARRICENSES SA 7808
## 4 47329 VANNUCCI VANNUCCI ALBERTO 620534
## 5 50075 MARIA SELENIA CAYETANA CARVAJAL VENEGAS 506818
## 6 149005 ROSARIO CONEJO FÑCRUZ MARY GUASCH C 8240
## 7 469611 SAM SAM BRIAN WALTER HUBERT 526936
## 8 611086 MULLER MULLER JEAN-CLAUDE 103397
## 9 776002 RODRIGUEZ RODRIGUEZ VICTOR MANUEL 63089
## 10 1070043 MARKS RUIZ HENRY JAMES 1451873
## # ... with 78,693 more rows, and 6 more variables: situacion.x <chr>,
## # lugar.pago.x <chr>, nombre.y <chr>, deuda16 <dbl>, situacion.y <chr>,
## # lugar.pago.y <chr>
Si queremos seleccionar un rango de columnas por ejemplo de id a situacion usamos :.
select(morosidad, id:situacion.x)
## # A tibble: 78,703 x 4
## id nombre.x deuda17
## <dbl> <chr> <dbl>
## 1 0 VAN ADELBERGEN ISOLDA 265838
## 2 15452 BLAISE BLAISE CHRISTOPHE 83414
## 3 34382 INDUSTRIAS ELECTRONICAS COSTARRICENSES SA 7808
## 4 47329 VANNUCCI VANNUCCI ALBERTO 620534
## 5 50075 MARIA SELENIA CAYETANA CARVAJAL VENEGAS 506818
## 6 149005 ROSARIO CONEJO FÑCRUZ MARY GUASCH C 8240
## 7 469611 SAM SAM BRIAN WALTER HUBERT 526936
## 8 611086 MULLER MULLER JEAN-CLAUDE 103397
## 9 776002 RODRIGUEZ RODRIGUEZ VICTOR MANUEL 63089
## 10 1070043 MARKS RUIZ HENRY JAMES 1451873
## # ... with 78,693 more rows, and 1 more variables: situacion.x <chr>
Si queremos guardar el resultado de esa función en un nuevo objeto, debemos asignarlo con <-. Por ejemplo para este ejericio nos interesa quedarnos únicamente con columnas que no estén repetidas. Si observamos la base, nos damos cuenta que la columna de nombre, lugar de pago y situación se repiten, entonces vamos a deseleccionar esas columnas y crear un nuevo objeto que se llame morosidad1.
morosidad1 <- select(morosidad, -nombre.y, -situacion.y, -lugar.pago.y)
morosidad1
## # A tibble: 78,703 x 7
## id nombre.x deuda17
## <dbl> <chr> <dbl>
## 1 0 VAN ADELBERGEN ISOLDA 265838
## 2 15452 BLAISE BLAISE CHRISTOPHE 83414
## 3 34382 INDUSTRIAS ELECTRONICAS COSTARRICENSES SA 7808
## 4 47329 VANNUCCI VANNUCCI ALBERTO 620534
## 5 50075 MARIA SELENIA CAYETANA CARVAJAL VENEGAS 506818
## 6 149005 ROSARIO CONEJO FÑCRUZ MARY GUASCH C 8240
## 7 469611 SAM SAM BRIAN WALTER HUBERT 526936
## 8 611086 MULLER MULLER JEAN-CLAUDE 103397
## 9 776002 RODRIGUEZ RODRIGUEZ VICTOR MANUEL 63089
## 10 1070043 MARKS RUIZ HENRY JAMES 1451873
## # ... with 78,693 more rows, and 4 more variables: situacion.x <chr>,
## # lugar.pago.x <chr>, Estado <chr>, deuda16 <dbl>
La función filter nos permite filtrar filas.
La sintaxis es simple: filter(base, condicion). Donde condición es la condión lógica por la que queremos filtrar datos. Para ello usamos operadores lógicos:
>: mayor que<: menor que>=: mayor o igual que<=: menor o igual que==: igual que (se ponen dos signos de igual)!=: diferente&: y|: ois.na(variable): filtra los valores en blanco de la variable seleccionada.!is.na(variable): filtra los valores que no están en blanco de la variable.Por ejemplo si queremos filtrar solamente las deudas superiores a un millón:
filter(morosidad1, deuda17>1000000)
## # A tibble: 30,438 x 7
## id nombre.x deuda17 situacion.x
## <dbl> <chr> <dbl> <chr>
## 1 1070043 MARKS RUIZ HENRY JAMES 1451873 COBRO JUDICIAL
## 2 3000465 HERNANDEZ RODAS MANUEL ANTONIO 2156724 COBRO ADMINISTRATIVO
## 3 4968006 SUCES DE EDUARDO ROJAS QUESADA 17668269 COBRO ADMINISTRATIVO
## 4 9700486 VERONICA ALVAREZ ZAMORAN 4177836 COBRO ADMINISTRATIVO
## 5 10000000 ANIBAL HERRERA BAUDELIO 1332517 COBRO ADMINISTRATIVO
## 6 11003242 RINE BORBON LUIS 1771856 COBRO JUDICIAL
## 7 11703874 MOSSUTO FONTANA ROCCO GIUSEPPE 1866968 COBRO JUDICIAL
## 8 11851989 PETER ALEXANDER TEODORI 1284362 COBRO JUDICIAL
## 9 11852243 DAMIA DAMIA EMIL 4685940 COBRO ADMINISTRATIVO
## 10 11880274 SCHLICKER SCHINDLBECK FRANK 1293144 DIFICIL COBRO
## # ... with 30,428 more rows, and 3 more variables: lugar.pago.x <chr>,
## # Estado <chr>, deuda16 <dbl>
O las deudas que crecieron entre 2016 y 2017:
filter(morosidad1, deuda17>deuda16)
## # A tibble: 56,539 x 7
## id nombre.x deuda17
## <dbl> <chr> <dbl>
## 1 0 VAN ADELBERGEN ISOLDA 265838
## 2 15452 BLAISE BLAISE CHRISTOPHE 83414
## 3 34382 INDUSTRIAS ELECTRONICAS COSTARRICENSES SA 7808
## 4 47329 VANNUCCI VANNUCCI ALBERTO 620534
## 5 469611 SAM SAM BRIAN WALTER HUBERT 526936
## 6 611086 MULLER MULLER JEAN-CLAUDE 103397
## 7 1070043 MARKS RUIZ HENRY JAMES 1451873
## 8 2380627 PLATERO FRANCO MARVIN 717483
## 9 3000465 HERNANDEZ RODAS MANUEL ANTONIO 2156724
## 10 9700486 VERONICA ALVAREZ ZAMORAN 4177836
## # ... with 56,529 more rows, and 4 more variables: situacion.x <chr>,
## # lugar.pago.x <chr>, Estado <chr>, deuda16 <dbl>
O solamente las deudas mayores a un millón y de díficil cobro:
filter(morosidad1, deuda17>1000000 & situacion.x=="DIFICIL COBRO")
## # A tibble: 9,482 x 7
## id nombre.x deuda17 situacion.x
## <dbl> <chr> <dbl> <chr>
## 1 11880274 SCHLICKER SCHINDLBECK FRANK 1293144 DIFICIL COBRO
## 2 12050037 DIAZ PILOTO JUSTO 22229809 DIFICIL COBRO
## 3 12251917 BIRD BIRD GEOFFREY 1267763 DIFICIL COBRO
## 4 13307917 LEWKOWICZ LEWKOWICZ HENRY 2074144 DIFICIL COBRO
## 5 13454769 BUSTOS VALDERRAMA JULIO ALBERTO 3317977 DIFICIL COBRO
## 6 13480637 PEREZ GIMENEZ VICENTE 1830254 DIFICIL COBRO
## 7 13509132 SEIDLER SEIDLER KARL PETER 4838378 DIFICIL COBRO
## 8 13952420 WILKIN WILKIN JEREMY ROBERT 1188119 DIFICIL COBRO
## 9 14050168 JANDREZ LOPEZ OVIDIO 4053836 DIFICIL COBRO
## 10 14110905 CETROLA CETROLA JULIO DOMINGO 1072692 DIFICIL COBRO
## # ... with 9,472 more rows, and 3 more variables: lugar.pago.x <chr>,
## # Estado <chr>, deuda16 <dbl>
En este ejemplo, tenemos deudas del 2016 y del 2017, y nos interesa analizar únicamente los casos de las empresas o personas que han estado morosas por los dos años. Para ello podemos usar la función filter:
morosidad1 <- filter(morosidad1, !is.na(deuda17), !is.na(deuda16))
El código de arriba lo que hace es filtrar la base por todos aquellos registros que no tengan valores vacíos en 2017 y luego por todos los que no tienen registros vacíos en 2016. Como podemos ver, esto nos da como resultado menos registros en nuestra base de datos.
Mutate nos permite crear nuevas columnas de forma fácil.
Podemos crear una variable que me diga cuánto cambió la deuda, que es la diferencia entre deuda17 y deuda16:
morosidad1 <- mutate(morosidad1, cambio.deuda=deuda17-deuda16)
Ahora podemos crear una nueva variable que me categorice el cambio en la deuda en si aumentó o no. Esto podemos hacerlo con la función if_else() o ifelse (funcionar igual). La sintaxis es: ifelse(condición, valor cierto, valor falso). (Es similar a la función if en Excel).
morosidad1 <- mutate(morosidad1, tipo.cambio=ifelse(cambio.deuda<0,"disminuyó", "aumentó"))
Con mutate podemos crear multiples variables a la vez, separando cada una por coma, por ejemplo:
morosidad1 <- mutate(morosidad1, cambio.deuda=deuda17-deuda16,
tipo.cambio=ifelse(cambio.deuda<0,"disminuyó", "aumentó"))
Arrange nos permite ordenar las base por una o varias columnas
Por ejemplo, queremos ordenar la base en orden ascendente por deuda17 y por cambio.deuda:
morosidad1 <- arrange(morosidad1, deuda17, cambio.deuda)
Si lo queremos en orden descendente usamos desc()
morosidad1 <- arrange(morosidad1, desc(deuda17), desc(cambio.deuda))
Un operador muy útil cuando trabajamos con dplyr es pipe operator que visualmente se ve así %>%. Este operador nos va a facilitar muchísimo el trabajo con funciones y nos permite hacer comando con menos líneas de código.
¿Cómo funciona el %>%? Lo primero es poner el ibjeto (tabla o dataframe) al cual queremos aplicar las operaciones de la forma base %>% funcion(). Esto nos ahorra estar poniendo como primer argumento de las funciones de dplyr al objeto.
Por ejemplo, recapitulemos todas las líneas de código que usamos anteriormente para limpiar la base de datos:
morosidad1 <- select(morosidad, -nombre.y, -situacion.y, -lugar.pago.y)
morosidad1 <- filter(morosidad1, !is.na(deuda17), !is.na(deuda16))
morosidad1 <- mutate(morosidad1, cambio.deuda=deuda17-deuda16)
morosidad1 <- mutate(morosidad1, tipo.cambio=ifelse(cambio.deuda<0,"disminuyó", "aumentó"))
morosidad1 <- arrange(morosidad1, desc(deuda17), desc(cambio.deuda))
Todos los pasos realizados anteriormente podríamos haberlos hecho de forma más simple usando el %>%:
morosidad2 <- morosidad %>%
select(-nombre.y, -situacion.y, -lugar.pago.y) %>%
filter(!is.na(deuda17), !is.na(deuda16)) %>%
mutate(cambio.deuda=deuda17-deuda16,
tipo.cambio=ifelse(cambio.deuda<0,"disminuyó", "aumentó")) %>%
arrange(desc(deuda17), desc(cambio.deuda))
Ahora que tenemos la base limpia podemos exportarla a otros formatos por ejemplo a csv.
write.csv(morosidad2, "baselimpia.csv")
tidyr es un paquete diseñado para tener datos ¨tidy¨ o limpios. Esos datos siguen dos principios que ya hemos visto reiteradamente: Cada variable está en una sola columna y cada fila es una observación.
Para entender mejor qué es “tidy data”, puede leer este artículo: Tidy data - Hadley Wickham
Este paquete tiene 4 funciones principales gather() spread() separate() y unite().
Antes de comenzar a ver las funciones importemos los archivos de trabajo:
#Ponemos tbl_df() para convertirlo de una vez a una tibble
estudiantes <- tbl_df(read.csv("students.csv", header = T, sep= ","))
estudiantes2<- tbl_df(read.csv("students2.csv", header = T, sep= ","))
Veamos estudiantes:
estudiantes
## # A tibble: 5 x 3
## grade male female
## <fctr> <int> <int>
## 1 A 1 5
## 2 B 5 0
## 3 C 5 2
## 4 D 5 5
## 5 E 7 4
¿Cuál es el problema? male y female son valores de la variable sexo, por lo que hay que cambiar la estructura de la base de datos. Esta estructura de una base de datos se conoce como “formato ancho” y tenemos que convertirla a un “formato largo”. Para eso usamos la función gather().
La función toma las columnas múltiples, las colapsa en una sola y crea una nueva columna con los valores respectivos.
La sintaxis es gather(data, key, value, columnas) o data %>% gather(key, value, columnas). Donde:
data: es la tabla o el data framekey: es el nombre que le voy a dar a la variable que voy a “fundir”.value: nombre de la variable que va a guardar los valores.columna: las columnas que quiero fundir. Podemos ponerlas separadas por coma, o pondemos usar el operador - para seleccionar todas las columnas menos una.En este ejemplo para reestructurar estudiantes el comando sería:
estudiantes_long <- gather(estudiantes, sexo, frecuencia, -grade)
estudiantes_long
## # A tibble: 10 x 3
## grade sexo frecuencia
## <fctr> <chr> <int>
## 1 A male 1
## 2 B male 5
## 3 C male 5
## 4 D male 5
## 5 E male 7
## 6 A female 5
## 7 B female 0
## 8 C female 2
## 9 D female 5
## 10 E female 4
Es la función contraria a gather(), que nos devolvería a la tabla original
estudiantes_wide <- spread(estudiantes_long, sexo, frecuencia)
estudiantes_wide
## # A tibble: 5 x 3
## grade female male
## * <fctr> <int> <int>
## 1 A 5 1
## 2 B 0 5
## 3 C 2 5
## 4 D 5 5
## 5 E 4 7
Veamos ahora qué pasa con estudiantes2:
estudiantes2
## # A tibble: 5 x 5
## grade male_1 female_1 male_2 female_2
## <fctr> <int> <int> <int> <int>
## 1 A 3 4 3 4
## 2 B 6 4 3 5
## 3 C 7 4 3 8
## 4 D 4 0 8 1
## 5 E 1 1 2 7
En este caso tenemos un doble problema tenemos valores de una misma variable en diferentes columnas y diferentes variables en una sola. En este caso nos separa a los hombres y mujeres segun la clase en la que están: 1 y 2.
Entonces tenemos que hacer dos pasos. Primero usamos la función gather():
estudiantes2_long <- gather(estudiantes2, sexo_clase, frecuencia, -grade)
estudiantes2_long
## # A tibble: 20 x 3
## grade sexo_clase frecuencia
## <fctr> <chr> <int>
## 1 A male_1 3
## 2 B male_1 6
## 3 C male_1 7
## 4 D male_1 4
## 5 E male_1 1
## 6 A female_1 4
## 7 B female_1 4
## 8 C female_1 4
## 9 D female_1 0
## 10 E female_1 1
## 11 A male_2 3
## 12 B male_2 3
## 13 C male_2 3
## 14 D male_2 8
## 15 E male_2 2
## 16 A female_2 4
## 17 B female_2 5
## 18 C female_2 8
## 19 D female_2 1
## 20 E female_2 7
Y ahora usamos la función separate().
Esta función nos permite separar columnas. La sintaxis es:
separate(data, col, into, sep), donde:
data: es la tabla o el data framecol: la columna que hay que separarinto: las columnas por las que vamos a separar. Se pueden poner como vector de la forma c(“col1”, “col2”)sep: separador, por ejemplo comas, puntos, guion bajo u otros caracteres. Si no se especifica el argumento R trata de identificar el patrón para separar los datos. Cuando se utiliza esta opción se debe poner sep=" " (entre comillas iría el caracter que usemos para separar)En este ejemplo, queremos separar el sexo de la clase.
estudiantes2_long2 <- separate(estudiantes2_long, sexo_clase, c("sexo", "clase"))
#En este caso R detectó el caracter para separar, el resultado es igual a si hubiéramos puesto la opción sep="_"
estudiantes2_long2
## # A tibble: 20 x 4
## grade sexo clase frecuencia
## * <fctr> <chr> <chr> <int>
## 1 A male 1 3
## 2 B male 1 6
## 3 C male 1 7
## 4 D male 1 4
## 5 E male 1 1
## 6 A female 1 4
## 7 B female 1 4
## 8 C female 1 4
## 9 D female 1 0
## 10 E female 1 1
## 11 A male 2 3
## 12 B male 2 3
## 13 C male 2 3
## 14 D male 2 8
## 15 E male 2 2
## 16 A female 2 4
## 17 B female 2 5
## 18 C female 2 8
## 19 D female 2 1
## 20 E female 2 7
Estos pasos podemos simplificarlos en uno solo con el uso del %>%:
estudiantes2_long <- estudiantes2 %>%
gather(sexo_clase, frecuencia, -grade) %>%
separate(sexo_clase, c("sexo", "clase")) %>%
print
## # A tibble: 20 x 4
## grade sexo clase frecuencia
## * <fctr> <chr> <chr> <int>
## 1 A male 1 3
## 2 B male 1 6
## 3 C male 1 7
## 4 D male 1 4
## 5 E male 1 1
## 6 A female 1 4
## 7 B female 1 4
## 8 C female 1 4
## 9 D female 1 0
## 10 E female 1 1
## 11 A male 2 3
## 12 B male 2 3
## 13 C male 2 3
## 14 D male 2 8
## 15 E male 2 2
## 16 A female 2 4
## 17 B female 2 5
## 18 C female 2 8
## 19 D female 2 1
## 20 E female 2 7
#el comando print, nos imprime el resultado
Es el contrario a separate. unite(data, col, ... , sep), donde:
data: es la tabla o el data framecol: la nueva columna con los valores unidos...: la lista de columnas que queremos unirsep: separador que va a unir las columnas, por ejemplo _.En este caso si queremos volver a la tabla original:
estudiantes2_unida <- estudiantes2_long %>%
unite(sexo_clase, sexo, clase, sep="-") %>%
print
## # A tibble: 20 x 3
## grade sexo_clase frecuencia
## * <fctr> <chr> <int>
## 1 A male-1 3
## 2 B male-1 6
## 3 C male-1 7
## 4 D male-1 4
## 5 E male-1 1
## 6 A female-1 4
## 7 B female-1 4
## 8 C female-1 4
## 9 D female-1 0
## 10 E female-1 1
## 11 A male-2 3
## 12 B male-2 3
## 13 C male-2 3
## 14 D male-2 8
## 15 E male-2 2
## 16 A female-2 4
## 17 B female-2 5
## 18 C female-2 8
## 19 D female-2 1
## 20 E female-2 7