Chapter 5 Importar datos en R

En raras ocasiones, los conjuntos de datos que utilizaremos en R para analizarlos los construimos directamente en R. Normalmente los tenemos en otros formatos y archivos, como de texto plano, archivos de Microsoft Excel o Libreoffice Calc, etc. Pues bien, en este curso os enseñaré cómo importar esos datos ya existentes en otros formatos a R, para así poder realizar todos los análisis que necesitemos. Más concretamente, aquí os enseñaré a importar a R 5 tipos de archivos

  • Archivos de texto plano, como .csv
  • Datos desde Microsoft Excel
  • Bases de datos POstgreSQL o MySQL
  • Desde la Web
  • Desde otros software estadísticos como SPSS, SAS o STATA

5.1 Importar archivos de texto plano con utils

5.1.1 Archivos .csv con read.csv()

Los archivos de texto plano son archivos de texto en el que las filas son las observaciones (menos la primera, que suele contener el nombre de las columnas), y las columnas están formadas por elementos separados por una coma. De hecho, csv significa Comma Separated Values.

La función para importar un archivo de texto plano .csv en R se llama read.csv(), y se encuentra incluida dentro del paquete utils. Este paquete se carga automáticamente al iniciar R, por lo que no tendremos que cargarlo de modo explícito.

La estructura básica de la función es:

read.csv("nombre y ruta del archivo .csv")

Sin embargo, las columnas con texto las convierte automáticamente a factores. Esto puede tener sentido si nuestras columnas lo fueran. Pero no siempre es así. Para cambiarlo, vamos a añadir un argumento extra a la función, llamado stringsAsFactors:

read.csv("nombre y ruta del archivo .csv, stringsAsFactors = FALSE")

Con stringsAsFactors = FALSE, le estamos indicando que las columnas que tengan texto se carguen como cadena de caracteres, y no como factores.

Vamos a usar el ejemplo swimming_pools.csv, que contiene los datos de las piscinas en Brisbane (Australia) (Source: data.gov.au).

# Lo importamos sin stringsAsFactors y vemos su estructura
pools <- read.csv("Datos/swimming_pools.csv")

# Check the structure of pools
str(pools)
## 'data.frame':    20 obs. of  4 variables:
##  $ Name     : Factor w/ 20 levels "Acacia Ridge Leisure Centre",..: 1 2 3 4 5 6 19 7 8 9 ...
##  $ Address  : Factor w/ 20 levels "1 Fairlead Crescent, Manly",..: 5 20 18 10 9 11 6 15 12 17 ...
##  $ Latitude : num  -27.6 -27.6 -27.6 -27.5 -27.4 ...
##  $ Longitude: num  153 153 153 153 153 ...
# Lo importamos con stringsAsFactors = FALSE y vemos su estructura
pools <- read.csv("Datos/swimming_pools.csv", stringsAsFactors = FALSE)

# Check the structure of pools
str(pools)
## 'data.frame':    20 obs. of  4 variables:
##  $ Name     : chr  "Acacia Ridge Leisure Centre" "Bellbowrie Pool" "Carole Park" "Centenary Pool (inner City)" ...
##  $ Address  : chr  "1391 Beaudesert Road, Acacia Ridge" "Sugarwood Street, Bellbowrie" "Cnr Boundary Road and Waterford Road Wacol" "400 Gregory Terrace, Spring Hill" ...
##  $ Latitude : num  -27.6 -27.6 -27.6 -27.5 -27.4 ...
##  $ Longitude: num  153 153 153 153 153 ...

Para conocer qué archivos tenemos en nuestro directorio de trabajo podemos usar la función dir().

5.1.2 Archivos .txt con tabulación con read.delim()

Si tenemos un archivo de texto plano .txt en el que los elementos estén separados con tabulación, podemos usar la función read.delim() para importarlos a R.

De forma predeterminada, esta función viene con sep = "\t", indicando que el separador de los elementos es el tabulador, y con header = TRUE indicando que la tabla contiene el nombre de las columnas en la primera fila.

#In this exercise, you will import hotdogs.txt, containing information on sodium and calorie levels in different hotdogs (Source: UCLA). The dataset has 3 variables, but the variable names are not available in the first line of the file. The file uses tabs as field separators.

# Import hotdogs.txt: hotdogs
hotdogs <- read.delim("Datos/hotdogs.txt", header = F)

# Summarize hotdogs
summary(hotdogs)
##        V1           V2              V3       
##  Beef   :20   Min.   : 86.0   Min.   :144.0  
##  Meat   :17   1st Qu.:132.0   1st Qu.:362.5  
##  Poultry:17   Median :145.0   Median :405.0  
##               Mean   :145.4   Mean   :424.8  
##               3rd Qu.:172.8   3rd Qu.:503.5  
##               Max.   :195.0   Max.   :645.0
# Finish the read.delim() call
hotdogs <- read.delim("Datos/hotdogs.txt", header = FALSE, col.names = c("type", "calories", "sodium"))

# Select the hot dog with the least calories: lily
lily <- hotdogs[which.min(hotdogs$calories), ]

# Select the observation with the most sodium: tom
tom <- hotdogs[which.max(hotdogs$sodium), ]

# Print lily and tom
print(lily)
##       type calories sodium
## 50 Poultry       86    358
print(tom)
##    type calories sodium
## 15 Beef      190    645

5.1.3 read.table()

Es la función más importante y básica para importar tablas en R, ya que puede agrupar a las anteriores y convertir casi cualquier tabla en un data frame en R. De hecho, read.csv() y read.delim() ejecutan read.table() de fondo pero con unos argumentos predefinidos que se ajustan al tipo de datos que se van a cargar.

# Comparamos read.table con read.csv para ver los argumentos predefinidos del último
read.table("Datos/swimming_pools.csv", header = TRUE, sep = ",", stringsAsFactors = FALSE)
##                                         Name
## 1                Acacia Ridge Leisure Centre
## 2                            Bellbowrie Pool
## 3                                Carole Park
## 4                Centenary Pool (inner City)
## 5                             Chermside Pool
## 6                Colmslie Pool (Morningside)
## 7             Spring Hill Baths (inner City)
## 8                 Dunlop Park Pool (Corinda)
## 9                      Fortitude Valley Pool
## 10 Hibiscus Sports Complex (upper MtGravatt)
## 11                 Ithaca Pool ( Paddington)
## 12                             Jindalee Pool
## 13                                Manly Pool
## 14            Mt Gravatt East Aquatic Centre
## 15       Musgrave Park Pool (South Brisbane)
## 16                            Newmarket Pool
## 17                              Runcorn Pool
## 18                             Sandgate Pool
## 19      Langlands Parks Pool (Stones Corner)
## 20                         Yeronga Park Pool
##                                        Address  Latitude Longitude
## 1           1391 Beaudesert Road, Acacia Ridge -27.58616  153.0264
## 2                 Sugarwood Street, Bellbowrie -27.56547  152.8911
## 3   Cnr Boundary Road and Waterford Road Wacol -27.60744  152.9315
## 4             400 Gregory Terrace, Spring Hill -27.45537  153.0251
## 5                 375 Hamilton Road, Chermside -27.38583  153.0351
## 6                 400 Lytton Road, Morningside -27.45516  153.0789
## 7             14 Torrington Street, Springhill -27.45960  153.0215
## 8                      794 Oxley Road, Corinda -27.54652  152.9806
## 9         432 Wickham Street, Fortitude Valley -27.45390  153.0368
## 10         90 Klumpp Road, Upper Mount Gravatt -27.55183  153.0735
## 11               131 Caxton Street, Paddington -27.46226  153.0103
## 12                 11 Yallambee Road, Jindalee -27.53236  152.9427
## 13                  1 Fairlead Crescent, Manly -27.45228  153.1874
## 14 Cnr wecker Road and Newnham Road, Mansfield -27.53214  153.0943
## 15       100 Edmonstone Street, South Brisbane -27.47978  153.0168
## 16                71 Alderson Stret, Newmarket -27.42968  153.0062
## 17                   37 Bonemill Road, Runcorn -27.59156  153.0764
## 18               231 Flinders Parade, Sandgate -27.31196  153.0691
## 19             5 Panitya Street, Stones Corner -27.49769  153.0487
## 20                     81 School Road, Yeronga -27.52053  153.0185
read.csv ("Datos/swimming_pools.csv", stringsAsFactors = FALSE)
##                                         Name
## 1                Acacia Ridge Leisure Centre
## 2                            Bellbowrie Pool
## 3                                Carole Park
## 4                Centenary Pool (inner City)
## 5                             Chermside Pool
## 6                Colmslie Pool (Morningside)
## 7             Spring Hill Baths (inner City)
## 8                 Dunlop Park Pool (Corinda)
## 9                      Fortitude Valley Pool
## 10 Hibiscus Sports Complex (upper MtGravatt)
## 11                 Ithaca Pool ( Paddington)
## 12                             Jindalee Pool
## 13                                Manly Pool
## 14            Mt Gravatt East Aquatic Centre
## 15       Musgrave Park Pool (South Brisbane)
## 16                            Newmarket Pool
## 17                              Runcorn Pool
## 18                             Sandgate Pool
## 19      Langlands Parks Pool (Stones Corner)
## 20                         Yeronga Park Pool
##                                        Address  Latitude Longitude
## 1           1391 Beaudesert Road, Acacia Ridge -27.58616  153.0264
## 2                 Sugarwood Street, Bellbowrie -27.56547  152.8911
## 3   Cnr Boundary Road and Waterford Road Wacol -27.60744  152.9315
## 4             400 Gregory Terrace, Spring Hill -27.45537  153.0251
## 5                 375 Hamilton Road, Chermside -27.38583  153.0351
## 6                 400 Lytton Road, Morningside -27.45516  153.0789
## 7             14 Torrington Street, Springhill -27.45960  153.0215
## 8                      794 Oxley Road, Corinda -27.54652  152.9806
## 9         432 Wickham Street, Fortitude Valley -27.45390  153.0368
## 10         90 Klumpp Road, Upper Mount Gravatt -27.55183  153.0735
## 11               131 Caxton Street, Paddington -27.46226  153.0103
## 12                 11 Yallambee Road, Jindalee -27.53236  152.9427
## 13                  1 Fairlead Crescent, Manly -27.45228  153.1874
## 14 Cnr wecker Road and Newnham Road, Mansfield -27.53214  153.0943
## 15       100 Edmonstone Street, South Brisbane -27.47978  153.0168
## 16                71 Alderson Stret, Newmarket -27.42968  153.0062
## 17                   37 Bonemill Road, Runcorn -27.59156  153.0764
## 18               231 Flinders Parade, Sandgate -27.31196  153.0691
## 19             5 Panitya Street, Stones Corner -27.49769  153.0487
## 20                     81 School Road, Yeronga -27.52053  153.0185
# Comparamos read.table con read.delim para ver los argumentos predefinidos del último
read.table("Datos/hotdogs.txt", header = TRUE, sep = "\t", stringsAsFactors = FALSE)
##       Beef X186 X495
## 1     Beef  181  477
## 2     Beef  176  425
## 3     Beef  149  322
## 4     Beef  184  482
## 5     Beef  190  587
## 6     Beef  158  370
## 7     Beef  139  322
## 8     Beef  175  479
## 9     Beef  148  375
## 10    Beef  152  330
## 11    Beef  111  300
## 12    Beef  141  386
## 13    Beef  153  401
## 14    Beef  190  645
## 15    Beef  157  440
## 16    Beef  131  317
## 17    Beef  149  319
## 18    Beef  135  298
## 19    Beef  132  253
## 20    Meat  173  458
## 21    Meat  191  506
## 22    Meat  182  473
## 23    Meat  190  545
## 24    Meat  172  496
## 25    Meat  147  360
## 26    Meat  146  387
## 27    Meat  139  386
## 28    Meat  175  507
## 29    Meat  136  393
## 30    Meat  179  405
## 31    Meat  153  372
## 32    Meat  107  144
## 33    Meat  195  511
## 34    Meat  135  405
## 35    Meat  140  428
## 36    Meat  138  339
## 37 Poultry  129  430
## 38 Poultry  132  375
## 39 Poultry  102  396
## 40 Poultry  106  383
## 41 Poultry   94  387
## 42 Poultry  102  542
## 43 Poultry   87  359
## 44 Poultry   99  357
## 45 Poultry  107  528
## 46 Poultry  113  513
## 47 Poultry  135  426
## 48 Poultry  142  513
## 49 Poultry   86  358
## 50 Poultry  143  581
## 51 Poultry  152  588
## 52 Poultry  146  522
## 53 Poultry  144  545
read.delim("Datos/hotdogs.txt", stringsAsFactors = FALSE)
##       Beef X186 X495
## 1     Beef  181  477
## 2     Beef  176  425
## 3     Beef  149  322
## 4     Beef  184  482
## 5     Beef  190  587
## 6     Beef  158  370
## 7     Beef  139  322
## 8     Beef  175  479
## 9     Beef  148  375
## 10    Beef  152  330
## 11    Beef  111  300
## 12    Beef  141  386
## 13    Beef  153  401
## 14    Beef  190  645
## 15    Beef  157  440
## 16    Beef  131  317
## 17    Beef  149  319
## 18    Beef  135  298
## 19    Beef  132  253
## 20    Meat  173  458
## 21    Meat  191  506
## 22    Meat  182  473
## 23    Meat  190  545
## 24    Meat  172  496
## 25    Meat  147  360
## 26    Meat  146  387
## 27    Meat  139  386
## 28    Meat  175  507
## 29    Meat  136  393
## 30    Meat  179  405
## 31    Meat  153  372
## 32    Meat  107  144
## 33    Meat  195  511
## 34    Meat  135  405
## 35    Meat  140  428
## 36    Meat  138  339
## 37 Poultry  129  430
## 38 Poultry  132  375
## 39 Poultry  102  396
## 40 Poultry  106  383
## 41 Poultry   94  387
## 42 Poultry  102  542
## 43 Poultry   87  359
## 44 Poultry   99  357
## 45 Poultry  107  528
## 46 Poultry  113  513
## 47 Poultry  135  426
## 48 Poultry  142  513
## 49 Poultry   86  358
## 50 Poultry  143  581
## 51 Poultry  152  588
## 52 Poultry  146  522
## 53 Poultry  144  545

Existen más funciones, como read.csv2() and read.delim2(), con algunos argumentos extras dependiendo de la estructura de los datos.

De forma predeterminada, esta función viene con sep = " ", indicando que el separador de los elementos es un espacio, y con header = FALSE indicando que la tabla no contiene el nombre de las columnas en la primera fila.

# Import the hotdogs.txt file: hotdogs
hotdogs <- read.table("Datos/hotdogs.txt", 
                      sep = "\t", 
                      col.names = c("type", "calories", "sodium"))

# Call head() on hotdogs
head(hotdogs)
##   type calories sodium
## 1 Beef      186    495
## 2 Beef      181    477
## 3 Beef      176    425
## 4 Beef      149    322
## 5 Beef      184    482
## 6 Beef      190    587

5.1.4 Otros argumentos para las funciones anteriores

  • colClasses. Especificamos el tipo de variable que es: numérica, factorial, cadena de caracteres, etc. Si una columna tiene NULL, esa columna no se carga en el conjunto de datos.
  • stringsAsFactors. Si queremos convertir en factoriales las cadenas de caracteres de las variables.
  • dec. Indicamos si el símbolo decimal es un punt (dec = ".") o una coma (dec = ",").
# Previous call to import hotdogs.txt
hotdogs <- read.delim("Datos/hotdogs.txt", header = FALSE, col.names = c("type", "calories", "sodium"))

# Display structure of hotdogs
str(hotdogs)
## 'data.frame':    54 obs. of  3 variables:
##  $ type    : Factor w/ 3 levels "Beef","Meat",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ calories: int  186 181 176 149 184 190 158 139 175 148 ...
##  $ sodium  : int  495 477 425 322 482 587 370 322 479 375 ...
# Edit the colClasses argument to import the data correctly: hotdogs2
hotdogs2 <- read.delim("Datos/hotdogs.txt", header = FALSE, 
                       col.names = c("type", "calories", "sodium"),
                       colClasses = c("factor", "NULL", "numeric"))

# Display structure of hotdogs2
str(hotdogs2)
## 'data.frame':    54 obs. of  2 variables:
##  $ type  : Factor w/ 3 levels "Beef","Meat",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ sodium: num  495 477 425 322 482 587 370 322 479 375 ...

5.2 Importar archivos Excel

5.2.1 readr y data.table

R ofrece paquetes específicos para poder cargar datos en su entorno. Estos paquetes específicos normalmente facilitan la importación de los datos comparado con las funciones que vimos anteriormente, que estaban ubicadas dentro del paquete utils. Pues bien, dos de estos paquetes que nos facilitan la vida son readr y data.table.

5.2.1.1 Paquete readr

El paquete readr está creado por Hadley Wickham. Cuando queremos cargar un archivo .csv, simplemente escribimos read_csv("archivo.csv") y listo. Ya se encarga la función de detectar todo lo necesario para cargarlo satisfactoriamente.

5.2.1.1.1 Funciones read_csv() y read_tsv()
library(readr)
read_csv("Datos/potatoes.csv")
## Parsed with column specification:
## cols(
##   area = col_integer(),
##   temp = col_integer(),
##   size = col_integer(),
##   storage = col_integer(),
##   method = col_integer(),
##   texture = col_double(),
##   flavor = col_double(),
##   moistness = col_double()
## )
## # A tibble: 160 x 8
##     area  temp  size storage method texture flavor moistness
##    <int> <int> <int>   <int>  <int>   <dbl>  <dbl>     <dbl>
##  1     1     1     1       1      1     2.9    3.2       3  
##  2     1     1     1       1      2     2.3    2.5       2.6
##  3     1     1     1       1      3     2.5    2.8       2.8
##  4     1     1     1       1      4     2.1    2.9       2.4
##  5     1     1     1       1      5     1.9    2.8       2.2
##  6     1     1     1       2      1     1.8    3         1.7
##  7     1     1     1       2      2     2.6    3.1       2.4
##  8     1     1     1       2      3     3      3         2.9
##  9     1     1     1       2      4     2.2    3.2       2.5
## 10     1     1     1       2      5     2      2.8       1.9
## # … with 150 more rows

