#---------------------------------------------------------------#
## Leer los datos                                               ##

data <- read.csv("datatest1.csv", 
               sep=";", 
               dec=",", 
               na.strings=c(".", "NA", "", "?","#DIV/0!"), 
               strip.white=TRUE, 
               encoding="UTF-8")

data$clase=as.factor(data$clase) # es bueno transformar
                                    # valores discretos
                                    # desordenado
                                    # en factores

#---------------------------------------------------------------#
## información sobre los datos                                   ##
str(data)
dim(data)     # num línea, num columnas ... ou :
nrow(data)    # num línea
ncol(data)    # num de columna 
names(data)   # nomde las columnas


typeof(data$v1) # códigos reales en palabras dobles
# typeof: tipo de codificación interna,
# ¡No es su naturaleza R!
is.double(data$v1) # ¡confirmación!
is.numeric(data$v1) # también es cierto que es numérico
class(data$v1) # naturaleza de la variable
str(data$v1) # veamos estos 100 números

typeof(datos$clase) # entero (codificación interna)
is.integer(data$class) # invalidación! (no es de naturaleza entera)
is.numeric(data$class) # ¡invalidación!
is.character(data$clase)# ¡ningún char tampoco!
is.factor(data$clase) # ¡sí, estos son los factores!
class(data$class) # naturaleza de la variable
str(data$clase) # veamos estos 100 factores

anyNA(data) # comprobar si los datos no incluyen
#  valores desconocidos
table(is.na(data)) # tabla permite contar los FALSES
# y por lo tanto el número de NA


#---------------------------------------------------------------#
## manipulaciones básicas                                      ##
#---------------------------------------------------------------#

df <- data.frame(data)   # creación data frame
#---------------------------------------------------------------#
## las líneas                                                  ##
df[1,]                   # primera línea
d <- df[1,]    
is.data.frame(d)         # un data frame de una línea

df[10:20,]               # líneas 10 a 20 incluidas

#---------------------------------------------------------------#
## las columnas                                                ##

df[,1]            # columna 1
c <-  df[,1]   
is.vector(c) # es un vector que representa la columna

c <- data.frame(c)# transforma vector en dataframe
is.data.frame(c) # ¡funciona!

c <- df[,1:5]
is.data.frame(c) # ¡ahora es un dataframe de 5 columnas!


d <- df[4:6,3:5]
dim(d)
is.data.frame(d) # este es un dataframe de 3 líneas por 3 columnas


df$v1 # columna 1 vía nombre :v1
c <- df["v1"] # ahora es un dataframe
is.data.frame(c) # ¡funciona!

                  # para obtener 4 de las columnas
                  # fabrica un vector con los nombres 
v <-c("v1","v2","v3","clase")  
df_ <- df[,v]              # data frame de las 4 cols extraídas
names(df_)

#---------------------------------------------------------------#
summary(df_)               # estadísticas básica sobre df_

#---------------------------------------------------------------#
## filtrar las columnas con subset                            ##

df__ <- subset(df_, select = -2)       #  eliminar columna 2
names(df__)

df__ <- subset(df_, select = -c(1,2))  #  eliminar columnas 1 y 2
names(df__)

df__ <- subset(df_, select = -v1)      #  eliminar columna v1
names(df__)

df__ <- subset(df_, select = -c(v1))   # ídem  eliminar columna v1
names(df__)

df__ <- subset(df_, select = -c(v1,v2))#  eliminar col v1 y v2
names(df__)

df__ <- subset(df_, select = c(1,2))   # conservar columnas 1 y 2
names(df__)

df__ <- subset(df_, select = c(v1,v3)) # conservar columna v1 y v3
names(df__)

df__ <- subset(df_, select = v1:v3)    # conservar columna v1 a v3
names(df__)


#---------------------------------------------------------------#
## trabajos sobre una columna de factores                          ##
levels(df_$clase) # matriz de valores, ¡raro!
str(levels(df_$clase)) # un array de chr(factores)

unique(df$clase) # matriz de factores
str(unique(df$clase)) # obtenemos un array de factores

prop.table(table(df_$clase)) # proporción por factor
#---------------------------------------------------------------#
## algunos cálculos                                            ##

