1. Introducción

La incorrecta administración de los datos dificulta obtener la información que se necesita en el momento en que se necesita. Afortunadamente, tenemos herramientas de software que, aunque se diseñen para abordar eficazmente el almacenamiento de datos, descubrimiento, cumplimiento, etc., tienen como objetivo general hacer que la gestión y el mantenimiento de los datos sea fácil. Pero, ¿son todos los datos igualmente sencillos de gestionar?

Vamos a ver dos tipos de datos con los que estamos acostumbrados a trabajar, los datos estructurados y no estructurados.

¿Qué son datos estructurados?

Cuando hablamos de datos estructurados nos referimos a la información que se suele encontrar en la mayoría de bases de datos. Son archivos de tipo texto que se acostumbran colocar en arreglos rectangularres de filas y columnas. Este tipo de datos pueden ser ordenados y procesados fácilmente por cualquier herramienta de analítica. Lo podríamos ver como si fuese un archivador perfectamente organizado donde todo está identificado, etiquetado y es de fácil acceso.

Es probable que la mayoría de las organizaciones estén familiarizadas con este tipo de datos y ya los estén utilizando de forma eficiente.

Pero, aunque parezca increíble, la base de datos con información estructurada de una empresa, ni siquiera contiene la mitad de la información que hay disponible en la empresa lista para ser usada. El \(80\%\) de la información relevante para un negocio se origina en forma no estructurada, principalmente en formato texto. Además, en la mayoría de empresas los datos potencialmente útiles resultan inaccesibles; algunos estudios han revelado que:

Los datos en la mayoria de las empresas suelen estar aislados, o se manejan en sistemas heredados o aplicaciones muy poco utilizadas.

El término no estructurado se enfrenta a diferentes opiniones por diversas razones. Hay quien dice que aunque no se pueda identificar una estructura formal en ellos, es posible que pueda estar implícita y, en ese caso, no debería ser categorizado como no estructurado. Sin embargo, por otro lado, si los datos tienen alguna forma de estructura, pero ésta no es útil y no puede se utiliza para procesarlos, estos deberían ser categorizados como no estructurados.

2. Estructuras de datos en R

Antes de mencionar las diferentes estructuras de datos, vale la pena recordar los diferentes tipos de datos con los que contamos en R.

Tipos de datos Descripción Definición
Numérico número decimal numero <- 1.5
Entero número entero int <- 1
Caracter cadenas de texo str <-"un texto"
Complejo número complejo comp <-3+2i
Lógico verdadero (T) o falso (F) a <- 1; b <- 2; a < b
Factor vector de caracteres str <-c("uno","dos","tres")

Veamos a continuación las estructuras de datos más comunes en R.

2.1 Vectores

Es el elemento más básico en R, el cual solo contiene elementos de la misma clase (son atómicos). Se crean con la función c() , que significa “concatenar” o “combinar”.

v  <- c(1.1,10,3.14)
v
## [1]  1.10 10.00  3.14
c(v,55,v)
## [1]  1.10 10.00  3.14 55.00  1.10 10.00  3.14
2.1.1 Operaciones con vectores
v*2+100
## [1] 102.20 120.00 106.28
v^2
## [1]   1.2100 100.0000   9.8596
sqrt(v-1)
## [1] 0.3162278 3.0000000 1.4628739

Algo importante por resaltar, es que cuando ejecutamos por ejemplo: v*2+100, lo que realmente calcula es:

v * c (2,2,2) + c (100,100,100) 
## [1] 102.20 120.00 106.28

Creación de diferentes vectores:

b <- c(2,4,6,8,10) # Crear un vector numérico
c <- c("esto", "eso", "lo otro") # crea un vector de caracteres
d <- c(1,2, "esto") # ¿crea un vector de tipo mixto?
d
## [1] "1"    "2"    "esto"
b[3]
## [1] 6

2.2 Secuencias numéricas

La función seq() , crea secuencias numéricas personalizadas.

1:20
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
pi:10
## [1] 3.141593 4.141593 5.141593 6.141593 7.141593 8.141593 9.141593
15:1
##  [1] 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1
seq(1, 20)
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
seq(0, 10, by=0.5)
##  [1]  0.0  0.5  1.0  1.5  2.0  2.5  3.0  3.5  4.0  4.5  5.0  5.5  6.0  6.5  7.0
## [16]  7.5  8.0  8.5  9.0  9.5 10.0
seq(5, 10, length=20)
##  [1]  5.000000  5.263158  5.526316  5.789474  6.052632  6.315789  6.578947
##  [8]  6.842105  7.105263  7.368421  7.631579  7.894737  8.157895  8.421053
## [15]  8.684211  8.947368  9.210526  9.473684  9.736842 10.000000

2.3 Listas

A diferencia de un vector, una lista es una colección de elementos que pueden ser de diferente tipo.