Lo mismo sucede con archivos de texto.

library(readr)
# Nombre de las columnas
properties <- c("area", "temp", "size", "storage", "method",
                "texture", "flavor", "moistness")

# Como no tienen nombres las columnas, le añadimos el argumento col_names
read_tsv("Datos/potatoes.txt", col_names = properties)
## Parsed with column specification:
## cols(
##   area = col_integer(),
##   temp = col_integer(),
##   size = col_integer(),
##   storage = col_integer(),
##   method = col_integer(),
##   texture = col_double(),
##   flavor = col_double(),
##   moistness = col_double()
## )
## # A tibble: 160 x 8
##     area  temp  size storage method texture flavor moistness
##    <int> <int> <int>   <int>  <int>   <dbl>  <dbl>     <dbl>
##  1     1     1     1       1      1     2.9    3.2       3  
##  2     1     1     1       1      2     2.3    2.5       2.6
##  3     1     1     1       1      3     2.5    2.8       2.8
##  4     1     1     1       1      4     2.1    2.9       2.4
##  5     1     1     1       1      5     1.9    2.8       2.2
##  6     1     1     1       2      1     1.8    3         1.7
##  7     1     1     1       2      2     2.6    3.1       2.4
##  8     1     1     1       2      3     3      3         2.9
##  9     1     1     1       2      4     2.2    3.2       2.5
## 10     1     1     1       2      5     2      2.8       1.9
## # … with 150 more rows
5.2.1.1.2 Función read_delim()

Al igual que read.table() era la función principal en el paquete utils, read_delim() es la función principal en el paquete readr. Esta función tiene dos argumentos obligatorios:

  • file: el archivo con los datos.
  • delim: el carácter que separa nuestros datos. Si es la tabulación, es ".

También tiene unos argumentos optativos:

  • col_names: indica el vector o los nombres de las columnas, en caso de que el archivo principal no lo lleve.
  • skip: especifica a partir de qué línea queremos comenzar la importación. Por ejemplo, si ponemos skip = 3, nuestro conjunto de datos cargará a partir de la fila 4. Hay que tener en cuenta que este argumento no discrimina si hay o no nombre de columnas en los datos, por lo que tenemos que tenerlo en consideración.
  • n_max: especifica el número de líneas que quieres importar a partir de la primera considerada. Si ponemos n_max = 10, nos cargará las primeras 10 líneas de nuestro conjunto de datos. Si lo combináramos con skip, serían 10 filas contando a partir del primer valor después de skip.
  • col_types: le puedes indicar directamente el tipo de datos que tiene cada columna. Hay cuatro posibilidades:
    1. integer
    2. double
    3. logical
    4. character
# Nombre de las columnas
properties <- c("area", "temp", "size", "storage", "method",
                "texture", "flavor", "moistness")

# Import potatoes.txt using read_delim(): potatoes
potatoes <- read_delim(file = "Datos/potatoes.txt", delim = "\t", col_names = properties)
## Parsed with column specification:
## cols(
##   area = col_integer(),
##   temp = col_integer(),
##   size = col_integer(),
##   storage = col_integer(),
##   method = col_integer(),
##   texture = col_double(),
##   flavor = col_double(),
##   moistness = col_double()
## )
# Queremos el intervalo de filas (observaciones) comprendido entre el 7 y el 11, ambos incluidos
potatoes_fragment <- read_tsv("Datos/potatoes.txt", skip = 6, n_max = 5, col_names = properties)
## Parsed with column specification:
## cols(
##   area = col_integer(),
##   temp = col_integer(),
##   size = col_integer(),
##   storage = col_integer(),
##   method = col_integer(),
##   texture = col_double(),
##   flavor = col_double(),
##   moistness = col_double()
## )
# Le indicamos que queremos las 8 columnas sean importadas como carácter (character)
potatoes_char <- read_tsv("Datos/potatoes.txt", col_types = "cccccccc", col_names = properties)

col_types with collectors

Another way of setting the types of the imported columns is using collectors. Collector functions can be passed in a list() to the col_types argument of read_ functions to tell them how to interpret values in a column.

For a complete list of collector functions, you can take a look at the collector documentation. For this exercise you will need two collector functions:

  • col_integer(): the column should be interpreted as an integer.
  • col_factor(levels, ordered = FALSE): the column should be interpreted as a factor with levels.

In this exercise, you will work with hotdogs.txt, which is a tab-delimited file without column names in the first row.

# readr is already loaded
library(readr)

# Import without col_types
hotdogs <- read_tsv("Datos/hotdogs.txt", col_names = c("type", "calories", "sodium"))
## Parsed with column specification:
## cols(
##   type = col_character(),
##   calories = col_integer(),
##   sodium = col_integer()
## )
# Display the summary of hotdogs
summary(hotdogs)
##      type              calories         sodium     
##  Length:54          Min.   : 86.0   Min.   :144.0  
##  Class :character   1st Qu.:132.0   1st Qu.:362.5  
##  Mode  :character   Median :145.0   Median :405.0  
##                     Mean   :145.4   Mean   :424.8  
##                     3rd Qu.:172.8   3rd Qu.:503.5  
##                     Max.   :195.0   Max.   :645.0
# The collectors you will need to import the data
fac <- col_factor(levels = c("Beef", "Meat", "Poultry"))
int <- col_integer()

# Edit the col_types argument to import the data correctly: hotdogs_factor
hotdogs_factor <- read_tsv("Datos/hotdogs.txt",
                           col_names = c("type", "calories", "sodium"),
                           col_types = list(fac, int, int))

# Display the summary of hotdogs_factor
summary(hotdogs_factor)
##       type       calories         sodium     
##  Beef   :20   Min.   : 86.0   Min.   :144.0  
##  Meat   :17   1st Qu.:132.0   1st Qu.:362.5  
##  Poultry:17   Median :145.0   Median :405.0  
##               Mean   :145.4   Mean   :424.8  
##               3rd Qu.:172.8   3rd Qu.:503.5  
##               Max.   :195.0   Max.   :645.0

5.2.1.2 Paquete data.table y función fread()

fread() es una función del paquete data.table que se asemeja a read.table(). De hecho hacen la misma función con argumentos imilares. La diferencia es que es extraordinariamente rápida. Normalmente, indicando la ruta del archivo de datos es suficiente para que lo importe a R de un modo satisfactorio.

# load the data.table package
library(data.table)
## data.table 1.10.4.3
##   The fastest way to learn (by data.table authors): https://www.datacamp.com/courses/data-analysis-the-data-table-way
##   Documentation: ?data.table, example(data.table) and browseVignettes("data.table")
##   Release notes, videos and slides: http://r-datatable.com
## 
## Attaching package: 'data.table'
## The following objects are masked from 'package:dplyr':
## 
##     between, first, last
# Import potatoes.csv with fread(): potatoes
potatoes <- fread("Datos/potatoes.csv")

# Print out potatoes
print(potatoes)
##      area temp size storage method texture flavor moistness
##   1:    1    1    1       1      1     2.9    3.2       3.0
##   2:    1    1    1       1      2     2.3    2.5       2.6
##   3:    1    1    1       1      3     2.5    2.8       2.8
##   4:    1    1    1       1      4     2.1    2.9       2.4
##   5:    1    1    1       1      5     1.9    2.8       2.2
##  ---                                                       
## 156:    2    2    2       4      1     2.7    3.3       2.6
## 157:    2    2    2       4      2     2.6    2.8       2.3
## 158:    2    2    2       4      3     2.5    3.1       2.6
## 159:    2    2    2       4      4     3.4    3.3       3.0
## 160:    2    2    2       4      5     2.5    2.8       2.3

Tiene dos argumentos principales:

  • drop. Elimina las columnas seleccionadas
  • select. Elimina las columnas no seleccionadas, o dicho de otro modo, solo las columnas seleccionadas son las que se cargan en R. Supongamos que queremos mantener las variables 1 y 8 al cargar en R los datos de potatoes, que se corresponden con la columna area y moistness:
fread("Datos/potatoes.csv", drop = 2:7) # eliminamos las columnas 2 a 7, incluidas
##      area moistness
##   1:    1       3.0
##   2:    1       2.6
##   3:    1       2.8
##   4:    1       2.4
##   5:    1       2.2
##  ---               
## 156:    2       2.6
## 157:    2       2.3
## 158:    2       2.6
## 159:    2       3.0
## 160:    2       2.3
fread("Datos/potatoes.csv", select = c(1, 8)) # seleccionamos solo las columnas que nos interesan
##      area moistness
##   1:    1       3.0
##   2:    1       2.6
##   3:    1       2.8
##   4:    1       2.4
##   5:    1       2.2
##  ---               
## 156:    2       2.6
## 157:    2       2.3
## 158:    2       2.6
## 159:    2       3.0
## 160:    2       2.3
fread("Datos/potatoes.csv", drop = c("temp", "size", "storage", "method", "texture", "flavor"))
##      area moistness
##   1:    1       3.0
##   2:    1       2.6
##   3:    1       2.8
##   4:    1       2.4
##   5:    1       2.2
##  ---               
## 156:    2       2.6
## 157:    2       2.3
## 158:    2       2.6
## 159:    2       3.0
## 160:    2       2.3
fread("Datos/potatoes.csv", select = c("area", "moistness"))
##      area moistness
##   1:    1       3.0
##   2:    1       2.6
##   3:    1       2.8
##   4:    1       2.4
##   5:    1       2.2
##  ---               
## 156:    2       2.6
## 157:    2       2.3
## 158:    2       2.6
## 159:    2       3.0
## 160:    2       2.3

5.2.1.3 Comparando la clase de objetos de readr y data.table

The class of the result of fread() is both data.table and data.frame. read_tsv() creates an object with three classes: tbl_df, tbl and data.frame.

5.2.2 readxlpara importar datos desde Microsoft Excel

readxl es un paquete desarrollado por Hadley Wickham. Este paquete contiene exclusivamente dos funciones:

  • excel_sheets(). Con esta función vamos a ver las diferentes hojas de cálculo de nuestro Excel.
  • read_excel(). Con esta función importaremos los datos en R de una hoja de cálculo Excel.
# Cargamos la función en nuestra sesión de R
library(readxl)

Vamos a trabajar con un ejemplo, urbanpop.xlsx, que tiene los datos de la pobación urbana de casi todos los países del mundo a lo largo del tiempo. Contiene tres hojas de cálculo para diferentes periodos de tiempo. En cada hoja, la primera fila contiene el nombre de las columnas.

# Vamos a ver las tres hojas de cálculo que contiene urbanpop.xlsx
# La función excel_sheets() te devuelve el resultado en modo vector
excel_sheets("Datos/urbanpop.xlsx")
## [1] "1960-1966" "1967-1974" "1975-2011"
# Ahora cargamos las 3 hojas del archivo añadiendo el argumento sheet.
pop_1 <- read_excel("Datos/urbanpop.xlsx", sheet = 1)
pop_2 <- read_excel("Datos/urbanpop.xlsx", sheet = 2)
pop_3 <- read_excel("Datos/urbanpop.xlsx", sheet = 3)

# Generamos una lista con los 3 objetos anteriores
pop_list <- list(pop_1, pop_2, pop_3)

El argumento sheets vale para indicar qué hoja de cálculo queremos importar a R. Podemos hacerlo con números, donde el 1 indica la primera hoja y el 3 la última de nuestro ejemplo, o bien añadiendo directamente el nombre de la hoja entre comillas. En nuestro ejemplo sheets = 1 y sheets = "1960-1966" importaría la misma hoja.

5.2.2.1 Combinar readxl con la función lapply()

Si nuestro archivo Excel tiene una gran cantidad de hojas de cálculo, la importación de cada una en nuestra sesión de R puede ser algo tedioso. Para eso, la función lapply() nos puede ayudar de un modo muy eficiente.

pop_list <- lapply(excel_sheets("Datos/urbanpop.xlsx"), read_excel, path = "Datos/urbanpop.xlsx")

Los principales argumentos de read_excel() son:

  • path: indicamos la ruta del archivo, como ya hemos hecho.
  • sheet: indicamos la hoja de cálculo a importar.
  • col_names: De modo predeterminado viene TRUE, pero podemos poner FALSE si no hay títulos de las columnas. Podemos también añadir un vector con los nombres personalizados.
  • col_types: de modo predeterminado viene NULL. Podemos añadir un vector con los tipos, por ejemplo c("text", "text"). También pueden ser numeric, date and blank. Con blank lo que hacemos es ignorar esa columna.
  • skip: se refiere a las filas que no queremos cargar en R a partir del archivo Excel. Hay que tener en cuenta que considera la primera fila también, por lo que si hay título de columnas, también las eliminará. Esto es interesante tenerlo en cuenta porque tendremos que usar entonces el argumento col_names en combinación con skip.
# Importamos urbanpop_nonames.xlsx como pop_a. No hay nombres y R los da automáticamente
pop_a <- read_excel("Datos/urbanpop_nonames.xlsx", sheet = 1, col_names = FALSE)

# Importamos urbanpop_nonames.xlsx como pop_a. No hay nombres, pero los definimos en cols
cols <- c("country", paste0("year_", 1960:1966))
pop_b <- read_excel("Datos/urbanpop_nonames.xlsx", sheet = 1, col_names = cols)

5.2.3 gdata como alternativa a readxl

gdata es un paquete creado por Gregory Warnes, y es una caja de herramientas para manipulación de datos, entre los que se encuentra la importación de archivos Excel a R, con la función read.xls().

Para la importación de los archivos Excel, gdata utiliza Perl, otro lenguaje de programación. Esta función lo que hace es usar Perl para transformar el archivo Excel .xls en un .csv, y posteriormente utiliza la función read.csv() del paquete utils para importarlo a R. Con la ventaja de poder añadir todos los argumentos de esta última función.

# Cargamos el paquete
library(gdata)
## gdata: read.xls support for 'XLS' (Excel 97-2004) files ENABLED.
## 
## gdata: read.xls support for 'XLSX' (Excel 2007+) files ENABLED.
## 
## Attaching package: 'gdata'
## The following objects are masked from 'package:data.table':
## 
##     first, last
## The following objects are masked from 'package:dplyr':
## 
##     combine, first, last
## The following object is masked from 'package:stats':
## 
##     nobs
## The following object is masked from 'package:utils':
## 
##     object.size
## The following object is masked from 'package:base':
## 
##     startsWith
# Importamos la segunda hoja de urbanpop.xlsx: urban_pop
urban_pop <- read.xls("Datos/urbanpop.xlsx", sheet = 2)

# Print the first 11 observations using head()
head(urban_pop, n = 11)
##                country       X1967       X1968       X1969       X1970
## 1          Afghanistan  1119067.20  1182159.06  1248900.79  1319848.78
## 2              Albania   621179.85   639964.46   658853.12   677839.12
## 3              Algeria  4826104.22  5017298.60  5219331.87  5429743.08
## 4       American Samoa    17348.66    17995.51    18618.68    19206.39
## 5              Andorra    15439.62    16726.99    18088.32    19528.96
## 6               Angola   757496.32   798459.26   841261.96   886401.63
## 7  Antigua and Barbuda    22086.25    22149.39    22182.92    22180.87
## 8            Argentina 17753280.98 18124103.64 18510462.30 18918072.79
## 9              Armenia  1337032.09  1392892.13  1449641.49  1507619.77
## 10               Aruba    29414.72    29576.09    29737.87    29901.57
## 11           Australia  9934404.03 10153969.77 10412390.67 10664093.55
##          X1971       X1972       X1973       X1974
## 1   1409001.09  1502401.79  1598835.45  1696444.83
## 2    698932.25   720206.57   741681.04   763385.45
## 3   5619041.53  5815734.49  6020647.35  6235114.38
## 4     19752.02    20262.67    20741.97    21194.38
## 5     20928.73    22405.84    23937.05    25481.98
## 6    955010.09  1027397.35  1103829.78  1184486.23
## 7     22560.87    22907.76    23221.29    23502.92
## 8  19329718.16 19763078.00 20211424.85 20664728.90
## 9   1564367.60  1622103.53  1680497.75  1739063.02
## 10    30081.36    30279.76    30467.42    30602.87
## 11 11047706.39 11269945.50 11461120.68 11772934.25
# Vamos con un segundo ejemplo algo más completo
# Column names for urban_pop
columns <- c("country", paste0("year_", 1967:1974))

# Finish the read.xls call
urban_pop <- read.xls("Datos/urbanpop.xlsx", sheet = 2,
                      skip = 50, header = FALSE, stringsAsFactors = FALSE,
                      col.names = columns)

# Print first 10 observation of urban_pop
head(urban_pop, n= 10)
##               country   year_1967   year_1968   year_1969   year_1970
## 1              Cyprus   231929.74   237831.38   243983.34   250164.52
## 2      Czech Republic  6204409.91  6266304.50  6326368.97  6348794.89
## 3             Denmark  3777552.62  3826785.08  3874313.99  3930042.97
## 4            Djibouti    77788.04    84694.35    92045.77    99845.22
## 5            Dominica    27550.36    29527.32    31475.62    33328.25
## 6  Dominican Republic  1535485.43  1625455.76  1718315.40  1814060.00
## 7             Ecuador  2059355.12  2151395.14  2246890.79  2345864.41
## 8               Egypt 13798171.00 14248342.19 14703858.22 15162858.52
## 9         El Salvador  1345528.98  1387218.33  1429378.98  1472181.26
## 10  Equatorial Guinea    75364.50    77295.03    78445.74    78411.07
##      year_1971   year_1972   year_1973   year_1974
## 1    261213.21   272407.99   283774.90   295379.83
## 2   6437055.17  6572632.32  6718465.53  6873458.18
## 3   3981360.12  4028247.92  4076867.28  4120201.43
## 4    107799.69   116098.23   125391.58   136606.25
## 5     34761.52    36049.99    37260.05    38501.47
## 6   1915590.38  2020157.01  2127714.45  2238203.87
## 7   2453817.78  2565644.81  2681525.25  2801692.62
## 8  15603661.36 16047814.69 16498633.27 16960827.93
## 9   1527985.34  1584758.18  1642098.95  1699470.87
## 10    77055.29    74596.06    71438.96    68179.26
# Otro ejemplo haciendo filtrado de datos, etc
# Add code to import data from all three sheets in urbanpop.xls
path <- "Datos/urbanpop.xlsx"
urban_sheet1 <- read.xls(path, sheet = 1, stringsAsFactors = FALSE)
urban_sheet2 <- read.xls(path, sheet = 2, stringsAsFactors = FALSE)
urban_sheet3 <- read.xls(path, sheet = 3, stringsAsFactors = FALSE)