v <-c("v1","v2","v3") 
df_ <- df[,v] 

# funciones muy rápidas, no usar si hay NA
# porque la implementación es diferente según los sistemas
colSums(df_) # suma por columna (3 valores)
colMeans(df_) # promedio por columna (3 valores)
rowSums(df_) # suma por fila (100 valores)
rowMeans(df_) # promedio por fila (100 valores)

#---------------------------------------------------------------#
## aggregate ... group by                                      ##

v <-c("v1","v2","v3","clase")  
df_ <- df[,v]

if(require("estados")==FALSE) install.packages("estados")
require("estados")                            # estados básicos
library(help = "estados")                     # de la ayuda

a <- aggregate(.~clase, data = df_, mean) # data frame
                                            # media por clase
                                            # por columna num
a
dim(a)

#---------------------------------------------------------------#
## combinación de líneas                                       ##
a <- df_[1:5, ]      # extracción 5 primeras líneas
b <- df_[96:100, ]   # extracción 5 últimas líneas
c <- rbind(a,b)      # combinaciones de los 2 paquetes de líneas 
c
nrow(c)
names(c)
c[99,]
c["99",]

row.names(c) <- NULL

#---------------------------------------------------------------#
## filtrar  las líneas con subset                              ##

c <- subset(df_,clase == "1")  # sobre el valor de un factor
c
nrow(c)

c <- subset(df_, v1 <= 0)        # sobre el contenido de una var num
c
nrow(c)

c <- subset(df_, v1 <= 0 &
                 v2 <= 0 &
                clase != 2)    # o más complejo ...
c
nrow(c)

                                 # comparación con pop total
c <- subset(df_, v1 <= 0)
p_v1_neg      <- prop.table(table(c$clase))
p_ensemble    <- prop.table(table(df_$clase))
m <- as.table(rbind(p_v1_neg,p_ensemble))
m

                                # test de la chi-2
c_neg      <- subset(df_, v1 <= 0)
c_pos      <- subset(df_, v1 > 0)
v1_negatif <- table(c_neg$clase)
v1_negatif
v1_positif <- table(c_pos$clase)
v1_positif

m <- as.table(rbind(v1_negatif,
                    v1_positif)
              )
m

(Xsq <- chisq.test(m))

Xsq$expected

#---------------------------------------------------------------#
## transformación o adición de columnas para el cálculo  via within ##
## flexible  y potente                                       ##


c <- within(df_,                    # para cada línea hacer:
                {
                 v4 <- v1+v2+v3
         
                }
            )
c
names(c) 

#---------------------------------------------------------------#
##  demonstración de la potencia la within()                     ##

                                    # para el ejemplo
f <- function(x,y,z){round(log(x+y+10)/(abs(z)+1))}

c <- within(df_,                    # para cada línea hacer:
                {
                vd <- abs(v2-v1)   
                vr <- round((v1+v2)/vd)# super llamamos a vd
                                       # del mismo bucle
                var_global <<- v1+v2+v3   # evita crear una col
                vp <- f(v1,v2,var_global) # sin cierre aquí!  
                vd <- round(vd,2)
                }
            )
c
names(c)                            # añadimos 2 columnas

#---------------------------------------------------------------#
## transformación o adición de col para el cálculo  via transform    ##

c <- transform(df_, v1 = v1 + 10)         # transforma una col
c

c <- transform(df_, vs = v1 + log(v2+10), # 2 columnas
                    vd = v1 + v2 +10) 
c
 
                                          # sapply anonyme
c <- transform(df_, vs = sapply(v1,function(x){x+100}))     
c


                                         # test y opción
f <- function(x){round(x) %% 3}          # para el ejemplo

c <- transform(df_, vs = ifelse(f(v1)>f(v3),v1-v2,v3-v2))    
c

#---------------------------------------------------------------#

                                           # conteo fiable
                                           # función auxiliar
test <- function(clase,v1,v2){(clase ==1)&(v1>v2)}

c <- transform(df_,t = ifelse(test(clase,v1,v2),1,0))
c
sum(c$t)                                   # conteo

#---------------------------------------------------------------#
                                    
