Capítulo 9 Repaso: empezando a trastear con datos

Scripts usados:

Vamos a hacer un alto en el camino y hacer un repaso de lo que hemos aprendido con un conjunto nuevo, el conjunto de datos swiss del paquete {datasets}. Intenta contestar a las preguntas planteadas antes de que sean resueltas. Si te resulta aún un poco complicado, no pasa nada, la solución es seguir trasteando hasta que rompas algo (es broma).

 

1. ¿Cómo cargarías los datos sabiendo su nombre y el paquete en el que está?

 

Nuestros datos se llaman swiss y son del paquete {datasets}, así que lo primero que debemos hacer es instalar el paquete (en caso de no haberlo hecho aún, con install.packages("datasets")), después llamar a ese paquete (tenemos el libro comprado y lo sacamos de la estantería) con library(datasets) y escribir el nombre del conjunto de datos para mostrarlo.

library(datasets)
swiss
##              Fertility Agriculture Examination Education Catholic
## Courtelary        80.2        17.0          15        12     9.96
## Delemont          83.1        45.1           6         9    84.84
## Franches-Mnt      92.5        39.7           5         5    93.40
## Moutier           85.8        36.5          12         7    33.77
## Neuveville        76.9        43.5          17        15     5.16
## Porrentruy        76.1        35.3           9         7    90.57
## Broye             83.8        70.2          16         7    92.85
## Glane             92.4        67.8          14         8    97.16
## Gruyere           82.4        53.3          12         7    97.67
## Sarine            82.9        45.2          16        13    91.38
## Veveyse           87.1        64.5          14         6    98.61
## Aigle             64.1        62.0          21        12     8.52
## Aubonne           66.9        67.5          14         7     2.27
## Avenches          68.9        60.7          19        12     4.43
## Cossonay          61.7        69.3          22         5     2.82
## Echallens         68.3        72.6          18         2    24.20
## Grandson          71.7        34.0          17         8     3.30
## Lausanne          55.7        19.4          26        28    12.11
## La Vallee         54.3        15.2          31        20     2.15
## Lavaux            65.1        73.0          19         9     2.84
## Morges            65.5        59.8          22        10     5.23
## Moudon            65.0        55.1          14         3     4.52
## Nyone             56.6        50.9          22        12    15.14
## Orbe              57.4        54.1          20         6     4.20
## Oron              72.5        71.2          12         1     2.40
## Payerne           74.2        58.1          14         8     5.23
## Paysd'enhaut      72.0        63.5           6         3     2.56
## Rolle             60.5        60.8          16        10     7.72
## Vevey             58.3        26.8          25        19    18.46
## Yverdon           65.4        49.5          15         8     6.10
## Conthey           75.5        85.9           3         2    99.71
## Entremont         69.3        84.9           7         6    99.68
## Herens            77.3        89.7           5         2   100.00
## Martigwy          70.5        78.2          12         6    98.96
## Monthey           79.4        64.9           7         3    98.22
## St Maurice        65.0        75.9           9         9    99.06
## Sierre            92.2        84.6           3         3    99.46
## Sion              79.3        63.1          13        13    96.83
## Boudry            70.4        38.4          26        12     5.62
## La Chauxdfnd      65.7         7.7          29        11    13.79
## Le Locle          72.7        16.7          22        13    11.22
## Neuchatel         64.4        17.6          35        32    16.92
## Val de Ruz        77.6        37.6          15         7     4.97
## ValdeTravers      67.6        18.7          25         7     8.65
## V. De Geneve      35.0         1.2          37        53    42.34
## Rive Droite       44.7        46.6          16        29    50.43
## Rive Gauche       42.8        27.7          22        29    58.33
##              Infant.Mortality
## Courtelary               22.2
## Delemont                 22.2
## Franches-Mnt             20.2
## Moutier                  20.3
## Neuveville               20.6
## Porrentruy               26.6
## Broye                    23.6
## Glane                    24.9
## Gruyere                  21.0
## Sarine                   24.4
## Veveyse                  24.5
## Aigle                    16.5
## Aubonne                  19.1
## Avenches                 22.7
## Cossonay                 18.7
## Echallens                21.2
## Grandson                 20.0
## Lausanne                 20.2
## La Vallee                10.8
## Lavaux                   20.0
## Morges                   18.0
## Moudon                   22.4
## Nyone                    16.7
## Orbe                     15.3
## Oron                     21.0
## Payerne                  23.8
## Paysd'enhaut             18.0
## Rolle                    16.3
## Vevey                    20.9
## Yverdon                  22.5
## Conthey                  15.1
## Entremont                19.8
## Herens                   18.3
## Martigwy                 19.4
## Monthey                  20.2
## St Maurice               17.8
## Sierre                   16.3
## Sion                     18.1
## Boudry                   20.3
## La Chauxdfnd             20.5
## Le Locle                 18.9
## Neuchatel                23.0
## Val de Ruz               20.0
## ValdeTravers             19.5
## V. De Geneve             18.0
## Rive Droite              18.2
## Rive Gauche              19.3