# Extend the cbind() call to include urban_sheet3: urban
urban <- cbind(urban_sheet1, urban_sheet2[-1], urban_sheet3[-1])

# Remove all rows with NAs from urban: urban_clean
urban_clean <- na.omit(urban)

# Print out a summary of urban_clean
summary(urban_clean)
##    country              X1960               X1961          
##  Length:197         Min.   :     3378   Min.   :     3433  
##  Class :character   1st Qu.:    87735   1st Qu.:    92905  
##  Mode  :character   Median :   599714   Median :   630788  
##                     Mean   :  5012388   Mean   :  5282488  
##                     3rd Qu.:  3130085   3rd Qu.:  3155370  
##                     Max.   :126469700   Max.   :129268133  
##      X1962               X1963               X1964          
##  Min.   :     3481   Min.   :     3532   Min.   :     3586  
##  1st Qu.:    98331   1st Qu.:   104988   1st Qu.:   112084  
##  Median :   659464   Median :   704989   Median :   740609  
##  Mean   :  5440972   Mean   :  5612312   Mean   :  5786961  
##  3rd Qu.:  3250211   3rd Qu.:  3416490   3rd Qu.:  3585464  
##  Max.   :131974143   Max.   :134599886   Max.   :137205240  
##      X1965               X1966               X1967          
##  Min.   :     3644   Min.   :     3706   Min.   :     3771  
##  1st Qu.:   119322   1st Qu.:   128565   1st Qu.:   138024  
##  Median :   774957   Median :   809768   Median :   838449  
##  Mean   :  5964970   Mean   :  6126413   Mean   :  6288771  
##  3rd Qu.:  3666724   3rd Qu.:  3871757   3rd Qu.:  4019906  
##  Max.   :139663053   Max.   :141962708   Max.   :144201722  
##      X1968               X1969               X1970          
##  Min.   :     3835   Min.   :     3893   Min.   :     3941  
##  1st Qu.:   147846   1st Qu.:   158252   1st Qu.:   171063  
##  Median :   890270   Median :   929450   Median :   976471  
##  Mean   :  6451367   Mean   :  6624909   Mean   :  6799110  
##  3rd Qu.:  4158186   3rd Qu.:  4300669   3rd Qu.:  4440047  
##  Max.   :146340364   Max.   :148475901   Max.   :150922373  
##      X1971               X1972               X1973          
##  Min.   :     4017   Min.   :     4084   Min.   :     4146  
##  1st Qu.:   181483   1st Qu.:   189492   1st Qu.:   197792  
##  Median :  1008630   Median :  1048738   Median :  1097293  
##  Mean   :  6980895   Mean   :  7165338   Mean   :  7349454  
##  3rd Qu.:  4595966   3rd Qu.:  4766545   3rd Qu.:  4838297  
##  Max.   :152863831   Max.   :154530473   Max.   :156034106  
##      X1974               X1975               X1976          
##  Min.   :     4206   Min.   :     4267   Min.   :     4334  
##  1st Qu.:   205410   1st Qu.:   211746   1st Qu.:   216991  
##  Median :  1159402   Median :  1223146   Median :  1249829  
##  Mean   :  7540446   Mean   :  7731973   Mean   :  7936401  
##  3rd Qu.:  4906384   3rd Qu.:  5003370   3rd Qu.:  5121118  
##  Max.   :157488074   Max.   :159452730   Max.   :165583752  
##      X1977               X1978               X1979          
##  Min.   :     4402   Min.   :     4470   Min.   :     4539  
##  1st Qu.:   222209   1st Qu.:   227605   1st Qu.:   233461  
##  Median :  1311276   Median :  1340811   Median :  1448185  
##  Mean   :  8145945   Mean   :  8361360   Mean   :  8583138  
##  3rd Qu.:  5227677   3rd Qu.:  5352746   3rd Qu.:  5558850  
##  Max.   :171550310   Max.   :177605736   Max.   :183785364  
##      X1980               X1981               X1982          
##  Min.   :     4607   Min.   :     4645   Min.   :     4681  
##  1st Qu.:   242583   1st Qu.:   248948   1st Qu.:   257944  
##  Median :  1592397   Median :  1673079   Median :  1713060  
##  Mean   :  8808772   Mean   :  9049163   Mean   :  9295226  
##  3rd Qu.:  5815772   3rd Qu.:  6070457   3rd Qu.:  6337995  
##  Max.   :189947471   Max.   :199385258   Max.   :209435968  
##      X1983               X1984               X1985          
##  Min.   :     4716   Min.   :     4750   Min.   :     4782  
##  1st Qu.:   274139   1st Qu.:   284939   1st Qu.:   300928  
##  Median :  1730626   Median :  1749033   Median :  1786125  
##  Mean   :  9545035   Mean   :  9798559   Mean   : 10058661  
##  3rd Qu.:  6619987   3rd Qu.:  6918261   3rd Qu.:  6931780  
##  Max.   :219680098   Max.   :229872397   Max.   :240414890  
##      X1986               X1987               X1988          
##  Min.   :     4809   Min.   :     4835   Min.   :     4859  
##  1st Qu.:   307699   1st Qu.:   321125   1st Qu.:   334616  
##  Median :  1850910   Median :  1953694   Median :  1997011  
##  Mean   : 10323839   Mean   : 10595817   Mean   : 10873041  
##  3rd Qu.:  6935763   3rd Qu.:  6939905   3rd Qu.:  6945022  
##  Max.   :251630158   Max.   :263433513   Max.   :275570541  
##      X1989               X1990               X1991          
##  Min.   :     4883   Min.   :     4907   Min.   :     4946  
##  1st Qu.:   347348   1st Qu.:   370152   1st Qu.:   394611  
##  Median :  1993544   Median :  2066505   Median :  2150230  
##  Mean   : 11154458   Mean   : 11438543   Mean   : 11725076  
##  3rd Qu.:  6885378   3rd Qu.:  6830026   3rd Qu.:  6816589  
##  Max.   :287810747   Max.   :300165618   Max.   :314689997  
##      X1992               X1993               X1994          
##  Min.   :     4985   Min.   :     5024   Min.   :     5062  
##  1st Qu.:   418788   1st Qu.:   427457   1st Qu.:   435959  
##  Median :  2237405   Median :  2322158   Median :  2410297  
##  Mean   : 12010922   Mean   : 12296949   Mean   : 12582930  
##  3rd Qu.:  6820099   3rd Qu.:  7139656   3rd Qu.:  7499901  
##  Max.   :329099365   Max.   :343555327   Max.   :358232230  
##      X1995               X1996               X1997          
##  Min.   :     5100   Min.   :     5079   Min.   :     5055  
##  1st Qu.:   461993   1st Qu.:   488136   1st Qu.:   494203  
##  Median :  2482393   Median :  2522460   Median :  2606125  
##  Mean   : 12871480   Mean   : 13165924   Mean   : 13463675  
##  3rd Qu.:  7708571   3rd Qu.:  7686092   3rd Qu.:  7664316  
##  Max.   :373035157   Max.   :388936607   Max.   :405031716  
##      X1998               X1999               X2000          
##  Min.   :     5029   Min.   :     5001   Min.   :     4971  
##  1st Qu.:   498002   1st Qu.:   505144   1st Qu.:   525629  
##  Median :  2664983   Median :  2737809   Median :  2826647  
##  Mean   : 13762861   Mean   : 14063387   Mean   : 14369278  
##  3rd Qu.:  7784056   3rd Qu.:  8083488   3rd Qu.:  8305564  
##  Max.   :421147610   Max.   :437126845   Max.   :452999147  
##      X2001               X2002               X2003          
##  Min.   :     5003   Min.   :     5034   Min.   :     5064  
##  1st Qu.:   550638   1st Qu.:   567531   1st Qu.:   572094  
##  Median :  2925851   Median :  2928252   Median :  2944934  
##  Mean   : 14705743   Mean   : 15043381   Mean   : 15384513  
##  3rd Qu.:  8421967   3rd Qu.:  8448628   3rd Qu.:  8622732  
##  Max.   :473204511   Max.   :493402140   Max.   :513607776  
##      X2004               X2005               X2006          
##  Min.   :     5090   Min.   :     5111   Min.   :     5135  
##  1st Qu.:   593900   1st Qu.:   620511   1st Qu.:   632659  
##  Median :  2994356   Median :  3057923   Median :  3269963  
##  Mean   : 15730299   Mean   : 16080262   Mean   : 16435872  
##  3rd Qu.:  8999112   3rd Qu.:  9394001   3rd Qu.:  9689807  
##  Max.   :533892175   Max.   :554367818   Max.   :575050081  
##      X2007               X2008               X2009          
##  Min.   :     5155   Min.   :     5172   Min.   :     5189  
##  1st Qu.:   645172   1st Qu.:   658017   1st Qu.:   671085  
##  Median :  3432024   Median :  3589395   Median :  3652338  
##  Mean   : 16797484   Mean   : 17164898   Mean   : 17533997  
##  3rd Qu.:  9803381   3rd Qu.: 10210317   3rd Qu.: 10518289  
##  Max.   :595731464   Max.   :616552722   Max.   :637533976  
##      X2010               X2011          
##  Min.   :     5206   Min.   :     5233  
##  1st Qu.:   684302   1st Qu.:   698009  
##  Median :  3676309   Median :  3664664  
##  Mean   : 17904811   Mean   : 18276297  
##  3rd Qu.: 10618596   3rd Qu.: 10731193  
##  Max.   :658557734   Max.   :678796403

5.3 XLConnect: puente entre Microsoft Excel y R

Esta paquete está desarrollado por Martin Studer, y sirve para conectar R con Excel. Se considera como un puente entre Excel y R, utilizando Java como conector. Trabaja tanto con archivos XLS como XLSX.

Cuando se instala en R, también instala, entre otros, los paquetes XLConnectJars (que define las clases de Java) y rJava, que introduce la interfaz de Java en R.

XLConnect genera un nuevo tipo de objeto en R que se llama workbook. Aquí están algunas de las principales funciones de este paquete:

  • loadWorkbook(): sirve para conectar R con un archivo Excel generando el archivo workbook.
  • getSheets(): sirve para sacar los nombres de las hojas de cálculo.
  • readWorksheet(): sirve para cargar en R las hojas de cálculo. Tiene argumentos como startRow, endRow, startCol y endCol muy útiles para decirle exactamente qué parte de la hoja de cálculo queremos cargar.
# Load the XLConnect package
library(XLConnect)
## Loading required package: XLConnectJars
## XLConnect 0.2-15 by Mirai Solutions GmbH [aut],
##   Martin Studer [cre],
##   The Apache Software Foundation [ctb, cph] (Apache POI),
##   Graph Builder [ctb, cph] (Curvesapi Java library)
## http://www.mirai-solutions.com
## https://github.com/miraisolutions/xlconnect
# Build connection to urbanpop.xlsx: my_book
my_book <- loadWorkbook("Datos/urbanpop.xlsx")