a <- aggregate(.~ t, data =c, mean)
a[,-5]                              # drop col 5

                                    # par clase y vs
a <- aggregate(.~ t+clase, data =c, mean)
a <- a[,-5]                        
a

#---------------------------------------------------------------#
# tri data.frame                                                #

order(c("a","b","d","c"))
order(c("a","b","d","c"), decreasing = TRUE)
order(c("a","b",NA,"d",NA,"c"), na.last = FALSE)

                                    # ordenar según col
b <- a[order(a$t, a$clase),]
b

                                    # por nombre de col
d <- b[,order(names(b),decreasing = TRUE)]
d

d <- d[,c(2,1,3,4)]                 # manualmente
d


#---------------------------------------------------------------#
## trabajos básicos sobre una variable numérica                 ##

#---------------------------------------------------------------#
## aparencia de la muestra                                     ##

dff <- subset(df, select = c(5,6,13))
              
n_col <- ncol(df)-1              # la última columna no es
                                 # numérica, es la clase

op <- par(mfrow = c(2,4))        # cada gráfico 
                                 # contiene  2 líneas
                                 # de        4 gráficos
for (i in 1:n_col){
  df_i <- dff[,i]
  nom <- names(dff)[i]
  plot(density(df_i),main = toupper(nom))
  hist(df_i, main = "Frecuencia por valor",
             xlab = paste("valores de",nom))
  cdplot(df_i,df$clase,main = "Densidad condicional",
                        xlab = paste("valores de",nom),
                        ylab = "valores de clase"
         ) 
  plot(df$clase,df_i, xlab = "valores de clase",
                       ylab = paste("valores de",nom), 
                       main ="Reparto")
  } 
rm(df_i)   # limpieza data.frame temporal
par(op)                          # IMPORTANTE restaura los
                                 # argumentos de presentación

#---------------------------------------------------------------#
## aspecto de la muestra scatterplot v X v                   ##
dff2 <- subset(df, select = c(5,6,7,13))
n_col <- ncol(dff2)-1
op <- par(mfrow = c(2,2))      

clase_ <- dff2$clase
for (i in 1:n_col){
  for (j in 1:n_col) {
    if (i<j ){   
      df_i <- dff2[,i]
      df_j <- dff2[,j]
      df_ijc <- data.frame(df_i,df_j,clase_)  # data.frame temporal
      names(df_ijc)<-c("axe_1","axe_2","clase")
      with(df_ijc,                        # para este data.frame hacer                          
         plot(axe_1,
              axe_2,            
              col=clase,               # color depende de clase
              pch=as.numeric(clase),   # símbolo depende de clase
              xlab = names(dff2)[i],      # los verdaderos nombres de los ejes
              ylab = names(dff2)[j] 
              )) 
      }
    }
  }
rm(df_ijc) # limpieza data.frame temporal
rm(df_i)   # limpieza data.frame temporal
rm(df_j)   # limpieza data.frame temporal
rm(clase_)# limpieza data.frame temporal
par(op)                         

## SI OBTIENE EL ERROR:
## Error en plot.new(): márgenes de figura demasiado grandes
## necesita aumentar mucho con su ratón
## ¡¡el tamaño de la ventana de visualización del plot
## o use la siguiente sugerencia antes del código:
par("mar") # comprobar opción
par(mar=c(1,1,1,1)) # adaptar la opción
#---------------------------------------------------------------#
## creación legenda naive - visualización de los símbolos y color ##

lib <- c("clase 0",
         "clase 1",
         "clase 2",
         "clase 3")
clase <- as.factor(0:3)
v      <- c(0,0,0,0)
w      <- 0:3
plot(v,
     w, 
     main = "Significado de los símbolos",
     xlab  ="",  # sin etiqueta aje x
     ylab  ="",  # sin etiqueta aje y
     xaxp = c(0, 1,1), # aje x de 0 ? 1 tick 1
     xaxt = "n", # sin aje x
     yaxt = "n", # sin aje y
     bty = "n",  # sin marco
     col=clase,               # color depende de clase
     pch=as.numeric(clase))   # símbolo depende de clase