Podríamos no pedirle el libro entero sino solo esa página, de ese conjunto de datos, usando datasets::swiss (sin hacer uso del library() previo).

datasets::swiss

 

2. Tenemos los datos guardados en swiss, ¿qué tipo de objeto es?

 

Al mostrarlos ya lo habrás intuido pero nuestro conjunto swiss es de tipo data.frame. Para comprobarlo podemos usar la función class().

class(swiss)
## [1] "data.frame"

Si somos un poco observadores/as vemos que todas las variables parecen numéricas así que…podríamos tener una matriz de números. ¿Cómo convertimos los datos a una matriz?

as.matrix(swiss)
##              Fertility Agriculture Examination Education Catholic
## Courtelary        80.2        17.0          15        12     9.96
## Delemont          83.1        45.1           6         9    84.84
## Franches-Mnt      92.5        39.7           5         5    93.40
## Moutier           85.8        36.5          12         7    33.77
## Neuveville        76.9        43.5          17        15     5.16
## Porrentruy        76.1        35.3           9         7    90.57
## Broye             83.8        70.2          16         7    92.85
## Glane             92.4        67.8          14         8    97.16
## Gruyere           82.4        53.3          12         7    97.67
## Sarine            82.9        45.2          16        13    91.38
## Veveyse           87.1        64.5          14         6    98.61
## Aigle             64.1        62.0          21        12     8.52
## Aubonne           66.9        67.5          14         7     2.27
## Avenches          68.9        60.7          19        12     4.43
## Cossonay          61.7        69.3          22         5     2.82
## Echallens         68.3        72.6          18         2    24.20
## Grandson          71.7        34.0          17         8     3.30
## Lausanne          55.7        19.4          26        28    12.11
## La Vallee         54.3        15.2          31        20     2.15
## Lavaux            65.1        73.0          19         9     2.84
## Morges            65.5        59.8          22        10     5.23
## Moudon            65.0        55.1          14         3     4.52
## Nyone             56.6        50.9          22        12    15.14
## Orbe              57.4        54.1          20         6     4.20
## Oron              72.5        71.2          12         1     2.40
## Payerne           74.2        58.1          14         8     5.23
## Paysd'enhaut      72.0        63.5           6         3     2.56
## Rolle             60.5        60.8          16        10     7.72
## Vevey             58.3        26.8          25        19    18.46
## Yverdon           65.4        49.5          15         8     6.10
## Conthey           75.5        85.9           3         2    99.71
## Entremont         69.3        84.9           7         6    99.68
## Herens            77.3        89.7           5         2   100.00
## Martigwy          70.5        78.2          12         6    98.96
## Monthey           79.4        64.9           7         3    98.22
## St Maurice        65.0        75.9           9         9    99.06
## Sierre            92.2        84.6           3         3    99.46
## Sion              79.3        63.1          13        13    96.83
## Boudry            70.4        38.4          26        12     5.62
## La Chauxdfnd      65.7         7.7          29        11    13.79
## Le Locle          72.7        16.7          22        13    11.22
## Neuchatel         64.4        17.6          35        32    16.92
## Val de Ruz        77.6        37.6          15         7     4.97
## ValdeTravers      67.6        18.7          25         7     8.65
## V. De Geneve      35.0         1.2          37        53    42.34
## Rive Droite       44.7        46.6          16        29    50.43
## Rive Gauche       42.8        27.7          22        29    58.33
##              Infant.Mortality
## Courtelary               22.2
## Delemont                 22.2
## Franches-Mnt             20.2
## Moutier                  20.3
## Neuveville               20.6
## Porrentruy               26.6
## Broye                    23.6
## Glane                    24.9
## Gruyere                  21.0
## Sarine                   24.4
## Veveyse                  24.5
## Aigle                    16.5
## Aubonne                  19.1
## Avenches                 22.7
## Cossonay                 18.7
## Echallens                21.2
## Grandson                 20.0
## Lausanne                 20.2
## La Vallee                10.8
## Lavaux                   20.0
## Morges                   18.0
## Moudon                   22.4
## Nyone                    16.7
## Orbe                     15.3
## Oron                     21.0
## Payerne                  23.8
## Paysd'enhaut             18.0
## Rolle                    16.3
## Vevey                    20.9
## Yverdon                  22.5
## Conthey                  15.1
## Entremont                19.8
## Herens                   18.3
## Martigwy                 19.4
## Monthey                  20.2
## St Maurice               17.8
## Sierre                   16.3
## Sion                     18.1
## Boudry                   20.3
## La Chauxdfnd             20.5
## Le Locle                 18.9
## Neuchatel                23.0
## Val de Ruz               20.0
## ValdeTravers             19.5
## V. De Geneve             18.0
## Rive Droite              18.2
## Rive Gauche              19.3
## [1] "matrix"

 