# Print out the class of my_book
class(my_book)
## [1] "workbook"
## attr(,"package")
## [1] "XLConnect"
# List the sheets in my_book
getSheets(my_book)
## [1] "1960-1966" "1967-1974" "1975-2011"
# Import the second sheet in my_book
readWorksheet(my_book, sheet= "1967-1974")
##                            country        X1967        X1968        X1969
## 1                      Afghanistan 1.119067e+06 1.182159e+06 1.248901e+06
## 2                          Albania 6.211798e+05 6.399645e+05 6.588531e+05
## 3                          Algeria 4.826104e+06 5.017299e+06 5.219332e+06
## 4                   American Samoa 1.734866e+04 1.799551e+04 1.861868e+04
## 5                          Andorra 1.543962e+04 1.672699e+04 1.808832e+04
## 6                           Angola 7.574963e+05 7.984593e+05 8.412620e+05
## 7              Antigua and Barbuda 2.208625e+04 2.214939e+04 2.218292e+04
## 8                        Argentina 1.775328e+07 1.812410e+07 1.851046e+07
## 9                          Armenia 1.337032e+06 1.392892e+06 1.449641e+06
## 10                           Aruba 2.941472e+04 2.957609e+04 2.973787e+04
## 11                       Australia 9.934404e+06 1.015397e+07 1.041239e+07
## 12                         Austria 4.803149e+06 4.831817e+06 4.852208e+06
## 13                      Azerbaijan 2.446990e+06 2.495725e+06 2.542062e+06
## 14                         Bahamas 9.868390e+04 1.036697e+05 1.084730e+05
## 15                         Bahrain 1.619616e+05 1.663785e+05 1.714590e+05
## 16                      Bangladesh 4.173453e+06 4.484842e+06 4.790505e+06
## 17                        Barbados 8.819371e+04 8.858041e+04 8.902489e+04
## 18                         Belarus 3.556448e+06 3.696854e+06 3.838003e+06
## 19                         Belgium 8.950504e+06 8.999366e+06 9.038506e+06
## 20                          Belize 5.879024e+04 5.971173e+04 6.049220e+04
## 21                           Benin 3.820221e+05 4.118595e+05 4.430131e+05
## 22                         Bermuda 5.200000e+04 5.300000e+04 5.400000e+04
## 23                          Bhutan 1.437897e+04 1.561689e+04 1.694642e+04
## 24                         Bolivia 1.527065e+06 1.575177e+06 1.625173e+06
## 25          Bosnia and Herzegovina 8.516924e+05 8.902697e+05 9.294496e+05
## 26                        Botswana 3.431976e+04 4.057616e+04 4.722223e+04
## 27                          Brazil 4.719352e+07 4.931688e+07 5.148910e+07
## 28                          Brunei 6.128905e+04 6.622218e+04 7.150276e+04
## 29                        Bulgaria 4.019906e+06 4.158186e+06 4.300669e+06
## 30                    Burkina Faso 2.968238e+05 3.086611e+05 3.209607e+05
## 31                         Burundi 7.616560e+04 7.881625e+04 8.135573e+04
## 32                        Cambodia 8.357562e+05 9.263155e+05 1.017799e+06
## 33                        Cameroon 1.157892e+06 1.231243e+06 1.308158e+06
## 34                          Canada 1.510423e+07 1.546449e+07 1.579236e+07
## 35                      Cape Verde 4.724476e+04 4.923400e+04 5.135658e+04
## 36                  Cayman Islands 8.875000e+03 9.002000e+03 9.216000e+03
## 37        Central African Republic 4.303721e+05 4.529338e+05 4.761054e+05
## 38                            Chad 3.315042e+05 3.605791e+05 3.909776e+05
## 39                 Channel Islands 4.329456e+04 4.344349e+04 4.358417e+04
## 40                           Chile 6.606825e+06 6.805959e+06 7.005123e+06
## 41                           China 1.343974e+08 1.368900e+08 1.396005e+08
## 42                        Colombia 1.033119e+07 1.078053e+07 1.123560e+07
## 43                         Comoros 3.978906e+04 4.183902e+04 4.396565e+04
## 44                Congo, Dem. Rep. 5.161472e+06 5.475208e+06 5.802069e+06
## 45                     Congo, Rep. 4.506698e+05 4.733352e+05 4.972107e+05
## 46                      Costa Rica 6.217858e+05 6.499164e+05 6.782539e+05
## 47                   Cote d'Ivoire 1.243350e+06 1.330719e+06 1.424438e+06
## 48                         Croatia 1.608233e+06 1.663051e+06 1.717607e+06
## 49                            Cuba 4.927341e+06 5.032014e+06 5.137260e+06
## 50                          Cyprus 2.319297e+05 2.378314e+05 2.439833e+05
## 51                  Czech Republic 6.204410e+06 6.266305e+06 6.326369e+06
## 52                         Denmark 3.777553e+06 3.826785e+06 3.874314e+06
## 53                        Djibouti 7.778804e+04 8.469435e+04 9.204577e+04
## 54                        Dominica 2.755036e+04 2.952732e+04 3.147562e+04
## 55              Dominican Republic 1.535485e+06 1.625456e+06 1.718315e+06
## 56                         Ecuador 2.059355e+06 2.151395e+06 2.246891e+06
## 57                           Egypt 1.379817e+07 1.424834e+07 1.470386e+07
## 58                     El Salvador 1.345529e+06 1.387218e+06 1.429379e+06
## 59               Equatorial Guinea 7.536450e+04 7.729503e+04 7.844574e+04
## 60                         Eritrea 2.025150e+05 2.121646e+05 2.221863e+05
## 61                         Estonia 8.283882e+05 8.472205e+05 8.662579e+05
## 62                        Ethiopia 2.139904e+06 2.249670e+06 2.365149e+06
## 63                  Faeroe Islands 9.878976e+03 1.017780e+04 1.047732e+04
## 64                            Fiji 1.632216e+05 1.690663e+05 1.749364e+05
## 65                         Finland 2.822234e+06 2.872371e+06 2.908120e+06
## 66                          France 3.486791e+07 3.554830e+07 3.622608e+07
## 67                French Polynesia 5.087720e+04 5.421077e+04 5.768190e+04
## 68                           Gabon 1.380242e+05 1.478459e+05 1.582525e+05
## 69                          Gambia 7.036836e+04 7.628527e+04 8.261546e+04
## 70                         Georgia 1.863610e+06 1.900576e+06 1.938616e+06
## 71                         Germany 5.546852e+07 5.576506e+07 5.625874e+07
## 72                           Ghana 2.219604e+06 2.311442e+06 2.408851e+06
## 73                          Greece 4.300274e+06 4.415310e+06 4.518763e+06
## 74                       Greenland 2.879686e+04 3.040882e+04 3.206093e+04
## 75                         Grenada 3.004680e+04 3.019593e+04 3.031077e+04
## 76                            Guam 4.629560e+04 4.844571e+04 5.065242e+04
## 77                       Guatemala 1.739459e+06 1.802725e+06 1.868309e+06
## 78                          Guinea 5.618868e+05 5.962425e+05 6.304226e+05
## 79                   Guinea-Bissau 8.719596e+04 8.804516e+04 8.932212e+04
## 80                          Guyana 1.979563e+05 2.033071e+05 2.081042e+05
## 81                           Haiti 8.205857e+05 8.567168e+05 8.934834e+05
## 82                        Honduras 6.700552e+05 7.041621e+05 7.396318e+05
## 83                Hong Kong, China 3.236781e+06 3.316190e+06 3.379661e+06
## 84                         Hungary 6.013289e+06 6.079237e+06 6.147720e+06
## 85                         Iceland 1.661399e+05 1.693063e+05 1.717736e+05
## 86                           India 9.936339e+07 1.025948e+08 1.059532e+08
## 87                       Indonesia 1.786885e+07 1.862152e+07 1.940053e+07
## 88                            Iran 1.024223e+07 1.074839e+07 1.127204e+07
## 89                            Iraq 4.785700e+06 5.053788e+06 5.335012e+06
## 90                         Ireland 1.448735e+06 1.472843e+06 1.499153e+06
## 91                     Isle of Man 2.974060e+04 3.041582e+04 3.107182e+04
## 92                          Israel 2.257543e+06 2.323491e+06 2.403561e+06
## 93                           Italy 3.322924e+07 3.369844e+07 3.414982e+07
## 94                         Jamaica 7.040407e+05 7.257254e+05 7.482876e+05
## 95                           Japan 6.997406e+07 7.101819e+07 7.332929e+07
## 96                          Jordan 7.024333e+05 7.513107e+05 7.991228e+05
## 97                      Kazakhstan 6.018757e+06 6.209379e+06 6.396692e+06
## 98                           Kenya 9.424282e+05 1.010199e+06 1.082085e+06
## 99                        Kiribati 9.944575e+03 1.054187e+04 1.115324e+04
## 100                    North Korea 6.359134e+06 6.797010e+06 7.252939e+06
## 101                    South Korea 1.067144e+07 1.142358e+07 1.219746e+07
## 102                         Kuwait 4.812897e+05 5.332849e+05 5.878232e+05
## 103                Kyrgyz Republic 9.987404e+05 1.037698e+06 1.075216e+06
## 104                            Lao 2.214381e+05 2.333150e+05 2.458144e+05
## 105                         Latvia 1.343553e+06 1.374667e+06 1.404423e+06
## 106                        Lebanon 1.253621e+06 1.320402e+06 1.390579e+06
## 107                        Lesotho 7.042371e+04 7.636722e+04 8.253367e+04
## 108                        Liberia 3.145211e+05 3.336211e+05 3.536543e+05
## 109                          Libya 7.048490e+05 7.933851e+05 8.884915e+05
## 110                  Liechtenstein 3.771201e+03 3.835222e+03 3.893073e+03
## 111                      Lithuania 1.415402e+06 1.462854e+06 1.508107e+06
##            X1970        X1971        X1972        X1973        X1974
## 1   1.319849e+06 1.409001e+06 1.502402e+06 1.598835e+06 1.696445e+06
## 2   6.778391e+05 6.989322e+05 7.202066e+05 7.416810e+05 7.633855e+05
## 3   5.429743e+06 5.619042e+06 5.815734e+06 6.020647e+06 6.235114e+06
## 4   1.920639e+04 1.975202e+04 2.026267e+04 2.074197e+04 2.119438e+04
## 5   1.952896e+04 2.092873e+04 2.240584e+04 2.393705e+04 2.548198e+04
## 6   8.864016e+05 9.550101e+05 1.027397e+06 1.103830e+06 1.184486e+06
## 7   2.218087e+04 2.256087e+04 2.290776e+04 2.322129e+04 2.350292e+04
## 8   1.891807e+07 1.932972e+07 1.976308e+07 2.021142e+07 2.066473e+07
## 9   1.507620e+06 1.564368e+06 1.622104e+06 1.680498e+06 1.739063e+06
## 10  2.990157e+04 3.008136e+04 3.027976e+04 3.046742e+04 3.060287e+04
## 11  1.066409e+07 1.104771e+07 1.126995e+07 1.146112e+07 1.177293e+07
## 12  4.872871e+06 4.895910e+06 4.925699e+06 4.954325e+06 4.964026e+06
## 13  2.586413e+06 2.660993e+06 2.734825e+06 2.807955e+06 2.880447e+06
## 14  1.130101e+05 1.171566e+05 1.209989e+05 1.246644e+05 1.283499e+05
## 15  1.775008e+05 1.844398e+05 1.923163e+05 2.014935e+05 2.124162e+05
## 16  5.078286e+06 5.456170e+06 5.812548e+06 6.161815e+06 6.530579e+06
## 17  8.956543e+04 9.055245e+04 9.164208e+04 9.277639e+04 9.387156e+04
## 18  3.978504e+06 4.132164e+06 4.286801e+06 4.440936e+06 4.592935e+06
## 19  9.061057e+06 9.089909e+06 9.137946e+06 9.179155e+06 9.220531e+06
## 20  6.114133e+04 6.183991e+04 6.240329e+04 6.294338e+04 6.362671e+04
## 21  4.756114e+05 5.158195e+05 5.579376e+05 6.020932e+05 6.484097e+05
## 22  5.500000e+04 5.460000e+04 5.420000e+04 5.380000e+04 5.340000e+04
## 23  1.838141e+04 2.017266e+04 2.209976e+04 2.415974e+04 2.634254e+04
## 24  1.677184e+06 1.731437e+06 1.787719e+06 1.845894e+06 1.905749e+06
## 25  9.695495e+05 1.008630e+06 1.048738e+06 1.089648e+06 1.130966e+06
## 26  5.428641e+04 6.186900e+04 6.992963e+04 7.852997e+04 8.775392e+04
## 27  5.371642e+07 5.600051e+07 5.834048e+07 6.074473e+07 6.322438e+07
## 28  7.714802e+04 8.088400e+04 8.478142e+04 8.880798e+04 9.291945e+04
## 29  4.440047e+06 4.554372e+06 4.665864e+06 4.780947e+06 4.904324e+06
## 30  3.336985e+05 3.475107e+05 3.618362e+05 3.767243e+05 3.922410e+05
## 31  8.369155e+04 9.049313e+04 9.717071e+04 1.038732e+05 1.108747e+05
## 32  1.107998e+06 9.614523e+05 8.076237e+05 6.470452e+05 4.811320e+05
## 33  1.388878e+06 1.523689e+06 1.665342e+06 1.814545e+06 1.972201e+06
## 34  1.613246e+07 1.637385e+07 1.663528e+07 1.691758e+07 1.722167e+07
## 35  5.364682e+04 5.638241e+04 5.931521e+04 6.221562e+04 6.475257e+04
## 36  9.545000e+03 1.000400e+04 1.058100e+04 1.125300e+04 1.199000e+04
## 37  4.997496e+05 5.268630e+05 5.546158e+05 5.832534e+05 6.131560e+05
## 38  4.229151e+05 4.628673e+05 5.049060e+05 5.488032e+05 5.940966e+05
## 39  4.371195e+04 4.368323e+04 4.363962e+04 4.355859e+04 4.341204e+04
## 40  7.204920e+06 7.398470e+06 7.592419e+06 7.785880e+06 7.977602e+06
## 41  1.423868e+08 1.463523e+08 1.499932e+08 1.534576e+08 1.566609e+08
## 42  1.169300e+07 1.214719e+07 1.260270e+07 1.306371e+07 1.353659e+07
## 43  4.615440e+04 4.811136e+04 5.012270e+04 5.227286e+04 5.468356e+04
## 44  6.140904e+06 6.282834e+06 6.425372e+06 6.570538e+06 6.721175e+06
## 45  5.224066e+05 5.497894e+05 5.786398e+05 6.088504e+05 6.402364e+05
## 46  7.067986e+05 7.335459e+05 7.604308e+05 7.879183e+05 8.166588e+05
## 47  1.525425e+06 1.638738e+06 1.760508e+06 1.891241e+06 2.031395e+06
## 48  1.773046e+06 1.826422e+06 1.879428e+06 1.932436e+06 1.984976e+06
## 49  5.244279e+06 5.407254e+06 5.572975e+06 5.738231e+06 5.898512e+06
## 50  2.501645e+05 2.612132e+05 2.724080e+05 2.837749e+05 2.953798e+05
## 51  6.348795e+06 6.437055e+06 6.572632e+06 6.718466e+06 6.873458e+06
## 52  3.930043e+06 3.981360e+06 4.028248e+06 4.076867e+06 4.120201e+06
## 53  9.984522e+04 1.077997e+05 1.160982e+05 1.253916e+05 1.366062e+05
## 54  3.332825e+04 3.476152e+04 3.604999e+04 3.726005e+04 3.850147e+04
## 55  1.814060e+06 1.915590e+06 2.020157e+06 2.127714e+06 2.238204e+06
## 56  2.345864e+06 2.453818e+06 2.565645e+06 2.681525e+06 2.801693e+06
## 57  1.516286e+07 1.560366e+07 1.604781e+07 1.649863e+07 1.696083e+07
## 58  1.472181e+06 1.527985e+06 1.584758e+06 1.642099e+06 1.699471e+06
## 59  7.841107e+04 7.705529e+04 7.459606e+04 7.143896e+04 6.817926e+04
## 60  2.325927e+05 2.420318e+05 2.517894e+05 2.620127e+05 2.729047e+05
## 61  8.847697e+05 9.015668e+05 9.191148e+05 9.354101e+05 9.510326e+05
## 62  2.487032e+06 2.609266e+06 2.738496e+06 2.870320e+06 2.998291e+06
## 63  1.077427e+04 1.106567e+04 1.135462e+04 1.164494e+04 1.194279e+04
## 64  1.809345e+05 1.868715e+05 1.929448e+05 1.991372e+05 2.054102e+05
## 65  2.934402e+06 2.976176e+06 3.032239e+06 3.088022e+06 3.142947e+06
## 66  3.691751e+07 3.740758e+07 3.790747e+07 3.840573e+07 3.888504e+07
## 67  6.125900e+04 6.368624e+04 6.613374e+04 6.861999e+04 7.117748e+04
## 68  1.694483e+05 1.845557e+05 2.007952e+05 2.181618e+05 2.365466e+05
## 69  8.942094e+04 9.676352e+04 1.047188e+05 1.132281e+05 1.221660e+05
## 70  1.904782e+06 1.943501e+06 2.058124e+06 2.096168e+06 2.134461e+06
## 71  5.649607e+07 5.664462e+07 5.696131e+07 5.718614e+07 5.725360e+07
## 72  2.515296e+06 2.601135e+06 2.695926e+06 2.795186e+06 2.892229e+06
## 73  4.616575e+06 4.686154e+06 4.766545e+06 4.838297e+06 4.906384e+06
## 74  3.375322e+04 3.449046e+04 3.545317e+04 3.612819e+04 3.665970e+04
## 75  3.040587e+04 3.039084e+04 3.037836e+04 3.034479e+04 3.025489e+04
## 76  5.291621e+04 5.791466e+04 6.308539e+04 6.843879e+04 7.399464e+04
## 77  1.936380e+06 2.002850e+06 2.071676e+06 2.142378e+06 2.214270e+06
## 78  6.636291e+05 7.000651e+05 7.353800e+05 7.696670e+05 8.032624e+05
## 79  9.123325e+04 9.389158e+04 9.722136e+04 1.011893e+05 1.057146e+05
## 80  2.120772e+05 2.155336e+05 2.181112e+05 2.201426e+05 2.221226e+05
## 81  9.307198e+05 9.535772e+05 9.764460e+05 9.996672e+05 1.023722e+06
## 82  7.769459e+05 8.163257e+05 8.577454e+05 9.014120e+05 9.475283e+05
## 83  3.473191e+06 3.564807e+06 3.650021e+06 3.771147e+06 3.870519e+06
## 84  6.214324e+06 6.276071e+06 6.338877e+06 6.403550e+06 6.476603e+06
## 85  1.735679e+05 1.757064e+05 1.790372e+05 1.825107e+05 1.857581e+05
## 86  1.094455e+08 1.137519e+08 1.182288e+08 1.228790e+08 1.277043e+08
## 87  2.020553e+07 2.127053e+07 2.237329e+07 2.351361e+07 2.469105e+07
## 88  1.181219e+07 1.239191e+07 1.299286e+07 1.362195e+07 1.428880e+07
## 89  5.627633e+06 5.924798e+06 6.232252e+06 6.551369e+06 6.884387e+06
## 90  1.529549e+06 1.558990e+06 1.593945e+06 1.631517e+06 1.670769e+06
## 91  3.166567e+04 3.182827e+04 3.189547e+04 3.190477e+04 3.190731e+04
## 92  2.503959e+06 2.598970e+06 2.681284e+06 2.808059e+06 2.909400e+06
## 93  3.459238e+07 3.490238e+07 3.525021e+07 3.564021e+07 3.602531e+07
## 94  7.723456e+05 7.935444e+05 8.162612e+05 8.398898e+05 8.633533e+05
## 95  7.500006e+07 7.678337e+07 7.868950e+07 8.017343e+07 8.256444e+07
## 96  8.440427e+05 8.861825e+05 9.252900e+05 9.628976e+05 1.001686e+06
## 97  6.585936e+06 6.756162e+06 6.928193e+06 7.100036e+06 7.268241e+06
## 98  1.158426e+06 1.261182e+06 1.370525e+06 1.486815e+06 1.610388e+06
## 99  1.177903e+04 1.253191e+04 1.329569e+04 1.407663e+04 1.488213e+04
## 100 7.721750e+06 8.009574e+06 8.299056e+06 8.584095e+06 8.857069e+06
## 101 1.299394e+07 1.374559e+07 1.451567e+07 1.530510e+07 1.611498e+07
## 102 6.451490e+05 7.009110e+05 7.585954e+05 8.180756e+05 8.792009e+05
## 103 1.108956e+06 1.136687e+06 1.165919e+06 1.195227e+06 1.226436e+06
## 104 2.590287e+05 2.739823e+05 2.898053e+05 3.060341e+05 3.219629e+05
## 105 1.432319e+06 1.459146e+06 1.487488e+06 1.516637e+06 1.546838e+06
## 106 1.465634e+06 1.541721e+06 1.622874e+06 1.705275e+06 1.783166e+06
## 107 8.892443e+04 9.542557e+04 1.021606e+05 1.091860e+05 1.165855e+05
## 108 3.746759e+05 3.980213e+05 4.225051e+05 4.482161e+05 4.752605e+05
## 109 9.904397e+05 1.087657e+06 1.191671e+06 1.302852e+06 1.421573e+06
## 110 3.941192e+03 4.016945e+03 4.084375e+03 4.146087e+03 4.206141e+03
## 111 1.555873e+06 1.614349e+06 1.671308e+06 1.727112e+06 1.782930e+06
##  [ reached getOption("max.print") -- omitted 98 rows ]
# Utilizando lapply para cargar todas las hojas
my_book <- loadWorkbook("Datos/urbanpop.xlsx")
sheets <- getSheets(my_book)
all <- lapply(sheets, readWorksheet, object = my_book)
str(all)
## List of 3
##  $ :'data.frame':    209 obs. of  8 variables:
##   ..$ country: chr [1:209] "Afghanistan" "Albania" "Algeria" "American Samoa" ...
##   ..$ X1960  : num [1:209] 769308 494443 3293999 NA NA ...
##   ..$ X1961  : num [1:209] 814923 511803 3515148 13660 8724 ...
##   ..$ X1962  : num [1:209] 858522 529439 3739963 14166 9700 ...
##   ..$ X1963  : num [1:209] 903914 547377 3973289 14759 10748 ...
##   ..$ X1964  : num [1:209] 951226 565572 4220987 15396 11866 ...
##   ..$ X1965  : num [1:209] 1000582 583983 4488176 16045 13053 ...
##   ..$ X1966  : num [1:209] 1058743 602512 4649105 16693 14217 ...
##  $ :'data.frame':    209 obs. of  9 variables:
##   ..$ country: chr [1:209] "Afghanistan" "Albania" "Algeria" "American Samoa" ...
##   ..$ X1967  : num [1:209] 1119067 621180 4826104 17349 15440 ...
##   ..$ X1968  : num [1:209] 1182159 639964 5017299 17996 16727 ...
##   ..$ X1969  : num [1:209] 1248901 658853 5219332 18619 18088 ...
##   ..$ X1970  : num [1:209] 1319849 677839 5429743 19206 19529 ...
##   ..$ X1971  : num [1:209] 1409001 698932 5619042 19752 20929 ...
##   ..$ X1972  : num [1:209] 1502402 720207 5815734 20263 22406 ...
##   ..$ X1973  : num [1:209] 1598835 741681 6020647 20742 23937 ...
##   ..$ X1974  : num [1:209] 1696445 763385 6235114 21194 25482 ...
##  $ :'data.frame':    209 obs. of  38 variables:
##   ..$ country: chr [1:209] "Afghanistan" "Albania" "Algeria" "American Samoa" ...
##   ..$ X1975  : num [1:209] 1793266 785350 6460138 21632 27019 ...
##   ..$ X1976  : num [1:209] 1905033 807990 6774099 22047 28366 ...
##   ..$ X1977  : num [1:209] 2021308 830959 7102902 22452 29677 ...
##   ..$ X1978  : num [1:209] 2142248 854262 7447728 22899 31037 ...
##   ..$ X1979  : num [1:209] 2268015 877898 7810073 23457 32572 ...
##   ..$ X1980  : num [1:209] 2398775 901884 8190772 24177 34366 ...
##   ..$ X1981  : num [1:209] 2493265 927224 8637724 25173 36356 ...
##   ..$ X1982  : num [1:209] 2590846 952447 9105820 26342 38618 ...
##   ..$ X1983  : num [1:209] 2691612 978476 9591900 27655 40983 ...
##   ..$ X1984  : num [1:209] 2795656 1006613 10091289 29062 43207 ...
##   ..$ X1985  : num [1:209] 2903078 1037541 10600112 30524 45119 ...
##   ..$ X1986  : num [1:209] 3006983 1072365 11101757 32014 46254 ...
##   ..$ X1987  : num [1:209] 3113957 1109954 11609104 33548 47019 ...
##   ..$ X1988  : num [1:209] 3224082 1146633 12122941 35095 47669 ...
##   ..$ X1989  : num [1:209] 3337444 1177286 12645263 36618 48577 ...
##   ..$ X1990  : num [1:209] 3454129 1198293 13177079 38088 49982 ...
##   ..$ X1991  : num [1:209] 3617842 1215445 13708813 39600 51972 ...
##   ..$ X1992  : num [1:209] 3788685 1222544 14248297 41049 54469 ...
##   ..$ X1993  : num [1:209] 3966956 1222812 14789176 42443 57079 ...
##   ..$ X1994  : num [1:209] 4152960 1221364 15322651 43798 59243 ...
##   ..$ X1995  : num [1:209] 4347018 1222234 15842442 45129 60598 ...
##   ..$ X1996  : num [1:209] 4531285 1228760 16395553 46343 60927 ...
##   ..$ X1997  : num [1:209] 4722603 1238090 16935451 47527 60462 ...
##   ..$ X1998  : num [1:209] 4921227 1250366 17469200 48705 59685 ...
##   ..$ X1999  : num [1:209] 5127421 1265195 18007937 49906 59281 ...
##   ..$ X2000  : num [1:209] 5341456 1282223 18560597 51151 59719 ...
##   ..$ X2001  : num [1:209] 5564492 1315690 19198872 52341 61062 ...
##   ..$ X2002  : num [1:209] 5795940 1352278 19854835 53583 63212 ...
##   ..$ X2003  : num [1:209] 6036100 1391143 20529356 54864 65802 ...
##   ..$ X2004  : num [1:209] 6285281 1430918 21222198 56166 68301 ...
##   ..$ X2005  : num [1:209] 6543804 1470488 21932978 57474 70329 ...
##   ..$ X2006  : num [1:209] 6812538 1512255 22625052 58679 71726 ...
##   ..$ X2007  : num [1:209] 7091245 1553491 23335543 59894 72684 ...
##   ..$ X2008  : num [1:209] 7380272 1594351 24061749 61118 73335 ...
##   ..$ X2009  : num [1:209] 7679982 1635262 24799591 62357 73897 ...
##   ..$ X2010  : num [1:209] 7990746 1676545 25545622 63616 74525 ...
##   ..$ X2011  : num [1:209] 8316976 1716842 26216968 64817 75207 ...
# Import columns 3, 4, and 5 from second sheet in my_book: urbanpop_sel
urbanpop_sel <- readWorksheet(my_book, sheet = 2, startCol = 3, endCol= 5)