c     <- list(x=1, y=5)
p     <- list(id=123, cord=c, spatial.reference="WGS_84")
p$id # Los elementos de la lista generalmente se acceden por nombre
## [1] 123
p$cord
## $x
## [1] 1
## 
## $y
## [1] 5
p$cord$x
## [1] 1
p[[2]] # Los elementos están ordenados para que se pueda acceder por índice. Usar corchetes individuales, devuelve una lista
## $x
## [1] 1
## 
## $y
## [1] 5

2.4 Matrices

Una matriz es una estructura bidimensional. Las filas son horizontales y las columnas son verticales. Tiene una característica importante la cual es que acepta sólo una única clase de datos (al igual que los vectores).

M  <- matrix(1:20,nrow=4,ncol=5)
M
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    5    9   13   17
## [2,]    2    6   10   14   18
## [3,]    3    7   11   15   19
## [4,]    4    8   12   16   20
v      <- 1:20
dim(v) <- c(4,5)
v
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    5    9   13   17
## [2,]    2    6   10   14   18
## [3,]    3    7   11   15   19
## [4,]    4    8   12   16   20
identical(M,v)
## [1] TRUE
2.4.1 Operaciones con matrices
A <- matrix(1:9, nrow = 3, byrow = TRUE) # se llena por renglones
A
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
a <- c(3.2,5,14)       # primer vector
b <- c(2.5,4,24)       # segundo vector
c <- c(4.5,7,37)       # tercer vector

B <- rbind(a,b,c)   # une los vectores por renglones 
B
##   [,1] [,2] [,3]
## a  3.2    5   14
## b  2.5    4   24
## c  4.5    7   37
C <- cbind(a,b,c)   # une los vectores por columnas 
C
##         a    b    c
## [1,]  3.2  2.5  4.5
## [2,]  5.0  4.0  7.0
## [3,] 14.0 24.0 37.0
A-B      # resta de matrices
##   [,1] [,2] [,3]
## a -2.2   -3  -11
## b  1.5    1  -18
## c  2.5    1  -28
4*A      # multiplicación escalar
##      [,1] [,2] [,3]
## [1,]    4    8   12
## [2,]   16   20   24
## [3,]   28   32   36
A%*%C    # multiplicación de matrices
##          a     b     c
## [1,]  55.2  82.5 129.5
## [2,] 121.8 174.0 275.0
## [3,] 188.4 265.5 420.5
t(B)     # transpuesta
##         a    b    c
## [1,]  3.2  2.5  4.5
## [2,]  5.0  4.0  7.0
## [3,] 14.0 24.0 37.0
diag(C)  # matriz diagonal
## [1]  3.2  4.0 37.0
det(A)   # determinante
## [1] 6.661338e-16
solve(C) # inversa
##         [,1]      [,2]        [,3]
## a  -3.076923  2.384615 -0.07692308
## b -13.384615  8.523077  0.01538462
## c   9.846154 -6.430769  0.04615385

2.5 Data frames

Un data frame es una estructura de datos bidimensional similar a una matriz, pero funciona de manera muy diferente. Si bien un data frame parece una tabla simple, de hecho es una lista de vectores de la misma longitud. La principal diferencia es que un data frame permite tipos de datos mixtos (por ejemplo, numérico, lógico, caracter). Esto les permite almacenar diferentes tipos de variables, lo cual es muy útil en el análisis estadístico.

arboles <- c("Tipuana", "Andina", "Ceiba")
df <-data.frame(arboles,B) # se crea un data frame (df)
df
##   arboles  X1 X2 X3
## a Tipuana 3.2  5 14
## b  Andina 2.5  4 24
## c   Ceiba 4.5  7 37
class(df)
## [1] "data.frame"
cnombres <- c("Nombre_cientifico","Diametro", "Altura","edad")
colnames(df) <- cnombres
df
##   Nombre_cientifico Diametro Altura edad
## a           Tipuana      3.2      5   14
## b            Andina      2.5      4   24
## c             Ceiba      4.5      7   37

2.5.1 Conjuntos de datos en R

Varios conjuntos de datos tabulados o data sets se icluyen en la instalación de R (en el paquete datasets ) y por defecto se ecuentran cargados para su uso. la funcion data() lista todos los data sets de R.

str(Titanic)
##  'table' num [1:4, 1:2, 1:2, 1:2] 0 0 35 0 0 0 17 0 118 154 ...
##  - attr(*, "dimnames")=List of 4
##   ..$ Class   : chr [1:4] "1st" "2nd" "3rd" "Crew"
##   ..$ Sex     : chr [1:2] "Male" "Female"
##   ..$ Age     : chr [1:2] "Child" "Adult"
##   ..$ Survived: chr [1:2] "No" "Yes"
str(iris)
## 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
# names() muestra los nombres de las variables de un dataframe
names(iris)
## [1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"
# head() muestra las n (en este caso 4) primeras filas de un dataframe
head(iris, n = 4)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
summary(iris)
##   Sepal.Length    Sepal.Width     Petal.Length    Petal.Width   
##  Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
##  1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
##  Median :5.800   Median :3.000   Median :4.350   Median :1.300  
##  Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199  
##  3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
##  Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
##        Species  
##  setosa    :50  
##  versicolor:50  
##  virginica :50  
##                 
##                 
## 