3. ¿Cómo podríamos tener una descripción detallada de los datos?

 

La forma más inmediata es hacerlo es con la función ? swiss, que nos permite ver la documentación en el panel de ayuda.

? swiss

También podemos ver el nombre de las columnas con names() y el nombre de las filas con row.names()

names(swiss)
## [1] "Fertility"        "Agriculture"      "Examination"      "Education"       
## [5] "Catholic"         "Infant.Mortality"
row.names(swiss)
##  [1] "Courtelary"   "Delemont"     "Franches-Mnt" "Moutier"      "Neuveville"  
##  [6] "Porrentruy"   "Broye"        "Glane"        "Gruyere"      "Sarine"      
## [11] "Veveyse"      "Aigle"        "Aubonne"      "Avenches"     "Cossonay"    
## [16] "Echallens"    "Grandson"     "Lausanne"     "La Vallee"    "Lavaux"      
## [21] "Morges"       "Moudon"       "Nyone"        "Orbe"         "Oron"        
## [26] "Payerne"      "Paysd'enhaut" "Rolle"        "Vevey"        "Yverdon"     
## [31] "Conthey"      "Entremont"    "Herens"       "Martigwy"     "Monthey"     
## [36] "St Maurice"   "Sierre"       "Sion"         "Boudry"       "La Chauxdfnd"
## [41] "Le Locle"     "Neuchatel"    "Val de Ruz"   "ValdeTravers" "V. De Geneve"
## [46] "Rive Droite"  "Rive Gauche"

Los datos representan algunos indicadores de fertilidad y socioeconómicos (estandarizados, entre 0 y 100) de las 47 provincias francoparlantes de Suiza, con datos del año 1888. Como podemos leer en la ayuda, en la web https://opr.princeton.edu/archive/pefp/switz.aspx tenemos los datos de 182 distritos para dicho año.

 