# añade lib (con  posición y tamaño)
text(v-0.43,w+0.04,lib,cex = 0.8)  

#---------------------------------------------------------------#
## correlaciones entre variables numéricas                     ##

if(require("corrplot")==FALSE) install.packages("corrplot")
require(corrplot)

num_all <- c(names(df)[1:12]) # las 12 primeras variables


cor <-cor(df[num_all])
corrplot(cor, 
         title = "Correlación entre var numéricas",
         order = "AOE",
         method = "ellipse", 
         type = "lower", 
         tl.cex = 0.6 ) 


#---------------------------------------------------------------#
## una variable respecto a otras 2                         ##

## plot las clases en función de v1 y v2                    ##

with(df,                           
     plot(v1, v2,                   # ejes v1 y v2
          col=clase,               # color depende de clase
          pch=as.numeric(clase)))  # forma depende de clase

## separación de las clases en función de v5 y v6
if(require("ggplot2")==FALSE) install.packages("ggplot2")
require("ggplot2")            # libraría gráfica moderna
qplot(v5, v6, data=df, facets=clase ~.) 

## plot en 3D, manipulable con el ratón                         ##
if(require("rgl")==FALSE) install.packages("rgl")
require("rgl")            # para el 3D
open3d()                  # abre el canvas
plot3d(df$v3,df$v5,df$clase) # puntos (V3,v5,clase) en 3D
plot3d(df$v3,df$v5,df$v7)     # puntos (V1,v3,v7) en 3D

## gráficos por parejas
v <-c("v3","v5","v6","v7","v11","v12","clase")                ##
df_ <- df[,v]
require(fBasics, quietly=TRUE) # para llamada  basicas
                               # Estadísticas útiles
lapply( subset(df_, select = v3:v7), basicestados) 
# plot con un color por clase de origen 
plot(df_, col = df_$clase, 
     pch = as.numeric(df_$clase))



## BONUS regresión lineal v7 en función de v3 y v5       ##
model <- lm(v7 ~ v3+v5, data = df) # regresión v1=a.v3+b.v7+c
summary(model)            # resultados
m<-model$coefficients     # almacenar los coeficientes de reg
m
plot(model)               # análisis visual de la regresión

#---------------------------------------------------------------#

v <-c("v3","v5","v6","v7","v11","v12","clase")  
df_ <- df[,v]

require(fBasics, quietly=TRUE) # para llamadas basicas
                                            # Estadística útiles
lapply( subset(df_, select = v3:v7), basicestados) 

                    # plot con un color por clase de origen 
plot(df_, col = df_$clase, 
          pch = as.numeric(df_$clase))


#---------------------------------------------------------------#
## diagrama de cajas                                         ##

op <- par(mfrow=c(1,4))  # para meter las 4 cajas en la misma página
boxplot(df$v5 , main="v5" , collapse=" ") # cajas
boxplot(df$v5 , main="v6" , collapse=" ") # 
boxplot(df$v11, main="v11", collapse=" ") # 
boxplot(df$v12, main="v12", collapse=" ") # 

length(boxplot.estados(df$v5 )$out) # num de puntos impropios
length(boxplot.estados(df$v6 )$out)
length(boxplot.estados(df$v11)$out)
length(boxplot.estados(df$v12)$out)
par(op)

#---------------------------------------------------------------#
## eliminación de los puntos impropios                             ##

library(dplyr)      # librería de manipulación de datos
m <- min(boxplot.estados(df$v12)$out) 
df_bis <- filter(df, v12 <=m)       # filtar por dplyr

op <- par(mfrow=c(1,2))  # para meter las 2 cajas en una misma página
boxplot(df$v12,     main="v12 original", collapse=" ") #
boxplot(df_bis$v12, main="v12 sin puntos impropios", collapse=" ") 
par(op)


#---------------------------------------------------------------#
# nuevo diagrama por parejas sin puntos impropios                   #
v <-c("v3","v5","v6","v7","v11","v12","clase")  
df_ <- df_bis[,v]

require(fBasics, quietly=TRUE) # para llamadas básicas
# Estadísticas útiles
lapply( subset(df_, select = v3:v7), basicestados) 