# Import first column from second sheet in my_book: countries
countries <- readWorksheet(my_book, sheet = 2, startCol= 1, endCol=1)

# cbind() urbanpop_sel and countries together: selection
selection <- cbind(urbanpop_sel, countries)

5.3.1 Crear, rellenar, guardar nuevas hojas en Excel desde R

Generamos unos nuevos datos en R y queremos meterlos en nuestro Excel. Funciones:

  • createSheet(): creamos una nueva hoja de cálculo en nuestro Excel.
  • writeWorksheet(): le introducimos los datos que queremos a esa hoja Excel.
  • saveWorkbook(): guardamos los cambios de Excel.
# Add a worksheet to my_book, named "data_summary"
createSheet(my_book, "data_summary")

# Use getSheets() on my_book
getSheets(my_book)
## [1] "1960-1966"    "1967-1974"    "1975-2011"    "data_summary"
# Create data frame: summ
sheets <- getSheets(my_book)[1:3]
dims <- sapply(sheets, function(x) dim(readWorksheet(my_book, sheet = x)), USE.NAMES = FALSE)
summ <- data.frame(sheets = sheets,
                   nrows = dims[1, ],
                   ncols = dims[2, ])

# Add data in summ to "data_summary" sheet
writeWorksheet(my_book, summ, "data_summary")

# Save workbook as summary.xlsx
saveWorkbook(my_book, "Datos/summary.xlsx")

5.3.2 Renombrar y eliminar hojas de Excel

  • renameSheet(): tiene tres argumentos, el archivo Excel, nombre antiguo y nombre nuevo. Es importante guardar después con saveWorkbook().
  • removeSheet(): sirve para eliminar hojas del archivo Excel.
# Rename "data_summary" sheet to "summary"
renameSheet(my_book, "data_summary", "summary")

# Print out sheets of my_book
getSheets(my_book)
## [1] "1960-1966" "1967-1974" "1975-2011" "summary"
# Save workbook to "renamed.xlsx"
saveWorkbook(my_book, "Datos/renamed.xlsx")
# Build connection to renamed.xlsx: my_book
my_book <- loadWorkbook("Datos/renamed.xlsx")

# Remove the fourth sheet
removeSheet(my_book, 4)

# Save workbook to "clean.xlsx"
saveWorkbook(my_book, "Datos/clean.xlsx")

Obviamente, lo visto es muy sencillo hacerlo directamente desde Excel. La gran ventaja de R en este caso es la reproducibilidad y la programación automática de todas estas tareas.

5.4 Importar bases de datos relacionales SQL

Muchas empresas almacenan lo datos en bases de datos relacionales, existiendo varios métodos de poder incorporarlos a R.

Una base de datos relacional está compuesta por un conjunto de tablas que contienen algunas columnas que permiten conectar todas esas tablas entre sí. De este modo se almacena la información solo una vez y se ahorra mucho espacio al tenerlas conectadas.

Cómo están almacenadas estas tablas depende del DBMS (Database Management System). Implementaciones DBMS Open Source, como MySQL, PostgreSQL o SQLite son muy populares. Aunque también las hay propietarias, como Oracle Database o Microsoft SQL Server. Aunque prácticamente todas ellas utilizan SQL (Structure Query Language) como lenguaje para mantener y estructurar las bases de datos.

Dependiendo del tipo de base de datos, tendremos varios paquetes en R:

  • MySQL - RMySQL
  • PostgresSQL - RPostgreSQL
  • Oracle Database - ROracle
  • Y así sucesivamente.

Sin embargo, las funciones para poder manipular esas bases de datos relacionales se encuentran en un paquete con las convenciones llamado DBI.

Técnicamente hablando DBI es la interfaz de conexión y RMySQL, por ejemplo, es la implementación. De hecho, cada vez que instalamos uno de los paquetes arriba mencionados, te instala automáticamente DBI.

5.4.1 Conexión con bases de datos SQL remotas

La conexión con bases de datos SQL remotas en R se hace a tavés de la función dbConnect(). Estos son los argumentos principales que se han de incluir:

  • DBIdriver

Si están en un servidor remoto, tendremos que especificar los siguientes argumentos:

  • dbname
  • host
  • port
  • user
  • password

5.4.2 Establecer la conexión

Lo primero que tenemos que hacer es acceder una base de datos SQL. Para ello cargamos el pagquete DBI y cargamos la base de datos MySQL. Nuestro DBIdriver para bases de datos MySQL es RMySQL::MySQL().

5.4.3 Listar, importar y desconectar

Existen 3 funciones importantes:

  • dbListTables(): nos genera un vector con el nombre de las tablas contenidas en nuestro archivo MySQL.
  • dbReadTable(): nos importa una tabla a nuestra sesión de R.
  • dbDisconnect(): nos desconectamos de nuestra base de datos.

5.4.4 Consultas en SQL desde R: dbGetQuery()

. En situaciones donde nuestra base de datos SQL contenga millones de filas, nos es interesante hacer una selección previa de los datos que estamos interesados en analizar. Esto lo hacemos con la función dbGetQuery(). Vamos a ver dos aproximaciones a la hora de poder consultar una base de datos SQL, una usando lo conocido hasta ahora y otra explicando la función mencionada.

Conceptualmente, las dos aproximaciones vistas son muy diferentes aunque el resultado final sea el mismo. Por un lado, en la primera se carga toda la base de datos en R y luego se selecciona lo que queremos, mientras que en la segunda aproximación sólo cargamos en R los datos que queremos. Es decir, la selección la hace en la base de datos SQL y el resultado de esa selección es lo que se importa in R. Esto hace que la segunda aproximación sea muchísimo más eficiente y rápida que la primera, principalmente cuando estamos trabajando con una cantidad ingente de datos.

Además, la forma de hacer la selección en la segunda aproximación es completamente diferente a la primera, ya que utiliza una sintaxis nueva, donde el nombre de los argumentos van en mayúscula y no hay separaciones por comas. Se hace de una forma más natural. La equivalencia sería data = FROM, select = SELECT y subset = WHERE.

Veamos un segundo ejemplo.

5.4.4.1 Usando INNER JOIN para juntar varias tablas

Of course, SQL does not stop with the the three keywords SELECT, FROM and WHERE. Another very often used keyword is JOIN, and more specifically INNER JOIN. Take this call for example:

Here, the users table is joined with the tweats table. This is possible because the id column in the users table corresponds to the user_id column in the tweats table. Also notice how name, from the users table, and post and date, from the tweats table, can be referenced to without problems.

Can you predict the outcome of the following query?

5.4.5 Dentro de dbGetQuery()

Cuando ejecutamos dbGetQuery(), se ejecutan en segundo plano 3 funciones:

  • dbSendQuery(): es la responsable de enviar la consulta a la base de datos SQL.
  • dbFetch(): es la responsable de hacer la búsqueda directamente en SQL.
  • dbClearResult(): limpia los resultados.

Por lo tanto, en vez de usar dbGetQuery(), podemos ejecutar las 3 funciones vistas. Esto a priori parece poco aconsejable. Sin embargo, si los resultados de nuestra consulta están compuestos por miles de observaciones, podemos seleccionar trabajar poco a poco con ellas modificando dichas funciones dentro de dbFetch(), con el argumento n.

5.4.6 dbDisconnect() para cerrar la conexión con SQL

Siempre que nos conectamos a una base de datos usando dbConnect(), estamos creando una nueva conexión a esa base de datos. En esto caso, RMySQL automáticamente especifica un número máximo de conexiones abiertas y cierra algunas de ellas por tí, pero siempre es un buen detalle desconectar manualmente la conexión una vez utilizada. Para eso usamos dbDisconnect().

5.5 Importar bases de datos de la web

Hasta ahora hemos visto cómo trabajar con bases de datos relacionales SQL. Sin embargo, vamos a trabajar ahora con bases de datos que se encuentran en la web.

5.5.1 Importar archivos de texto plano de la web (HTTP y HTTPS)

Supongamos que tenemos un archivo .csv. Nuestra inercia sería descargarnos el archivo de internet y luego usar read.csv() del paquete utils para cargarlo. Sin embargo, este paquete también permite leer archivos que estén en la web. Siempre hay que especificiar en la dirección del archivo la ruta de acceso con http o https.

read.csv("http://s3.amazonaws.com/assets.datacamp.com/production/course_1478/datasets/swimming_pools.csv")
##                                         Name
## 1                Acacia Ridge Leisure Centre
## 2                            Bellbowrie Pool
## 3                                Carole Park
## 4                Centenary Pool (inner City)
## 5                             Chermside Pool
## 6                Colmslie Pool (Morningside)
## 7             Spring Hill Baths (inner City)
## 8                 Dunlop Park Pool (Corinda)
## 9                      Fortitude Valley Pool
## 10 Hibiscus Sports Complex (upper MtGravatt)
## 11                 Ithaca Pool ( Paddington)
## 12                             Jindalee Pool
## 13                                Manly Pool
## 14            Mt Gravatt East Aquatic Centre
## 15       Musgrave Park Pool (South Brisbane)
## 16                            Newmarket Pool
## 17                              Runcorn Pool
## 18                             Sandgate Pool
## 19      Langlands Parks Pool (Stones Corner)
## 20                         Yeronga Park Pool
##                                        Address  Latitude Longitude
## 1           1391 Beaudesert Road, Acacia Ridge -27.58616  153.0264
## 2                 Sugarwood Street, Bellbowrie -27.56547  152.8911
## 3   Cnr Boundary Road and Waterford Road Wacol -27.60744  152.9315
## 4             400 Gregory Terrace, Spring Hill -27.45537  153.0251
## 5                 375 Hamilton Road, Chermside -27.38583  153.0351
## 6                 400 Lytton Road, Morningside -27.45516  153.0789
## 7             14 Torrington Street, Springhill -27.45960  153.0215
## 8                      794 Oxley Road, Corinda -27.54652  152.9806
## 9         432 Wickham Street, Fortitude Valley -27.45390  153.0368
## 10         90 Klumpp Road, Upper Mount Gravatt -27.55183  153.0735
## 11               131 Caxton Street, Paddington -27.46226  153.0103
## 12                 11 Yallambee Road, Jindalee -27.53236  152.9427
## 13                  1 Fairlead Crescent, Manly -27.45228  153.1874
## 14 Cnr wecker Road and Newnham Road, Mansfield -27.53214  153.0943
## 15       100 Edmonstone Street, South Brisbane -27.47978  153.0168
## 16                71 Alderson Stret, Newmarket -27.42968  153.0062
## 17                   37 Bonemill Road, Runcorn -27.59156  153.0764
## 18               231 Flinders Parade, Sandgate -27.31196  153.0691
## 19             5 Panitya Street, Stones Corner -27.49769  153.0487
## 20                     81 School Road, Yeronga -27.52053  153.0185

Si usamos el paquete de Hadley Wickham readr, sería del siguiente modo:

# Load the readr package
 library(readr)

# Import the csv file: pools
url_csv <- "http://s3.amazonaws.com/assets.datacamp.com/production/course_1478/datasets/swimming_pools.csv"
pools <- read_csv(url_csv)
## Parsed with column specification:
## cols(
##   Name = col_character(),
##   Address = col_character(),
##   Latitude = col_double(),
##   Longitude = col_double()
## )
# Import the txt file: potatoes
url_delim <- "http://s3.amazonaws.com/assets.datacamp.com/production/course_1478/datasets/potatoes.txt"
potatoes <- read_tsv(url_delim)
## Parsed with column specification:
## cols(
##   area = col_integer(),
##   temp = col_integer(),
##   size = col_integer(),
##   storage = col_integer(),
##   method = col_integer(),
##   texture = col_double(),
##   flavor = col_double(),
##   moistness = col_double()
## )
# Print pools and potatoes
print(pools)
## # A tibble: 20 x 4
##    Name                      Address                     Latitude Longitude
##    <chr>                     <chr>                          <dbl>     <dbl>
##  1 Acacia Ridge Leisure Cen… 1391 Beaudesert Road, Acac…    -27.6      153.
##  2 Bellbowrie Pool           Sugarwood Street, Bellbowr…    -27.6      153.
##  3 Carole Park               Cnr Boundary Road and Wate…    -27.6      153.
##  4 Centenary Pool (inner Ci… 400 Gregory Terrace, Sprin…    -27.5      153.
##  5 Chermside Pool            375 Hamilton Road, Chermsi…    -27.4      153.
##  6 Colmslie Pool (Morningsi… 400 Lytton Road, Morningsi…    -27.5      153.
##  7 Spring Hill Baths (inner… 14 Torrington Street, Spri…    -27.5      153.
##  8 Dunlop Park Pool (Corind… 794 Oxley Road, Corinda        -27.5      153.
##  9 Fortitude Valley Pool     432 Wickham Street, Fortit…    -27.5      153.
## 10 Hibiscus Sports Complex … 90 Klumpp Road, Upper Moun…    -27.6      153.
## 11 Ithaca Pool ( Paddington) 131 Caxton Street, Padding…    -27.5      153.
## 12 Jindalee Pool             11 Yallambee Road, Jindalee    -27.5      153.
## 13 Manly Pool                1 Fairlead Crescent, Manly     -27.5      153.
## 14 Mt Gravatt East Aquatic … Cnr wecker Road and Newnha…    -27.5      153.
## 15 Musgrave Park Pool (Sout… 100 Edmonstone Street, Sou…    -27.5      153.
## 16 Newmarket Pool            71 Alderson Stret, Newmark…    -27.4      153.
## 17 Runcorn Pool              37 Bonemill Road, Runcorn      -27.6      153.
## 18 Sandgate Pool             231 Flinders Parade, Sandg…    -27.3      153.
## 19 Langlands Parks Pool (St… 5 Panitya Street, Stones C…    -27.5      153.
## 20 Yeronga Park Pool         81 School Road, Yeronga        -27.5      153.
print(potatoes)
## # A tibble: 160 x 8
##     area  temp  size storage method texture flavor moistness
##    <int> <int> <int>   <int>  <int>   <dbl>  <dbl>     <dbl>
##  1     1     1     1       1      1     2.9    3.2       3  
##  2     1     1     1       1      2     2.3    2.5       2.6
##  3     1     1     1       1      3     2.5    2.8       2.8
##  4     1     1     1       1      4     2.1    2.9       2.4
##  5     1     1     1       1      5     1.9    2.8       2.2
##  6     1     1     1       2      1     1.8    3         1.7
##  7     1     1     1       2      2     2.6    3.1       2.4
##  8     1     1     1       2      3     3      3         2.9
##  9     1     1     1       2      4     2.2    3.2       2.5
## 10     1     1     1       2      5     2      2.8       1.9
## # … with 150 more rows
# https URL to the swimming_pools csv file.
url_csv <- "https://s3.amazonaws.com/assets.datacamp.com/production/course_1478/datasets/swimming_pools.csv"

# Import the file using read.csv(): pools1
pools1 <- read.csv(url_csv)

# Load the readr package
library(readr)