4. ¿Cómo podríamos «ver» los datos? ¿Cuántas provincias hay incluidas? ¿Cuántas variables han sido medidas en cada una de ellas?

 

Podemos hacerlo de varias maneras, y una de ellas es pedirle una cabecera de la tabla (las primeras filas) con head().

head(swiss)
##              Fertility Agriculture Examination Education Catholic
## Courtelary        80.2        17.0          15        12     9.96
## Delemont          83.1        45.1           6         9    84.84
## Franches-Mnt      92.5        39.7           5         5    93.40
## Moutier           85.8        36.5          12         7    33.77
## Neuveville        76.9        43.5          17        15     5.16
## Porrentruy        76.1        35.3           9         7    90.57
##              Infant.Mortality
## Courtelary               22.2
## Delemont                 22.2
## Franches-Mnt             20.2
## Moutier                  20.3
## Neuveville               20.6
## Porrentruy               26.6

También podemos ver una versión «excelizada» de los datos con `View()

View(swiss)

Para ver las dimensiones de los datos podemos recurrir a dim() (nos dará un vector de longitud 2 con el número de filas y columnas) o a nrow() y ncol()

dim(swiss)
## [1] 47  6
nrow(swiss)
## [1] 47
ncol(swiss)
## [1] 6

 

5. ¿Cómo podríamos definir una nueva variable de tipo texto con los nombres de filas que obtenemos de row.names()?

 

La función row.names() nos devuelve los nombres de las filas, que vamos a guardar en una variable (por ejemplo, en nombres).

nombres <- row.names(swiss)
nombres
##  [1] "Courtelary"   "Delemont"     "Franches-Mnt" "Moutier"      "Neuveville"  
##  [6] "Porrentruy"   "Broye"        "Glane"        "Gruyere"      "Sarine"      
## [11] "Veveyse"      "Aigle"        "Aubonne"      "Avenches"     "Cossonay"    
## [16] "Echallens"    "Grandson"     "Lausanne"     "La Vallee"    "Lavaux"      
## [21] "Morges"       "Moudon"       "Nyone"        "Orbe"         "Oron"        
## [26] "Payerne"      "Paysd'enhaut" "Rolle"        "Vevey"        "Yverdon"     
## [31] "Conthey"      "Entremont"    "Herens"       "Martigwy"     "Monthey"     
## [36] "St Maurice"   "Sierre"       "Sion"         "Boudry"       "La Chauxdfnd"
## [41] "Le Locle"     "Neuchatel"    "Val de Ruz"   "ValdeTravers" "V. De Geneve"
## [46] "Rive Droite"  "Rive Gauche"

Esa variable la vamos a añadir como primera columna, haciendo uso de data.frame(), concatenando dicha columna a las que ya tenemos.

tabla_nueva <- data.frame("provincias" = nombres, swiss)
head(tabla_nueva)
##                provincias Fertility Agriculture Examination Education Catholic
## Courtelary     Courtelary      80.2        17.0          15        12     9.96
## Delemont         Delemont      83.1        45.1           6         9    84.84
## Franches-Mnt Franches-Mnt      92.5        39.7           5         5    93.40
## Moutier           Moutier      85.8        36.5          12         7    33.77
## Neuveville     Neuveville      76.9        43.5          17        15     5.16
## Porrentruy     Porrentruy      76.1        35.3           9         7    90.57
##              Infant.Mortality
## Courtelary               22.2
## Delemont                 22.2
## Franches-Mnt             20.2
## Moutier                  20.3
## Neuveville               20.6
## Porrentruy               26.6

Podemos incluso eliminar el nombre de las filas (ya las tenemos guardadas como variables).

row.names(tabla_nueva) <- NULL # anulamos nombre de filas
head(tabla_nueva)
##     provincias Fertility Agriculture Examination Education Catholic
## 1   Courtelary      80.2        17.0          15        12     9.96
## 2     Delemont      83.1        45.1           6         9    84.84
## 3 Franches-Mnt      92.5        39.7           5         5    93.40
## 4      Moutier      85.8        36.5          12         7    33.77
## 5   Neuveville      76.9        43.5          17        15     5.16
## 6   Porrentruy      76.1        35.3           9         7    90.57
##   Infant.Mortality
## 1             22.2
## 2             22.2
## 3             20.2
## 4             20.3
## 5             20.6
## 6             26.6

 

6. ¿Cómo podemos decidir cual de las provincias tiene un indicador estandarizado de la fertilidad superior a 80?

 

La opción más inmediata es obtener la variable Fertility con $ y ejecutar la condición lógica: si es mayor que 80 devolverá TRUE; en caso contrario, FALSE.

tabla_nueva$Fertility > 80
##  [1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [37]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

Para saber las filas exactas que cumplen dicha condición (sus índices) podemos usar la función which().

which(tabla_nueva$Fertility > 80)
##  [1]  1  2  3  4  7  8  9 10 11 37

Incluso podemos pasarles esos índices al vector de nombres que hemos añadido y obtener el nombre de las provincias que cumplen dicha condición.

tabla_nueva$nombres[which(tabla_nueva$Fertility > 80)]
## NULL

 

7. ¿Cómo podemos filtrar la tabla y seleccionar solo dichas provincias, las que tienen fertilidad superior a 80?

 

Podemos hacerlo principalmente de dos maneras. La primera es tratar a los datos como una matriz con el operador [], dejando las columnas libres y pasándole como índices en las filas precisamente la condición lógica: seleccionará las TRUE y no seleccionará las FALSE.

tabla_nueva$Fertility > 80
##  [1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [37]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
tabla_nueva[tabla_nueva$Fertility > 80, ]
##      provincias Fertility Agriculture Examination Education Catholic
## 1    Courtelary      80.2        17.0          15        12     9.96
## 2      Delemont      83.1        45.1           6         9    84.84
## 3  Franches-Mnt      92.5        39.7           5         5    93.40
## 4       Moutier      85.8        36.5          12         7    33.77
## 7         Broye      83.8        70.2          16         7    92.85
## 8         Glane      92.4        67.8          14         8    97.16
## 9       Gruyere      82.4        53.3          12         7    97.67
## 10       Sarine      82.9        45.2          16        13    91.38
## 11      Veveyse      87.1        64.5          14         6    98.61
## 37       Sierre      92.2        84.6           3         3    99.46
##    Infant.Mortality
## 1              22.2
## 2              22.2
## 3              20.2
## 4              20.3
## 7              23.6
## 8              24.9
## 9              21.0
## 10             24.4
## 11             24.5
## 37             16.3

La otra manera, más corta y concisa, es usando subset(), que además nos permitiría seleccionar columnas si quisiéramos filtrarlas.

# sin filtrar columnas
subset(tabla_nueva, subset = Fertility > 80)
##      provincias Fertility Agriculture Examination Education Catholic
## 1    Courtelary      80.2        17.0          15        12     9.96
## 2      Delemont      83.1        45.1           6         9    84.84
## 3  Franches-Mnt      92.5        39.7           5         5    93.40
## 4       Moutier      85.8        36.5          12         7    33.77
## 7         Broye      83.8        70.2          16         7    92.85
## 8         Glane      92.4        67.8          14         8    97.16
## 9       Gruyere      82.4        53.3          12         7    97.67
## 10       Sarine      82.9        45.2          16        13    91.38
## 11      Veveyse      87.1        64.5          14         6    98.61
## 37       Sierre      92.2        84.6           3         3    99.46
##    Infant.Mortality
## 1              22.2
## 2              22.2
## 3              20.2
## 4              20.3
## 7              23.6
## 8              24.9
## 9              21.0
## 10             24.4
## 11             24.5
## 37             16.3
# filtrando columnas
subset(tabla_nueva, subset = Fertility > 80,
       select = c("provincias", "Fertility", "Education"))
##      provincias Fertility Education
## 1    Courtelary      80.2        12
## 2      Delemont      83.1         9
## 3  Franches-Mnt      92.5         5
## 4       Moutier      85.8         7
## 7         Broye      83.8         7
## 8         Glane      92.4         8
## 9       Gruyere      82.4         7
## 10       Sarine      82.9        13
## 11      Veveyse      87.1         6
## 37       Sierre      92.2         3

 

8. ¿Cómo podemos añadir una nueva variable lógica que nos guarde TRUE si la fertilidad es superior a 80 y FALSE en caso contrario?

 

Vamos a guardar el resultado de la condición lógica en una variable y vamos a incluirla en el data.frame igual que hemos incluido los nombres.

var_logica <- tabla_nueva$Fertility > 80
tabla_nueva_2 <- data.frame(tabla_nueva, "alta_fertilidad" = var_logica)

Podemos realizar el filtro anterior haciendo uso de esa nueva variable.

# sin filtrar columnas
subset(tabla_nueva_2, subset = alta_fertilidad == TRUE)
##      provincias Fertility Agriculture Examination Education Catholic
## 1    Courtelary      80.2        17.0          15        12     9.96
## 2      Delemont      83.1        45.1           6         9    84.84
## 3  Franches-Mnt      92.5        39.7           5         5    93.40
## 4       Moutier      85.8        36.5          12         7    33.77
## 7         Broye      83.8        70.2          16         7    92.85
## 8         Glane      92.4        67.8          14         8    97.16
## 9       Gruyere      82.4        53.3          12         7    97.67
## 10       Sarine      82.9        45.2          16        13    91.38
## 11      Veveyse      87.1        64.5          14         6    98.61
## 37       Sierre      92.2        84.6           3         3    99.46
##    Infant.Mortality alta_fertilidad
## 1              22.2            TRUE
## 2              22.2            TRUE
## 3              20.2            TRUE
## 4              20.3            TRUE
## 7              23.6            TRUE
## 8              24.9            TRUE
## 9              21.0            TRUE
## 10             24.4            TRUE
## 11             24.5            TRUE
## 37             16.3            TRUE
# igual (sin filtrar columnas)
subset(tabla_nueva_2, subset = alta_fertilidad)
##      provincias Fertility Agriculture Examination Education Catholic
## 1    Courtelary      80.2        17.0          15        12     9.96
## 2      Delemont      83.1        45.1           6         9    84.84
## 3  Franches-Mnt      92.5        39.7           5         5    93.40
## 4       Moutier      85.8        36.5          12         7    33.77
## 7         Broye      83.8        70.2          16         7    92.85
## 8         Glane      92.4        67.8          14         8    97.16
## 9       Gruyere      82.4        53.3          12         7    97.67
## 10       Sarine      82.9        45.2          16        13    91.38
## 11      Veveyse      87.1        64.5          14         6    98.61
## 37       Sierre      92.2        84.6           3         3    99.46
##    Infant.Mortality alta_fertilidad
## 1              22.2            TRUE
## 2              22.2            TRUE
## 3              20.2            TRUE
## 4              20.3            TRUE
## 7              23.6            TRUE
## 8              24.9            TRUE
## 9              21.0            TRUE
## 10             24.4            TRUE
## 11             24.5            TRUE
## 37             16.3            TRUE
# filtrando columnas
subset(tabla_nueva_2, subset = alta_fertilidad,
       select = c("provincias", "Fertility", "Education"))
##      provincias Fertility Education
## 1    Courtelary      80.2        12
## 2      Delemont      83.1         9
## 3  Franches-Mnt      92.5         5
## 4       Moutier      85.8         7
## 7         Broye      83.8         7
## 8         Glane      92.4         8
## 9       Gruyere      82.4         7
## 10       Sarine      82.9        13
## 11      Veveyse      87.1         6
## 37       Sierre      92.2         3

 

9. ¿Cómo podemos definir una nueva variable de tipo fecha, que empiece el 1 de enero de 1888, acabe el 31 de diciembre de 1888, y las fechas estén equiespaciadas en el tiempo?

 

Si recuerdas las fechas internamente son guardadas como números así que podemos definir una secuencia de fechas, desde una fecha inicial hasta una fecha final, con la misma longitud que filas tenemos en los datos.

fechas <-
  seq(as.Date("1888-01-01"), as.Date("1888-12-31"), l = nrow(tabla_nueva_2))
fechas
##  [1] "1888-01-01" "1888-01-08" "1888-01-16" "1888-01-24" "1888-02-01"
##  [6] "1888-02-09" "1888-02-17" "1888-02-25" "1888-03-04" "1888-03-12"
## [11] "1888-03-20" "1888-03-28" "1888-04-05" "1888-04-13" "1888-04-21"
## [16] "1888-04-29" "1888-05-06" "1888-05-14" "1888-05-22" "1888-05-30"
## [21] "1888-06-07" "1888-06-15" "1888-06-23" "1888-07-01" "1888-07-09"
## [26] "1888-07-17" "1888-07-25" "1888-08-02" "1888-08-10" "1888-08-18"
## [31] "1888-08-26" "1888-09-02" "1888-09-10" "1888-09-18" "1888-09-26"
## [36] "1888-10-04" "1888-10-12" "1888-10-20" "1888-10-28" "1888-11-05"
## [41] "1888-11-13" "1888-11-21" "1888-11-29" "1888-12-07" "1888-12-15"
## [46] "1888-12-23" "1888-12-31"

Podemos comprobar que son fechas usando class() pero también intentando sumar días a las fechas (sin que aparezca un error).

class(fechas)
## [1] "Date"
fechas + 1
##  [1] "1888-01-02" "1888-01-09" "1888-01-17" "1888-01-25" "1888-02-02"
##  [6] "1888-02-10" "1888-02-18" "1888-02-26" "1888-03-05" "1888-03-13"
## [11] "1888-03-21" "1888-03-29" "1888-04-06" "1888-04-14" "1888-04-22"
## [16] "1888-04-30" "1888-05-07" "1888-05-15" "1888-05-23" "1888-05-31"
## [21] "1888-06-08" "1888-06-16" "1888-06-24" "1888-07-02" "1888-07-10"
## [26] "1888-07-18" "1888-07-26" "1888-08-03" "1888-08-11" "1888-08-19"
## [31] "1888-08-27" "1888-09-03" "1888-09-11" "1888-09-19" "1888-09-27"
## [36] "1888-10-05" "1888-10-13" "1888-10-21" "1888-10-29" "1888-11-06"
## [41] "1888-11-14" "1888-11-22" "1888-11-30" "1888-12-08" "1888-12-16"
## [46] "1888-12-24" "1889-01-01"

Para añadir a la tabla dicha variable basta con hacer de nuevo data.frame() concatenando la tabla que teníamos con la nueva columna.

tabla_final <- data.frame(tabla_nueva_2, fechas)
head(tabla_final)
##     provincias Fertility Agriculture Examination Education Catholic
## 1   Courtelary      80.2        17.0          15        12     9.96
## 2     Delemont      83.1        45.1           6         9    84.84
## 3 Franches-Mnt      92.5        39.7           5         5    93.40
## 4      Moutier      85.8        36.5          12         7    33.77
## 5   Neuveville      76.9        43.5          17        15     5.16
## 6   Porrentruy      76.1        35.3           9         7    90.57
##   Infant.Mortality alta_fertilidad     fechas
## 1             22.2            TRUE 1888-01-01
## 2             22.2            TRUE 1888-01-08
## 3             20.2            TRUE 1888-01-16
## 4             20.3            TRUE 1888-01-24
## 5             20.6           FALSE 1888-02-01
## 6             26.6           FALSE 1888-02-09