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.
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:
una tercera parte de las empresas obtienen “muy pocos resultados tangibles” de sus datos.
Menos del \(0.5\%\) de los datos producidos mundialmente se analizan y utilizan.
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.
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.
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
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
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
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
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
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
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
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
##
##
##
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")
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")