# Import the file using read_csv(): pools2
pools2 <- read_csv(url_csv)
## Parsed with column specification:
## cols(
##   Name = col_character(),
##   Address = col_character(),
##   Latitude = col_double(),
##   Longitude = col_double()
## )
# Print the structure of pools1 and pools2
str(pools1)
## 'data.frame':    20 obs. of  4 variables:
##  $ Name     : Factor w/ 20 levels "Acacia Ridge Leisure Centre",..: 1 2 3 4 5 6 19 7 8 9 ...
##  $ Address  : Factor w/ 20 levels "1 Fairlead Crescent, Manly",..: 5 20 18 10 9 11 6 15 12 17 ...
##  $ Latitude : num  -27.6 -27.6 -27.6 -27.5 -27.4 ...
##  $ Longitude: num  153 153 153 153 153 ...
str(pools2)
## Classes 'tbl_df', 'tbl' and 'data.frame':    20 obs. of  4 variables:
##  $ Name     : chr  "Acacia Ridge Leisure Centre" "Bellbowrie Pool" "Carole Park" "Centenary Pool (inner City)" ...
##  $ Address  : chr  "1391 Beaudesert Road, Acacia Ridge" "Sugarwood Street, Bellbowrie" "Cnr Boundary Road and Waterford Road Wacol" "400 Gregory Terrace, Spring Hill" ...
##  $ Latitude : num  -27.6 -27.6 -27.6 -27.5 -27.4 ...
##  $ Longitude: num  153 153 153 153 153 ...
##  - attr(*, "spec")=List of 2
##   ..$ cols   :List of 4
##   .. ..$ Name     : list()
##   .. .. ..- attr(*, "class")= chr  "collector_character" "collector"
##   .. ..$ Address  : list()
##   .. .. ..- attr(*, "class")= chr  "collector_character" "collector"
##   .. ..$ Latitude : list()
##   .. .. ..- attr(*, "class")= chr  "collector_double" "collector"
##   .. ..$ Longitude: list()
##   .. .. ..- attr(*, "class")= chr  "collector_double" "collector"
##   ..$ default: list()
##   .. ..- attr(*, "class")= chr  "collector_guess" "collector"
##   ..- attr(*, "class")= chr "col_spec"

5.5.2 Importar archivos Excel de la web

A diferencia con un archivo .csv, la función del paquete readxl para cargar archivos Excel desde la web directamente poniendo su dirección fallan. Hay que hacer un paso intermedio que es descargar el archivo. Pero en vez de hacerlo manualmente, existe una función, download.file() que nos lo hace. Puede parecer que este código sobra cuando puedes hacerlo manualmente. Sin embargo, en aras de la reproducibilidad de nuestro trabajo, es un paso importante a hacer, ya que todos los pasos quedan registrados.

Sin embargo, poniendo la dirección web directamente en la función read.xls() del paquete gdata funciona sin ningún problema.

# Load the readxl and gdata package
library(gdata)
library(readxl)

# Specification of url: url_xls
url_xls <- "http://s3.amazonaws.com/assets.datacamp.com/production/course_1478/datasets/latitude.xls"

# Import the .xls file with gdata: excel_gdata
excel_gdata <- read.xls(url_xls)

# Download file behind URL, name it local_latitude.xls
local_latitude.xls <- download.file(url_xls, destfile = "local_latitude.xls")

# Import the local .xls file with readxl: excel_readxl
excel_readxl <- read_excel("local_latitude.xls")

5.5.2.1 download.file() y load()

Con download.file() podemos descargar cualquier archivo que esté en la web, no solo archivos Excel. Entre los archivos que pueden interesarnos se encuentrar los .RData, archivos contienen datos de R. Podremos cargar estos datos en R usando la función load(). Sin embargo, esta función no acepta direcciones web, por lo que primero hay que descargar el archivo y después cargarlo.

# https URL to the wine RData file.
url_rdata <- "https://s3.amazonaws.com/assets.datacamp.com/production/course_1478/datasets/wine.RData"

# Download the wine file to your working directory
wine_local <- download.file(url_rdata, destfile = "wine_local.RData")

# Load the wine data into your workspace using load()
load("wine_local.RData")

# Print out the summary of the wine data
summary(wine)
##     Alcohol        Malic acid        Ash        Alcalinity of ash
##  Min.   :11.03   Min.   :0.74   Min.   :1.360   Min.   :10.60    
##  1st Qu.:12.36   1st Qu.:1.60   1st Qu.:2.210   1st Qu.:17.20    
##  Median :13.05   Median :1.87   Median :2.360   Median :19.50    
##  Mean   :12.99   Mean   :2.34   Mean   :2.366   Mean   :19.52    
##  3rd Qu.:13.67   3rd Qu.:3.10   3rd Qu.:2.560   3rd Qu.:21.50    
##  Max.   :14.83   Max.   :5.80   Max.   :3.230   Max.   :30.00    
##    Magnesium      Total phenols     Flavanoids    Nonflavanoid phenols
##  Min.   : 70.00   Min.   :0.980   Min.   :0.340   Min.   :0.1300      
##  1st Qu.: 88.00   1st Qu.:1.740   1st Qu.:1.200   1st Qu.:0.2700      
##  Median : 98.00   Median :2.350   Median :2.130   Median :0.3400      
##  Mean   : 99.59   Mean   :2.292   Mean   :2.023   Mean   :0.3623      
##  3rd Qu.:107.00   3rd Qu.:2.800   3rd Qu.:2.860   3rd Qu.:0.4400      
##  Max.   :162.00   Max.   :3.880   Max.   :5.080   Max.   :0.6600      
##  Proanthocyanins Color intensity       Hue           Proline      
##  Min.   :0.410   Min.   : 1.280   Min.   :1.270   Min.   : 278.0  
##  1st Qu.:1.250   1st Qu.: 3.210   1st Qu.:1.930   1st Qu.: 500.0  
##  Median :1.550   Median : 4.680   Median :2.780   Median : 672.0  
##  Mean   :1.587   Mean   : 5.055   Mean   :2.604   Mean   : 745.1  
##  3rd Qu.:1.950   3rd Qu.: 6.200   3rd Qu.:3.170   3rd Qu.: 985.0  
##  Max.   :3.580   Max.   :13.000   Max.   :4.000   Max.   :1680.0

5.5.3 Paquete httr

Downloading a file from the Internet means sending a GET request and receiving the file you asked for. Internally, all the previously discussed functions use a GET request to download files.

httr provides a convenient function, GET() to execute this GET request. The result is a response object, that provides easy access to the status code, content-type and, of course, the actual content.

You can extract the content from the request using the content() function. At the time of writing, there are three ways to retrieve this content: as a raw object, as a character vector, or an R object, such as a list. If you don’t tell content() how to retrieve the content through the as argument, it’ll try its best to figure out which type is most appropriate based on the content-type.

# Load the httr package
library(httr)

# Get the url, save response to resp
url <- "http://www.example.com/"
resp <- GET(url)

# Print resp
print(resp)
## Response [http://www.example.com/]
##   Date: 2019-10-07 06:57
##   Status: 200
##   Content-Type: text/html; charset=UTF-8
##   Size: 1.27 kB
## <!doctype html>
## <html>
## <head>
##     <title>Example Domain</title>
## 
##     <meta charset="utf-8" />
##     <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
##     <meta name="viewport" content="width=device-width, initial-scale=1" />
##     <style type="text/css">
##     body {
## ...
# Get the raw content of resp: raw_content
raw_content <- content(resp, as = "raw")

# Print the head of raw_content
head(raw_content)
## [1] 3c 21 64 6f 63 74

Web content does not limit itself to HTML pages and files stored on remote servers such as DataCamp’s Amazon S3 instances. There are many other data formats out there. A very common one is JSON. This format is very often used by so-called Web APIs, interfaces to web servers with which you as a client can communicate to get or store information in more complicated ways.

You’ll learn about Web APIs and JSON in the video and exercises that follow, but some experimentation never hurts, does it?

# Get the url
url <- "http://www.omdbapi.com/?apikey=ff21610b&t=Annie+Hall&y=&plot=short&r=json"
resp <- GET(url)

# Print resp
print(resp)
## Response [http://www.omdbapi.com/?apikey=ff21610b&t=Annie+Hall&y=&plot=short&r=json]
##   Date: 2019-10-07 06:57
##   Status: 401
##   Content-Type: application/json; charset=utf-8
##   Size: 47 B
# Print content of resp as text. Use content() to get the content of resp. Set the as argument to "text". Simply print out the result. What do you see?
print(content(resp, as = "text"))
## [1] "{\"Response\":\"False\",\"Error\":\"Invalid API key!\"}"
# Print content of resp. Use content() to get the content of resp, but this time do not specify a second argument. R figures out automatically that you're dealing with a JSON, and converts the JSON to a named R list.
print(content(resp))
## $Response
## [1] "False"
## 
## $Error
## [1] "Invalid API key!"

5.5.4 APIs y JSON

JSON es un formato de datos que e es simple, conciso y bien estructurado, sobre todo para que sea comprensible por los humanos y fácilmente comprensible por los ordenadores. Y esto es muy útil para comunicarse con las API de las web.

Una API es Application Programming Interface, y consta de un conjunto de rutinas y protocolos para construir software. En nuestro caso nos interesa la Web API, una interfaz que nos permite añadir y obtener datos de un servidor utilizando HTTP verbs (GET and others).

Para poder añadir datos albergados en JSON a R, usamos el paquete jsonlite, escrito Jeroen Ooms. Este paquete, fruto de mejora de otros paquetes previos, nos permite descargar y cargar archivos JSON de internet en R, dándoles una estructura que sea comprensible en R, con la función fronJSON().

# Load the jsonlite package
library(jsonlite)

# wine_json is a JSON
wine_json <- '{"name":"Chateau Migraine", "year":1997, "alcohol_pct":12.4, "color":"red", "awarded":false}'

# Convert wine_json into a list: wine
wine <- fromJSON(wine_json)

# Print structure of wine
str(wine)
## List of 5
##  $ name       : chr "Chateau Migraine"
##  $ year       : int 1997
##  $ alcohol_pct: num 12.4
##  $ color      : chr "red"
##  $ awarded    : logi FALSE
# Definition of quandl_url
quandl_url <- "https://www.quandl.com/api/v3/datasets/WIKI/FB/data.json?auth_token=i83asDsiWUUyfoypkgMz"

# Import Quandl data: quandl_data
quandl_data <- fromJSON(quandl_url)

# Print structure of quandl_data
str(quandl_data)
## List of 1
##  $ dataset_data:List of 10
##   ..$ limit       : NULL
##   ..$ transform   : NULL
##   ..$ column_index: NULL
##   ..$ column_names: chr [1:13] "Date" "Open" "High" "Low" ...
##   ..$ start_date  : chr "2012-05-18"
##   ..$ end_date    : chr "2018-03-27"
##   ..$ frequency   : chr "daily"
##   ..$ data        : chr [1:1472, 1:13] "2018-03-27" "2018-03-26" "2018-03-23" "2018-03-22" ...
##   ..$ collapse    : NULL
##   ..$ order       : NULL

5.5.4.1 JSON & jsonlite

Un objeto JSON tiene esta estructura, en la que aparece el nombre de la variable entre comillas, dos puntos, y el valor que se le asigna, separando campos con comas. Los valores que pueden adquirir son string, numérico, booleano, null, un objeto JSON o un JSON array.

{"id": 1, "name": "Frank", "age": 23, "married": false}

x <- '{"id": 1, "name": "Frank", "age": 23, "married": false}'
r <- fromJSON(x)
str(r)
## List of 4
##  $ id     : int 1
##  $ name   : chr "Frank"
##  $ age    : int 23
##  $ married: logi FALSE

Los JSON arrays tienen la siguiente estructura:

[6, 3, 7, 2, 5, 4, 9]

# JSON array en R nos devuelve un vector
fromJSON('[6, 3, 7, 2, 5, 4, 9]')
## [1] 6 3 7 2 5 4 9
# También puede contener el JSON array elementos de diferente naturaleza
fromJSON('[6, "hola", null, true, 76, "adiós"]')
## [1] "6"     "hola"  NA      "TRUE"  "76"    "adiós"

Sin embargo, y como se mencionó al principio, los JSON arrays pueden contener otros objetos JSON en su interior, haciendo JSON encadenados. Veamos un ejemplo:

{"id": 1, "name": "Frank", "age": 23, "married": false, "partner": {"id": 4, "name": Julie}}

r <- fromJSON('{"id": 1, "name": "Frank", "age": 23, "married": false, "partner": {"id": 4, "name": "Julie"}}')

str(r)
## List of 5
##  $ id     : int 1
##  $ name   : chr "Frank"
##  $ age    : int 23
##  $ married: logi FALSE
##  $ partner:List of 2
##   ..$ id  : int 4
##   ..$ name: chr "Julie"

Vamos a construir ahora un JSON array compuesto por objetos JSON

[{"id": 1, "name": "Roberto"}, {"id": 3, "name": "Francisco"}, {"id": 6, "name": "María"}]

# Al pasar el JSON array a R, en este caso nos devuelve un dataframe
fromJSON('[{"id": 1, "name": "Roberto"}, {"id": 3, "name": "Francisco"}, {"id": 6, "name": "María"}]')
##   id      name
## 1  1   Roberto
## 2  3 Francisco
## 3  6     María
fromJSON('[{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6}]')
##   a b
## 1 1 2
## 2 3 4
## 3 5 6
# Esto nos devuelve una lista
fromJSON('{"a": [1, 2, 3], "b": [4, 5, 6]}')
## $a
## [1] 1 2 3
## 
## $b
## [1] 4 5 6
# Esto nos devuelve una matriz
fromJSON('[[1, 2], [3, 4]]')
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4

Existen otras funciones importantes dentro de jsonlite:

  • toJSON(): convierte objetos de R a formato JSON.
  • prettify(): Cambia la forma de mostrar objetos JSON. En este caso, cada valor aparece en una línea y hace que podamos leerlo muy fácilmente los humanos.
  • minify(): Cambia la forma de mostrar objetos JSON. Compacta todo lo posible el código, haciéndolo muy rápido para ordenadores, pero muy difícil de leer para los humanos.
# Convertimos un objeto de R en JSON
# URL pointing to the .csv file
url_csv <- "http://s3.amazonaws.com/assets.datacamp.com/production/course_1478/datasets/water.csv"

# Import the .csv file located at url_csv
water <- read.csv(url_csv, stringsAsFactors = FALSE)

# Convert the data file according to the requirements
water_json <- toJSON(water)

# Print out water_json
print(water_json)
## [{"water":"Algeria","X1992":0.064,"X2002":0.017},{"water":"American Samoa"},{"water":"Angola","X1992":0.0001,"X2002":0.0001},{"water":"Antigua and Barbuda","X1992":0.0033},{"water":"Argentina","X1992":0.0007,"X1997":0.0007,"X2002":0.0007},{"water":"Australia","X1992":0.0298,"X2002":0.0298},{"water":"Austria","X1992":0.0022,"X2002":0.0022},{"water":"Bahamas","X1992":0.0013,"X2002":0.0074},{"water":"Bahrain","X1992":0.0441,"X2002":0.0441,"X2007":0.1024},{"water":"Barbados","X2007":0.0146},{"water":"British Virgin Islands","X2007":0.0042},{"water":"Canada","X1992":0.0027,"X2002":0.0027},{"water":"Cape Verde","X1992":0.002,"X1997":0.0017},{"water":"Cayman Islands","X1992":0.0033},{"water":"Central African Rep."},{"water":"Chile","X1992":0.0048,"X2002":0.0048},{"water":"Colombia","X1992":0.0027,"X2002":0.0027},{"water":"Cuba","X1992":0.0069,"X1997":0.0069,"X2002":0.0069},{"water":"Cyprus","X1992":0.003,"X1997":0.003,"X2002":0.0335},{"water":"Czech Rep.","X1992":0.0002,"X2002":0.0002},{"water":"Denmark","X1992":0.015,"X2002":0.015},{"water":"Djibouti","X1992":0.0001,"X2002":0.0001},{"water":"Ecuador","X1992":0.0022,"X1997":0.0022,"X2002":0.0022},{"water":"Egypt","X1992":0.025,"X1997":0.025,"X2002":0.1},{"water":"El Salvador","X1992":0.0001,"X2002":0.0001},{"water":"Finland","X1992":0.0001,"X2002":0.0001},{"water":"France","X1992":0.0117,"X2002":0.0117},{"water":"Gibraltar","X1992":0.0077},{"water":"Greece","X1992":0.01,"X2002":0.01},{"water":"Honduras","X1992":0.0002,"X2002":0.0002},{"water":"Hungary","X1992":0.0002,"X2002":0.0002},{"water":"India","X1997":0.0005,"X2002":0.0005},{"water":"Indonesia","X1992":0.0187,"X2002":0.0187},{"water":"Iran","X1992":0.003,"X1997":0.003,"X2002":0.003,"X2007":0.2},{"water":"Iraq","X1997":0.0074,"X2002":0.0074},{"water":"Ireland","X1992":0.0002,"X2002":0.0002},{"water":"Israel","X1992":0.0256,"X2002":0.0256,"X2007":0.14},{"water":"Italy","X1992":0.0973,"X2002":0.0973},{"water":"Jamaica","X1992":0.0005,"X1997":0.0005,"X2002":0.0005},{"water":"Japan","X1997":0.04,"X2002":0.04},{"water":"Jordan","X1997":0.002,"X2007":0.0098},{"water":"Kazakhstan","X1997":1.328,"X2002":1.328},{"water":"Kuwait","X1992":0.507,"X1997":0.231,"X2002":0.4202},{"water":"Lebanon","X2007":0.0473},{"water":"Libya","X2002":0.018},{"water":"Malaysia","X1992":0.0043,"X2002":0.0043},{"water":"Maldives","X1992":0.0004},{"water":"Malta","X1992":0.024,"X1997":0.031,"X2002":0.031},{"water":"Marshall Islands","X1992":0.0007},{"water":"Mauritania","X1992":0.002,"X2002":0.002},{"water":"Mexico","X1992":0.0307,"X2002":0.0307},{"water":"Morocco","X1992":0.0034,"X1997":0.0034,"X2002":0.007},{"water":"Namibia","X1992":0.0003,"X2002":0.0003},{"water":"Netherlands Antilles","X1992":0.063},{"water":"Nicaragua","X1992":0.0002,"X2002":0.0002},{"water":"Nigeria","X1992":0.003,"X2002":0.003},{"water":"Norway","X1992":0.0001,"X2002":0.0001},{"water":"Oman","X1997":0.034,"X2002":0.034,"X2007":0.109},{"water":"Peru","X1992":0.0054,"X2002":0.0054},{"water":"Poland","X1992":0.007,"X2002":0.007},{"water":"Portugal","X1992":0.0016,"X2002":0.0016},{"water":"Qatar","X1992":0.065,"X1997":0.099,"X2002":0.099,"X2007":0.18},{"water":"Saudi Arabia","X1992":0.683,"X1997":0.727,"X2002":0.863,"X2007":1.033},{"water":"Senegal","X1992":0,"X2002":0},{"water":"Somalia","X1992":0.0001,"X2002":0.0001},{"water":"South Africa","X1992":0.018,"X2002":0.018},{"water":"Spain","X1992":0.1002,"X2002":0.1002},{"water":"Sudan","X1992":0.0004,"X1997":0.0004,"X2002":0.0004},{"water":"Sweden","X1992":0.0002,"X2002":0.0002},{"water":"Trinidad and Tobago","X2007":0.036},{"water":"Tunisia","X1992":0.008,"X2002":0.013},{"water":"Turkey","X1992":0.0005,"X2002":0.0005,"X2007":0.0005},{"water":"United Arab Emirates","X1992":0.163,"X1997":0.385,"X2007":0.95},{"water":"United Kingdom","X1992":0.0333,"X2002":0.0333},{"water":"United States","X1992":0.58,"X2002":0.58},{"water":"Venezuela","X1992":0.0052,"X2002":0.0052},{"water":"Yemen, Rep.","X1992":0.01,"X2002":0.01}]