3. Formatos de datos

3.1 Creación de bases de datos

edad     <- c(18,19,NA,18,24,17,22,15,22,25)
sexo     <- c(0,1,0,0,1,0,0,1,1,0)
estudios <- c(1,2,0,1,3,2,3,1,2,3)

En R (al menos en el paquete base) no es posible asignar etiquetas a los nombres de variable, por lo que conviene que dichos nombres sean muy claros. Para aclarar el significado de los valores de las variables categóricas (sexo y nivel de estudios) las convertimos en factores y asignamos etiquetas a sus valores mediante la función factor() :

sexo     <- factor(sexo, levels=c(0,1),labels=c("Hombre","Mujer"))
estudios <- factor(estudios, levels=c(0,1,2,3),
                  labels=c("Sin estudios","Primarios","Secundarios","Superiores"))
Data     <- data.frame(edad,sexo,estudios)
Data
##    edad   sexo     estudios
## 1    18 Hombre    Primarios
## 2    19  Mujer  Secundarios
## 3    NA Hombre Sin estudios
## 4    18 Hombre    Primarios
## 5    24  Mujer   Superiores
## 6    17 Hombre  Secundarios
## 7    22 Hombre   Superiores
## 8    15  Mujer    Primarios
## 9    22  Mujer  Secundarios
## 10   25 Hombre   Superiores
setwd("C:/Users/Administrador/Dropbox/UCARIBE/2021/CD/Datos estructurados") # directorio de trabajo
save(Data,file="Data1.rdata") # guardar los datos en formato R

write.csv(iris,file="Data2.csv",row.names=F, quote=F)
write.table(cars, file="Data3.txt") # función más general

library(xlsx)
write.xlsx(CO2, "CO2.xlsx")

3.2. Importar datos a R

Importar archivos en formatos “clasicos”.

# Formato .csv
Data1   <- read.table(file="Data2.csv",header=T, sep=",")
Data1_1 <- read.csv(file="Data2.csv",header=T, sep=",")

# Formato .txt

Data2   <- read.table(file="Data3.txt",header=T, sep=" ")


# Formato .xlsx
library(readxl)
CO2 <- read_excel("CO2.xlsx")
## Warning in strptime(x, format, tz = tz): unable to identify current timezone 'H':
## please set environment variable 'TZ'
## New names:
## * `` -> ...1

Importar archivos en formatos de otras plataformas.

library(foreign)
help(package=foreign)

 # ejemplo con formato SPSS.
Data4 <- read.spss("INEI.sav", to.data.frame = TRUE)
## re-encoding from UTF-8
## Warning in read.spss("INEI.sav", to.data.frame = TRUE): Undeclared level(s) 0
## added in variable: ocu200
Data4[1:5,1:5]
##           pano  pmes           conglome submuestra     vivienda
## 1 2012         Abril 017254              002       0056        
## 2 2012         Abril 017254              002       0054        
## 3 2012         Abril 017254              002       0054        
## 4 2012         Abril 017254              002       0056        
## 5 2012         Abril 017254              002       0056
 # ejemplo con formato Stata.
Data5<-read.dta("mundo.dta")
Data5[1:5,1:5]
##   numero       pais  conti          capital        moneda
## 1      1 Afganistan   asia            Kabul        Afgani
## 2      2    Albania europa           Tirana           Lek
## 3      3   Alemania europa           Berlin         Marco
## 4      4    Andorra europa Andorra la Viega Peseta-franco
## 5      5     Angola africa           Luanda  Nueva Kwanza
# ejemplo desde un sitio Web.
tabla.stata <- read.dta("https://stats.idre.ucla.edu/stat/data/test.dta")
tabla.stata 
##    make   model mpg weight price
## 1   AMC Concord  22   2930  4099
## 2   AMC   Pacer  17   3350  4749
## 3   AMC  Spirit  22   2640  3799
## 4 Buick Century  20   3250  4816
## 5 Buick Electra  15   4080  7827
 # ejemplo con formato SAS.
library(haven)
mtcars.sas <- read_sas("mtcars.sas")
head(mtcars.sas)
## # A tibble: 6 x 11
##     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1  21       6   160   110  3.9   2.62  16.5     0     1     4     4
## 2  21       6   160   110  3.9   2.88  17.0     0     1     4     4
## 3  22.8     4   108    93  3.85  2.32  18.6     1     1     4     1
## 4  21.4     6   258   110  3.08  3.22  19.4     1     0     3     1
## 5  18.7     8   360   175  3.15  3.44  17.0     0     0     3     2
## 6  18.1     6   225   105  2.76  3.46  20.2     1     0     3     1
# ejemplo con formato propio de R.
Data1 <-load("Data1.rdata")