# plot con un color por clase de origen 
plot(df_, col = df_$clase, 
     pch = as.numeric(df_$clase))

#---------------------------------------------------------------#
## código intermedio antes de continuar el capítulo    ##
#---------------------------------------------------------------#
set.seed(1)           # inicialización generador de num aleatorio
library(caret)        # añadimos una partición elegante
p          <- createDataPartition(y=df_$clase,
                                  p= 60/100,
                                  list=FALSE)
training   <- df_[p,]  
desconocido    <- df_[-p,]
q          <- createDataPartition(y=desconocido$clase,
                                  p= 50/100,
                                  list=FALSE)
test       <- desconocido[q,]
validation <- desconocido[-q,]


# tipos de variables y lista

categoria <- NULL
risk      <- NULL
id        <- NULL
ignore    <- NULL
weights   <- NULL
# 

#---------------------------------------------------------------#
# elección de las variables del data set 
X      <- c("v3", "v5", "v6", "v7")

y     <- "clase"                   # nuestro destino


#---------------------------------------------------------------#
##  Análisis de base de datos                                   ##
require(Hmisc, quietly=TRUE) # carga de las funciones útiles

contents(training[c(X, y)]) # tipos de variable
summary (training[c(X, y)]) # estadísticas básicas
str(training[c(X, y)])      # algunos valores
head(training[c(X, y)])     # primeras líneas
tail(training[c(X, y)])     # últimas líneas
describe(training[c(X, y)]) # otros estados

#------------------------------------------------- --------------#
## continuación de ejemplos del capítulo ##
#------------------------------------------------- --------------#
## esta parte es más detallada que el libro ##
## hay dos tipos de árboles de decisión ##
#------------------------------------------------- --------------#
## análisis a través de árboles de decisión ##
library(rpart)  # árbol de decisión
library(rattle) # para utilizar fancyRpartPlot
library(RColorBrewer)  # administrador de paleta de colores
library(caret)         # aporta una partición elegante
p          <- createDataPartition(y=df_$clase,
                                  p= 60/100,
                                  list=FALSE)
training   <- df_[p,]  
test       <- df_[-p,]

# elección de las variables del data set 
X      <- c("v3", "v5", "v6", "v7")
y     <- "clase"                   # nuestro destino

## formación árbol de decisión                              ##
d <- training[c(X, y)] # el data frame de entrenamiento

## prueba con los argumentos por defecto de rpart            ##
set.seed(1)           # inicialización generador de num aleatorio
model1 <- rpart(clase  ~ .  , 
               data = d)  # fitting
fancyRpartPlot(model1)     # designa el árbol de decisión
                           # muy sencillo 

predictions <- predict(model1,newdata = test)

## prueba con los argumentos para tener un árbol con más información    ##
model2 <- rpart(clase  ~ .  , 
               data = d,
               control=rpart.control(minsplit=1,cp=0)
               ) # fitting
fancyRpartPlot(model2)  # designa el árbol de decisión

#---------------------------------------------------------------#
## podemos variar cp, encontrar un óptimo, que ##
## usará para podar el árbol con la función "podar" ##
## modelo_optimo <- plum(modelo_maximo,cp=cp_optimo) ##

library(rpart) # árbol de decisiones
library(caret) # nos trae una partición elegante

# crear entrenamiento/prueba de partición
p          <- createDataPartition(y=df_$clase,
                                  p= 60/100,
                                  list=FALSE)
training   <- df_[p,]  
test       <- df_[-p,]

# elegir las variables del data set 
X     <- c("v3", "v5", "v6", "v7")
y     <- "clase"                   # nuestro destino

## constitución árbol de decisión                              ##
d <- training[c(X, y)] # el data frame de entrenamiento
model <-  rpart(clase  ~ .  , 
                data = d,
                control=rpart.control(minsplit=1,cp=0)
                ) # fitting

library(rpart.plot)       # para trazar el árbol
prp(model,extra=1)        # trazar el árbol

                          #  predecir en un juego de datos
predictions <-predict(model, test, type="class")

print(confusionMatrix(predictions,test$clase)) # verificar 
                                                # via matriz
                                                # de confusión


#---------------------------------------------------------------#