prettify() puede aplicarse de dos formas: directamente con la función a un objeto JSON que tengamos en R, o bien si queremos convertir un objeto R a JSON, existe un argumento en toJSON() que nos permite ya indicarlo: pretty.

# Usamos prettify y minify
# Convertimos las tres primeras líneas de mtcars a JSON usando el atributo pretty
pretty_json <- toJSON(mtcars[1:3,], pretty = TRUE)
print(pretty_json)
## [
##   {
##     "mpg": 21,
##     "cyl": 6,
##     "disp": 160,
##     "hp": 110,
##     "drat": 3.9,
##     "wt": 2.62,
##     "qsec": 16.46,
##     "vs": 0,
##     "am": 1,
##     "gear": 4,
##     "carb": 4,
##     "_row": "Mazda RX4"
##   },
##   {
##     "mpg": 21,
##     "cyl": 6,
##     "disp": 160,
##     "hp": 110,
##     "drat": 3.9,
##     "wt": 2.875,
##     "qsec": 17.02,
##     "vs": 0,
##     "am": 1,
##     "gear": 4,
##     "carb": 4,
##     "_row": "Mazda RX4 Wag"
##   },
##   {
##     "mpg": 22.8,
##     "cyl": 4,
##     "disp": 108,
##     "hp": 93,
##     "drat": 3.85,
##     "wt": 2.32,
##     "qsec": 18.61,
##     "vs": 1,
##     "am": 1,
##     "gear": 4,
##     "carb": 1,
##     "_row": "Datsun 710"
##   }
## ]
# Convertimos pretty_json a minify
mini_json <- minify(pretty_json)
print(mini_json)
## [{"mpg":21,"cyl":6,"disp":160,"hp":110,"drat":3.9,"wt":2.62,"qsec":16.46,"vs":0,"am":1,"gear":4,"carb":4,"_row":"Mazda RX4"},{"mpg":21,"cyl":6,"disp":160,"hp":110,"drat":3.9,"wt":2.875,"qsec":17.02,"vs":0,"am":1,"gear":4,"carb":4,"_row":"Mazda RX4 Wag"},{"mpg":22.8,"cyl":4,"disp":108,"hp":93,"drat":3.85,"wt":2.32,"qsec":18.61,"vs":1,"am":1,"gear":4,"carb":1,"_row":"Datsun 710"}]
# Y hacemos el paso contrario, convertimos mini_json a prettify
pretty2_json <- prettify(mini_json)
print(pretty2_json)
## [
##     {
##         "mpg": 21,
##         "cyl": 6,
##         "disp": 160,
##         "hp": 110,
##         "drat": 3.9,
##         "wt": 2.62,
##         "qsec": 16.46,
##         "vs": 0,
##         "am": 1,
##         "gear": 4,
##         "carb": 4,
##         "_row": "Mazda RX4"
##     },
##     {
##         "mpg": 21,
##         "cyl": 6,
##         "disp": 160,
##         "hp": 110,
##         "drat": 3.9,
##         "wt": 2.875,
##         "qsec": 17.02,
##         "vs": 0,
##         "am": 1,
##         "gear": 4,
##         "carb": 4,
##         "_row": "Mazda RX4 Wag"
##     },
##     {
##         "mpg": 22.8,
##         "cyl": 4,
##         "disp": 108,
##         "hp": 93,
##         "drat": 3.85,
##         "wt": 2.32,
##         "qsec": 18.61,
##         "vs": 1,
##         "am": 1,
##         "gear": 4,
##         "carb": 1,
##         "_row": "Datsun 710"
##     }
## ]
## 

5.6 Importar bases de datos de otros software estadísticos

Existen otros software para análisis de datos que también son relativamente comunes, aunque privativos: SAS (Statistical Analysis Software), STATA (STatistics and daTA) y SPSS (Statistical Package for Social Sciences). Cada uno tiene un ámbito de más implantación, así como sus propios formatos. Por ejemplo, SAS tiene como formatos .sas7bdat y .sas7bcat, STATA por su parte son archivos .dta y en SPSS son .savy .por.

R puede trabajar absolutamente con todos ellos, así como importar esos formatos en su interior. Para ello, existen dos paquetes principales de R:

  • haven. Desarrollado por Hadley Wickham, cuyo fin es ser consistente, fácil y rápido.
  • foreign. Desarrollado por el núcleo de R, y puede trabajar con muchos tipos de datos.

5.6.1 Paquete haven

El paquete haven permite importar archivos SAS, STATA y SPSS, ya que usa una librería de C desarrollada por Evan Millers y llamada ReadStat. Es muy fácil de usar, ya que en principio funciona simplemente cpm im argumento indicando la ruta de acceso al archivo. El resultado de la importación es un data frame de R.

5.6.1.1 Importar datos de SAS

Los datos se importan con la función read_sas(), indicando la ruta de acceso del archivo.

Vamos a trabajar con datos del área de enseñanza de SAS online, concretamente con unos datos con la edad, género, ganancias y nivel de compras de 36 individuos.

# Cargamos el paquete haven
library(haven)

# Importamos la base de datos sales.sas7bdat: sales
sales <- read_sas("http://s3.amazonaws.com/assets.datacamp.com/production/course_1478/datasets/sales.sas7bdat")

# Vemos la estructura de sales
str(sales)
## Classes 'tbl_df', 'tbl' and 'data.frame':    431 obs. of  4 variables:
##  $ purchase: num  0 0 1 1 0 0 0 0 0 0 ...
##  $ age     : num  41 47 41 39 32 32 33 45 43 40 ...
##  $ gender  : chr  "Female" "Female" "Female" "Female" ...
##  $ income  : chr  "Low" "Low" "Low" "Low" ...
##  - attr(*, "label")= chr "SALES"

5.6.1.2 Importar datos de STATA

Los datos se importan con dos funciones que funcionan igual: read_stata(), y read_dta(), indicando la ruta de acceso el archivo. En este caso, estas funciones pueden importar archivos con formato STATA 13 y STATA 14.

Es común en STATA de generar columnas categóricas con números. Al importarlas a R, se importan como labelled, y contienen tanto el número de la categoría como el valor de la misma. Un paso recomendable sería convertir esa columna con números categóricos en las categorías como tal. Para eso podemos usar as_factor() (presente en haven) y as.character().

# Vamos a trabajar con datos de las importaciones y exportaciones anuales de azúcar, en dólares y peso.
sugar <- read_dta("http://assets.datacamp.com/production/course_1478/datasets/trade.dta")
str(sugar)
## Classes 'tbl_df', 'tbl' and 'data.frame':    10 obs. of  5 variables:
##  $ Date    :Class 'labelled'  atomic [1:10] 10 9 8 7 6 5 4 3 2 1
##   .. ..- attr(*, "label")= chr "Date"
##   .. ..- attr(*, "format.stata")= chr "%9.0g"
##   .. ..- attr(*, "labels")= Named num [1:10] 1 2 3 4 5 6 7 8 9 10
##   .. .. ..- attr(*, "names")= chr [1:10] "2004-12-31" "2005-12-31" "2006-12-31" "2007-12-31" ...
##  $ Import  : atomic  37664782 16316512 11082246 35677943 9879878 ...
##   ..- attr(*, "label")= chr "Import"
##   ..- attr(*, "format.stata")= chr "%9.0g"
##  $ Weight_I: atomic  54029106 21584365 14526089 55034932 14806865 ...
##   ..- attr(*, "label")= chr "Weight_I"
##   ..- attr(*, "format.stata")= chr "%9.0g"
##  $ Export  : atomic  5.45e+07 1.03e+08 3.79e+07 4.85e+07 7.15e+07 ...
##   ..- attr(*, "label")= chr "Export"
##   ..- attr(*, "format.stata")= chr "%9.0g"
##  $ Weight_E: atomic  9.34e+07 1.58e+08 8.80e+07 1.12e+08 1.32e+08 ...
##   ..- attr(*, "label")= chr "Weight_E"
##   ..- attr(*, "format.stata")= chr "%9.0g"
##  - attr(*, "label")= chr "Written by R."
# Convertimos la variable Date en fecha y factorial
sugar$Date <- as.Date(as_factor(sugar$Date))
str(sugar)
## Classes 'tbl_df', 'tbl' and 'data.frame':    10 obs. of  5 variables:
##  $ Date    : Date, format: "2013-12-31" "2012-12-31" ...
##  $ Import  : atomic  37664782 16316512 11082246 35677943 9879878 ...
##   ..- attr(*, "label")= chr "Import"
##   ..- attr(*, "format.stata")= chr "%9.0g"
##  $ Weight_I: atomic  54029106 21584365 14526089 55034932 14806865 ...
##   ..- attr(*, "label")= chr "Weight_I"
##   ..- attr(*, "format.stata")= chr "%9.0g"
##  $ Export  : atomic  5.45e+07 1.03e+08 3.79e+07 4.85e+07 7.15e+07 ...
##   ..- attr(*, "label")= chr "Export"
##   ..- attr(*, "format.stata")= chr "%9.0g"
##  $ Weight_E: atomic  9.34e+07 1.58e+08 8.80e+07 1.12e+08 1.32e+08 ...
##   ..- attr(*, "label")= chr "Weight_E"
##   ..- attr(*, "format.stata")= chr "%9.0g"
##  - attr(*, "label")= chr "Written by R."

5.6.1.3 Importar datos de SPSS

Los datos se importan con la función read_spss(), indicando la ruta de acceso del archivo. Dependiendo del formato, la función read_spss() ejecutará las funciones read_por() y read_sav() para archivos .por y .sav respectivamente.

# Los datos están relacionados con 4 Big Five personalidades de 434 personas, de la Universidad de Boston (http://staff.bath.ac.uk/pssiw/stats2/page16/page16.html).

traits <- read_spss("Datos/person.sav")
summary(traits)
##     Neurotic      Extroversion   Agreeableness   Conscientiousness
##  Min.   : 0.00   Min.   : 5.00   Min.   :15.00   Min.   : 7.00    
##  1st Qu.:18.00   1st Qu.:26.00   1st Qu.:39.00   1st Qu.:25.00    
##  Median :24.00   Median :31.00   Median :45.00   Median :30.00    
##  Mean   :23.63   Mean   :30.23   Mean   :44.55   Mean   :30.85    
##  3rd Qu.:29.00   3rd Qu.:34.00   3rd Qu.:50.00   3rd Qu.:36.00    
##  Max.   :44.00   Max.   :65.00   Max.   :73.00   Max.   :58.00    
##  NA's   :14      NA's   :16      NA's   :19      NA's   :14
# Muestra un subconjunto con valores mayores de 40 de Extroversion Y Agreeableness
subset(traits, Extroversion > 40 & Agreeableness > 40)
## # A tibble: 8 x 4
##   Neurotic Extroversion Agreeableness Conscientiousness
##      <dbl>        <dbl>         <dbl>             <dbl>
## 1       38           43            49                29
## 2       20           42            46                31
## 3       18           42            49                31
## 4       42           43            44                29
## 5       30           42            51                24
## 6       18           42            50                25
## 7       27           45            55                23
## 8       18           43            57                34

5.6.1.4 Factorizar datos

Como se ha mencionado, es común en STATA, SPSS y otros de generar columnas categóricas con números. Al importarlas a R, se importan como labelled, y contienen tanto el número de la categoría como el valor de la misma. Un paso recomendable sería convertir esa columna con números categóricos en las categorías como tal. Para eso podemos usar as_factor() y as.character().

# Los datos del ejemplo incluyen a empleados y atributos demográficos y económicos de QRiE.
work <- read_spss("http://s3.amazonaws.com/assets.datacamp.com/production/course_1478/datasets/employee.sav")
summary(work$GENDER)
##    Length     Class      Mode 
##       474  labelled character
# Convertimos work$GENDER a factorial
work$GENDER <- as_factor(work$GENDER)
summary(work$GENDER)
## Female   Male 
##    216    258

5.6.2 Paquete foreign

Está escrito por el núcleo de R. Es algo menos consistente pero muy comprensible. Puede importar todos los tipos de datos, no solo de SAS, STATA y SPSS, sino también de archivos más exóticos como Systat, Weka, etc. Además, permite también exportar nuestros datos de R a esos formatos.

Cuando decimos que es menos consistente nos referimos a que, por ejemplo, el hecho de gestionar las variables factoriales en las distintas funciones de importación de datos tienen nombres diferentes aunque su resultado sea el mismo.

5.6.2.1 Importar archivos SAS

El paquete foreign no puede importar datos con formato .sas7bdat, sino solo las librerías SAS con formato .xport. Para importar el primer formato hay un paquete expreso llamado sas7bdat.

5.6.2.2 Importar archivos STATA

El paquete foreign puede importar formatoS de STATA de 5 a 12, usando la función read.dta(). El formato es el siguiente:

read.dta(file, convert.factors = TRUE, convert.dates = TRUE, missing.type = FALSE)

  • convert.factors. Convierte columnas labelled a valores factoriales de R.
  • convert.date. Convierte fechas y horas a obtos de fecha y POSIXct.
  • missing.type. Convierte todos los tipos de valores que faltan a NA si es FALSE, y si es TRUE almacena how values are missing in attributes.
# Cargamos foreign
library(foreign)

# Vamos a usar datos de las elecciones de EEUU en el año 2000, con el número de votos de cada candidato
florida <- read.dta("Datos/florida.dta")

# Vemos las primeras filas
head(florida)
##     gore   bush buchanan nader  total
## 1  47300  34062      262  3215  84839
## 2   2392   5610       73    53   8128
## 3  18850  38637      248   828  58563
## 4   3072   5413       65    84   8634
## 5  97318 115185      570  4470 217543
## 6 386518 177279      789  7099 571685
# Los datos contienen medidas socioeconómicas y acceso a la educación de diferentes individuos.
# Specify the file path using file.path(): path
path <- file.path("Datos/edequality.dta")

# Create and print structure of edu_equal_1
edu_equal_1 <- read.dta(path)
str(edu_equal_1)
## 'data.frame':    12214 obs. of  27 variables:
##  $ hhid              : num  1 1 1 2 2 3 4 4 5 6 ...
##  $ hhweight          : num  627 627 627 627 627 ...
##  $ location          : Factor w/ 2 levels "urban location",..: 1 1 1 1 1 2 2 2 1 1 ...
##  $ region            : Factor w/ 9 levels "Sofia city","Bourgass",..: 8 8 8 9 9 4 4 4 8 8 ...
##  $ ethnicity_head    : Factor w/ 4 levels "Bulgaria","Turks",..: 2 2 2 1 1 1 1 1 1 1 ...
##  $ age               : num  37 11 8 73 70 75 79 80 82 83 ...
##  $ gender            : Factor w/ 2 levels "male","female": 2 2 1 1 2 1 1 2 2 2 ...
##  $ relation          : Factor w/ 9 levels "head                      ",..: 1 3 3 1 2 1 1 2 1 1 ...
##  $ literate          : Factor w/ 2 levels "no","yes": 1 2 2 2 2 2 2 2 2 2 ...
##  $ income_mnt        : num  13.3 13.3 13.3 142.5 142.5 ...
##  $ income            : num  160 160 160 1710 1710 ...
##  $ aggregate         : num  1042 1042 1042 3271 3271 ...
##  $ aggr_ind_annual   : num  347 347 347 1635 1635 ...
##  $ educ_completed    : int  2 4 4 4 3 3 3 3 4 4 ...
##  $ grade_complete    : num  4 3 0 3 4 4 4 4 5 5 ...
##  $ grade_all         : num  4 11 8 11 8 8 8 8 13 13 ...
##  $ unemployed        : int  2 1 1 1 1 1 1 1 1 1 ...
##  $ reason_OLF        : int  NA NA NA 3 3 3 9 9 3 3 ...
##  $ sector            : int  NA NA NA NA NA NA 1 1 NA NA ...
##  $ occupation        : int  NA NA NA NA NA NA 5 5 NA NA ...
##  $ earn_mont         : num  0 0 0 0 0 0 20 20 0 0 ...
##  $ earn_ann          : num  0 0 0 0 0 0 240 240 0 0 ...
##  $ hours_week        : num  NA NA NA NA NA NA 30 35 NA NA ...
##  $ hours_mnt         : num  NA NA NA NA NA ...
##  $ fulltime          : int  NA NA NA NA NA NA 1 1 NA NA ...
##  $ hhexp             : num  100 100 100 343 343 ...
##  $ legacy_pension_amt: num  NA NA NA NA NA NA NA NA NA NA ...
##  - attr(*, "datalabel")= chr ""
##  - attr(*, "time.stamp")= chr ""
##  - attr(*, "formats")= chr  "%9.0g" "%9.0g" "%9.0g" "%9.0g" ...
##  - attr(*, "types")= int  100 100 108 108 108 100 108 108 108 100 ...
##  - attr(*, "val.labels")= chr  "" "" "location" "region" ...
##  - attr(*, "var.labels")= chr  "hhid" "hhweight" "location" "region" ...
##  - attr(*, "expansion.fields")=List of 12
##   ..$ : chr  "_dta" "_svy_su1" "cluster"
##   ..$ : chr  "_dta" "_svy_strata1" "strata"
##   ..$ : chr  "_dta" "_svy_stages" "1"
##   ..$ : chr  "_dta" "_svy_version" "2"
##   ..$ : chr  "_dta" "__XijVarLabcons" "(sum) cons"
##   ..$ : chr  "_dta" "ReS_Xij" "cons"
##   ..$ : chr  "_dta" "ReS_str" "0"
##   ..$ : chr  "_dta" "ReS_j" "group"
##   ..$ : chr  "_dta" "ReS_ver" "v.2"
##   ..$ : chr  "_dta" "ReS_i" "hhid dur"
##   ..$ : chr  "_dta" "note1" "variables g1pc, g2pc, g3pc, g4pc, g5pc, g7pc, g8pc, g9pc, g10pc, g11pc, g12pc,  gall, health, rent, durables we"| __truncated__
##   ..$ : chr  "_dta" "note0" "1"
##  - attr(*, "version")= int 7
##  - attr(*, "label.table")=List of 12
##   ..$ location: Named int  1 2
##   .. ..- attr(*, "names")= chr  "urban location" "rural location"
##   ..$ region  : Named int  1 2 3 4 5 6 7 8 9
##   .. ..- attr(*, "names")= chr  "Sofia city" "Bourgass" "Varna" "Lovetch" ...
##   ..$ ethnic  : Named int  1 2 3 4
##   .. ..- attr(*, "names")= chr  "Bulgaria" "Turks" "Roma" "Other"
##   ..$ s2_q2   : Named int  1 2
##   .. ..- attr(*, "names")= chr  "male" "female"
##   ..$ s2_q3   : Named int  1 2 3 4 5 6 7 8 9
##   .. ..- attr(*, "names")= chr  "head                      " "spouse/partner            " "child                     " "son/daughter-in-law       " ...
##   ..$ lit     : Named int  1 2
##   .. ..- attr(*, "names")= chr  "no" "yes"
##   ..$         : Named int  1 2 3 4
##   .. ..- attr(*, "names")= chr  "never attanded" "primary" "secondary" "postsecondary"
##   ..$         : Named int  1 2
##   .. ..- attr(*, "names")= chr  "Not unemployed" "Unemployed"
##   ..$         : Named int  1 2 3 4 5 6 7 8 9 10
##   .. ..- attr(*, "names")= chr  "student" "housewife/childcare" "in retirement" "illness, disability" ...
##   ..$         : Named int  1 2 3 4 5 6 7 8 9 10
##   .. ..- attr(*, "names")= chr  "agriculture" "mining" "manufacturing" "utilities" ...
##   ..$         : Named int  1 2 3 4 5
##   .. ..- attr(*, "names")= chr  "private company" "public works program" "government,public sector, army" "private individual" ...
##   ..$         : Named int  1 2
##   .. ..- attr(*, "names")= chr  "no" "yes"
# Create and print structure of edu_equal_2
edu_equal_2 <- read.dta(path, convert.factors = FALSE)
str(edu_equal_2)
## 'data.frame':    12214 obs. of  27 variables:
##  $ hhid              : num  1 1 1 2 2 3 4 4 5 6 ...
##  $ hhweight          : num  627 627 627 627 627 ...
##  $ location          : int  1 1 1 1 1 2 2 2 1 1 ...
##  $ region            : int  8 8 8 9 9 4 4 4 8 8 ...
##  $ ethnicity_head    : int  2 2 2 1 1 1 1 1 1 1 ...
##  $ age               : num  37 11 8 73 70 75 79 80 82 83 ...
##  $ gender            : int  2 2 1 1 2 1 1 2 2 2 ...
##  $ relation          : int  1 3 3 1 2 1 1 2 1 1 ...
##  $ literate          : int  1 2 2 2 2 2 2 2 2 2 ...
##  $ income_mnt        : num  13.3 13.3 13.3 142.5 142.5 ...
##  $ income            : num  160 160 160 1710 1710 ...
##  $ aggregate         : num  1042 1042 1042 3271 3271 ...
##  $ aggr_ind_annual   : num  347 347 347 1635 1635 ...
##  $ educ_completed    : int  2 4 4 4 3 3 3 3 4 4 ...
##  $ grade_complete    : num  4 3 0 3 4 4 4 4 5 5 ...
##  $ grade_all         : num  4 11 8 11 8 8 8 8 13 13 ...
##  $ unemployed        : int  2 1 1 1 1 1 1 1 1 1 ...
##  $ reason_OLF        : int  NA NA NA 3 3 3 9 9 3 3 ...
##  $ sector            : int  NA NA NA NA NA NA 1 1 NA NA ...
##  $ occupation        : int  NA NA NA NA NA NA 5 5 NA NA ...
##  $ earn_mont         : num  0 0 0 0 0 0 20 20 0 0 ...
##  $ earn_ann          : num  0 0 0 0 0 0 240 240 0 0 ...
##  $ hours_week        : num  NA NA NA NA NA NA 30 35 NA NA ...
##  $ hours_mnt         : num  NA NA NA NA NA ...
##  $ fulltime          : int  NA NA NA NA NA NA 1 1 NA NA ...
##  $ hhexp             : num  100 100 100 343 343 ...
##  $ legacy_pension_amt: num  NA NA NA NA NA NA NA NA NA NA ...
##  - attr(*, "datalabel")= chr ""
##  - attr(*, "time.stamp")= chr ""
##  - attr(*, "formats")= chr  "%9.0g" "%9.0g" "%9.0g" "%9.0g" ...
##  - attr(*, "types")= int  100 100 108 108 108 100 108 108 108 100 ...
##  - attr(*, "val.labels")= chr  "" "" "location" "region" ...
##  - attr(*, "var.labels")= chr  "hhid" "hhweight" "location" "region" ...
##  - attr(*, "expansion.fields")=List of 12
##   ..$ : chr  "_dta" "_svy_su1" "cluster"
##   ..$ : chr  "_dta" "_svy_strata1" "strata"
##   ..$ : chr  "_dta" "_svy_stages" "1"
##   ..$ : chr  "_dta" "_svy_version" "2"
##   ..$ : chr  "_dta" "__XijVarLabcons" "(sum) cons"
##   ..$ : chr  "_dta" "ReS_Xij" "cons"
##   ..$ : chr  "_dta" "ReS_str" "0"
##   ..$ : chr  "_dta" "ReS_j" "group"
##   ..$ : chr  "_dta" "ReS_ver" "v.2"
##   ..$ : chr  "_dta" "ReS_i" "hhid dur"
##   ..$ : chr  "_dta" "note1" "variables g1pc, g2pc, g3pc, g4pc, g5pc, g7pc, g8pc, g9pc, g10pc, g11pc, g12pc,  gall, health, rent, durables we"| __truncated__
##   ..$ : chr  "_dta" "note0" "1"
##  - attr(*, "version")= int 7
##  - attr(*, "label.table")=List of 12
##   ..$ location: Named int  1 2
##   .. ..- attr(*, "names")= chr  "urban location" "rural location"
##   ..$ region  : Named int  1 2 3 4 5 6 7 8 9
##   .. ..- attr(*, "names")= chr  "Sofia city" "Bourgass" "Varna" "Lovetch" ...
##   ..$ ethnic  : Named int  1 2 3 4
##   .. ..- attr(*, "names")= chr  "Bulgaria" "Turks" "Roma" "Other"
##   ..$ s2_q2   : Named int  1 2
##   .. ..- attr(*, "names")= chr  "male" "female"
##   ..$ s2_q3   : Named int  1 2 3 4 5 6 7 8 9
##   .. ..- attr(*, "names")= chr  "head                      " "spouse/partner            " "child                     " "son/daughter-in-law       " ...
##   ..$ lit     : Named int  1 2
##   .. ..- attr(*, "names")= chr  "no" "yes"
##   ..$         : Named int  1 2 3 4
##   .. ..- attr(*, "names")= chr  "never attanded" "primary" "secondary" "postsecondary"
##   ..$         : Named int  1 2
##   .. ..- attr(*, "names")= chr  "Not unemployed" "Unemployed"
##   ..$         : Named int  1 2 3 4 5 6 7 8 9 10
##   .. ..- attr(*, "names")= chr  "student" "housewife/childcare" "in retirement" "illness, disability" ...
##   ..$         : Named int  1 2 3 4 5 6 7 8 9 10
##   .. ..- attr(*, "names")= chr  "agriculture" "mining" "manufacturing" "utilities" ...
##   ..$         : Named int  1 2 3 4 5
##   .. ..- attr(*, "names")= chr  "private company" "public works program" "government,public sector, army" "private individual" ...
##   ..$         : Named int  1 2
##   .. ..- attr(*, "names")= chr  "no" "yes"
# Create and print structure of edu_equal_3
edu_equal_3 <- read.dta(path, convert.underscore = TRUE)
str(edu_equal_3)
## 'data.frame':    12214 obs. of  27 variables:
##  $ hhid              : num  1 1 1 2 2 3 4 4 5 6 ...
##  $ hhweight          : num  627 627 627 627 627 ...
##  $ location          : Factor w/ 2 levels "urban location",..: 1 1 1 1 1 2 2 2 1 1 ...
##  $ region            : Factor w/ 9 levels "Sofia city","Bourgass",..: 8 8 8 9 9 4 4 4 8 8 ...
##  $ ethnicity.head    : Factor w/ 4 levels "Bulgaria","Turks",..: 2 2 2 1 1 1 1 1 1 1 ...
##  $ age               : num  37 11 8 73 70 75 79 80 82 83 ...
##  $ gender            : Factor w/ 2 levels "male","female": 2 2 1 1 2 1 1 2 2 2 ...
##  $ relation          : Factor w/ 9 levels "head                      ",..: 1 3 3 1 2 1 1 2 1 1 ...
##  $ literate          : Factor w/ 2 levels "no","yes": 1 2 2 2 2 2 2 2 2 2 ...
##  $ income.mnt        : num  13.3 13.3 13.3 142.5 142.5 ...
##  $ income            : num  160 160 160 1710 1710 ...
##  $ aggregate         : num  1042 1042 1042 3271 3271 ...
##  $ aggr.ind.annual   : num  347 347 347 1635 1635 ...
##  $ educ.completed    : int  2 4 4 4 3 3 3 3 4 4 ...
##  $ grade.complete    : num  4 3 0 3 4 4 4 4 5 5 ...
##  $ grade.all         : num  4 11 8 11 8 8 8 8 13 13 ...
##  $ unemployed        : int  2 1 1 1 1 1 1 1 1 1 ...
##  $ reason.OLF        : int  NA NA NA 3 3 3 9 9 3 3 ...
##  $ sector            : int  NA NA NA NA NA NA 1 1 NA NA ...
##  $ occupation        : int  NA NA NA NA NA NA 5 5 NA NA ...
##  $ earn.mont         : num  0 0 0 0 0 0 20 20 0 0 ...
##  $ earn.ann          : num  0 0 0 0 0 0 240 240 0 0 ...
##  $ hours.week        : num  NA NA NA NA NA NA 30 35 NA NA ...
##  $ hours.mnt         : num  NA NA NA NA NA ...
##  $ fulltime          : int  NA NA NA NA NA NA 1 1 NA NA ...
##  $ hhexp             : num  100 100 100 343 343 ...
##  $ legacy.pension.amt: num  NA NA NA NA NA NA NA NA NA NA ...
##  - attr(*, "datalabel")= chr ""
##  - attr(*, "time.stamp")= chr ""
##  - attr(*, "formats")= chr  "%9.0g" "%9.0g" "%9.0g" "%9.0g" ...
##  - attr(*, "types")= int  100 100 108 108 108 100 108 108 108 100 ...
##  - attr(*, "val.labels")= chr  "" "" "location" "region" ...
##  - attr(*, "var.labels")= chr  "hhid" "hhweight" "location" "region" ...
##  - attr(*, "expansion.fields")=List of 12
##   ..$ : chr  "_dta" "_svy_su1" "cluster"
##   ..$ : chr  "_dta" "_svy_strata1" "strata"
##   ..$ : chr  "_dta" "_svy_stages" "1"
##   ..$ : chr  "_dta" "_svy_version" "2"
##   ..$ : chr  "_dta" "__XijVarLabcons" "(sum) cons"
##   ..$ : chr  "_dta" "ReS_Xij" "cons"
##   ..$ : chr  "_dta" "ReS_str" "0"
##   ..$ : chr  "_dta" "ReS_j" "group"
##   ..$ : chr  "_dta" "ReS_ver" "v.2"
##   ..$ : chr  "_dta" "ReS_i" "hhid dur"
##   ..$ : chr  "_dta" "note1" "variables g1pc, g2pc, g3pc, g4pc, g5pc, g7pc, g8pc, g9pc, g10pc, g11pc, g12pc,  gall, health, rent, durables we"| __truncated__
##   ..$ : chr  "_dta" "note0" "1"
##  - attr(*, "version")= int 7
##  - attr(*, "label.table")=List of 12
##   ..$ location: Named int  1 2
##   .. ..- attr(*, "names")= chr  "urban location" "rural location"
##   ..$ region  : Named int  1 2 3 4 5 6 7 8 9
##   .. ..- attr(*, "names")= chr  "Sofia city" "Bourgass" "Varna" "Lovetch" ...
##   ..$ ethnic  : Named int  1 2 3 4
##   .. ..- attr(*, "names")= chr  "Bulgaria" "Turks" "Roma" "Other"
##   ..$ s2_q2   : Named int  1 2
##   .. ..- attr(*, "names")= chr  "male" "female"
##   ..$ s2_q3   : Named int  1 2 3 4 5 6 7 8 9
##   .. ..- attr(*, "names")= chr  "head                      " "spouse/partner            " "child                     " "son/daughter-in-law       " ...
##   ..$ lit     : Named int  1 2
##   .. ..- attr(*, "names")= chr  "no" "yes"
##   ..$         : Named int  1 2 3 4
##   .. ..- attr(*, "names")= chr  "never attanded" "primary" "secondary" "postsecondary"
##   ..$         : Named int  1 2
##   .. ..- attr(*, "names")= chr  "Not unemployed" "Unemployed"
##   ..$         : Named int  1 2 3 4 5 6 7 8 9 10
##   .. ..- attr(*, "names")= chr  "student" "housewife/childcare" "in retirement" "illness, disability" ...
##   ..$         : Named int  1 2 3 4 5 6 7 8 9 10
##   .. ..- attr(*, "names")= chr  "agriculture" "mining" "manufacturing" "utilities" ...
##   ..$         : Named int  1 2 3 4 5
##   .. ..- attr(*, "names")= chr  "private company" "public works program" "government,public sector, army" "private individual" ...
##   ..$         : Named int  1 2
##   .. ..- attr(*, "names")= chr  "no" "yes"
# For example, you can ask yourself how many observations (e.g. how many people) have an age higher than 40 and are literate?
nrow(subset(edu_equal_1, age > 40 & literate == "yes"))
## [1] 6506
#How many observations/individuals from Bulgaria have an income above 1000?
nrow(subset(edu_equal_1, ethnicity_head == "Bulgaria" & income > 1000))
## [1] 8997

5.6.2.3 Importar archivos SPSS

El paquete foreign puede importar formatos de SPSS, usando la función read.spss(). El formato es el siguiente:

read.spss(file, use.value.labels = TRUE, to.data.frame = FALSE)

  • use.value.labels. Convierte las columnas labelled en valores factoriales de R.
  • to.data.frame. Devuelve un data frame en vez de una lista.

Existen otros muchos argumentos, como trim.factor.names, trim_values use.missings, etc.

# Import international.sav as a data frame: demo
demo <- read.spss("Datos/international.sav", to.data.frame = TRUE)
## re-encoding from CP1252
# Create boxplot of gdp variable of demo
boxplot(demo$gdp)

# Import international.sav as demo_1
demo_1 <- read.spss("Datos/international.sav", to.data.frame = TRUE, use.value.labels = FALSE)
## re-encoding from CP1252
# Print out the head of demo_1
head(demo_1)
##   id              country contint m_illit f_illit lifeexpt  gdp
## 1  1 Argentina                  2     3.0     3.0       16 3375
## 2  2 Benin                      1    45.2    74.5        7  521
## 3  3 Burundi                    1    33.2    48.1        5   86
## 4  4 Chile                      2     4.2     4.4       14 4523
## 5  5 Dominican Republic         2    12.0    12.7       12 2408
## 6  6 El Salvador                2    17.6    22.9       11 2302
# Import international.sav as demo_2
demo_2 <- read.spss("Datos/international.sav", to.data.frame = TRUE, use.value.labels = TRUE)
## re-encoding from CP1252
# Print out the head of demo_2
head(demo_2)
##   id              country  contint m_illit f_illit lifeexpt  gdp
## 1  1 Argentina            Americas     3.0     3.0       16 3375
## 2  2 Benin                  Africa    45.2    74.5        7  521
## 3  3 Burundi                Africa    33.2    48.1        5   86
## 4  4 Chile                Americas     4.2     4.4       14 4523
## 5  5 Dominican Republic   Americas    12.0    12.7       12 2408
## 6  6 El Salvador          Americas    17.6    22.9       11 2302