#---------------------------------------------------------------#
## R una super calculadora                                      ##
rm(list = ls())


10*(1+1+1.5)  # = 35         # cálculos

10**2         # = 100        # cuadrado 
10^2          # idem

100**(1/2)    # = 10         # potencia
100^(1/2)     # idem

sqrt(100)     # = 10         # raíz   
pi            # = 3.1416     # pi  
cos(pi)       # = -1         # cos
sin(pi/2)     # = 1          # sin
exp(1)        # = 2.71882    # exponencial
log(1)        # = 0          # log neperiano

round(2.566)     # redondeo de un entero
round(pi,0)      # ídem 
round(pi,2)      # redondeo 2 cifras después de la ,

a <- 100
a
print(a)

v <- c(10,20,30)  # un vector
v
length(v)         # longitud del vector

length(a)
is.vector(a)

2*v+1 # en cada componente del vector
v**2 # cuadrado de cada componente
log(v) # log de cada componente

w <- c(1,2,3) # otro vector
v-w # restar miembro de miembro
v*w # multiplicar miembro a miembro
v/w # división miembro a miembro
v%*%w # producto escalar

sum(v) # = 60 suma
mean(v) # = 20 media
min(v) # = 10 mín
max(v) # = 30 máx.
sd(v) # = 10 desviación estándar
median(v) # = 20 mediana
u <- c(1,2,3,4,5,6,7,8) # otro vector
u[2]                    # segundo componente

u[3:5]                  # nuevo vector
                        # los componentes 3 a 5

u[8] <- 80              # asignación de un componente
u

u[1:5] <- 1             # asignación 5 componentes           
u

#---------------------------------------------------------------#
# funciones interesantes sobre los vectores                       #

v <- c(10,20,30,30,60,50)      # un vector
w <- c(20,10,31,31,61,51)      # otro vector
u <- c(5 ,5 ,5 ,32,62,49)      # otro vector

str(v)                      # echar un vistazo a los datos
sum(is.na(v))                     # número de valores ausentes
v_ <- c(NA,v,NA,NA)                   # un vector con 3 valores ausentes
v_
sum(is.na(v_))                   # num valores ausentes


range(v)                   # min y max del vector
range(v_)                   # min y max del vector ¡FALLO!
range(v_ , na.rm = TRUE)                   # ignorando los NA

quantile(v)                        # cuartiles de v
quantile(v, probs =c(0,0.1,0.9,1)) # 80/20

summary(v)                     # resumen
sd(v, na.rm = TRUE)            # desviación típica

cor(v,w) # coef correlación entre vectores

sort(v)                   # clasificación vectorial en orden ascendente
order(v, decreasing = VERDADERO)                   # vector ordenar orden descendente
order(w)                   # dar puntero ordenado en elementos

rank(w, ties.method="min") # vector de rangos
# de valores base más pequeños=1
# "min": estilo completo. deporte

rank(w, ties.method="max") # vector de rangos
# de valores base más pequeños=1
# "min": data-sciences


pmax(v,w,u)                    # valores max miembro a miembro
pmin(v,w,u)                    # valores min miembro a miembro

cumsum(v)                      # sumas acumuladas
cumprod(v)                     # productos sucesivos

cummax(w)                      # máximo entre miembro 
                               #  miembros precedentes
cummin(w)                      # ídem con min



#---------------------------------------------------------------#
# booleanos - logicos                                            #

a <- 1
b <- 2

(a == 1)                       # TRUE
(a == b)                       # FALSE
(a <= b)                       # TRUE

A <- c(TRUE,TRUE,FALSE,FALSE)
B <- c(TRUE,FALSE,TRUE,FALSE)
A & B                          # tabla de verdad de "y"
A | B                          # tabla de verdad de "o"
! A                            # no-A
xor(A,B)                       # tabla verdad o exclusivo
!A|B                           # tabla de la implicación A==>B

str(A)                         # vector compuesto logico

c <- (a > b)                          # almacenar el resultado de una prueba
c

v <- c(10,20,30,30,60,50)                          # un vector
t <- (v > 30)                          # vector resultante de la prueba
t                          # miembro a miembro

w <- v[(v>30)]                          # conservamos solo los miembros
# con expresión TRU
w

which(v == 30)                      # encontrar los índices o
# miembro igual a 30

which(v == max(v))                      # encontrar índices o
# miembro es igual a val max miembro

which(v == min(v))                      # igual pero encuentra min

s <- 1*t                      # transformación a vector 1.0
s

v <- c(10,20,70,30,60,50)                      # un vector
all(v > 5)                      # ? todos los valores son mayores que 5
any(v < 5)                      # ? un valor menor que 5

#---------------------------------------------------------------#
# conjunto                                                      #

H <- unique(c("e","g","g","h","h","h"))
H

P <- c("e","f","g","h")
Q <- c("g","h","i","j")
union(P,Q)
intersect(P,Q)
setdiff(P,Q)
setdiff(Q,P)
union(setdiff(P,Q),setdiff(Q,P))

H
P
H %in% P
P %in% H
which(P %in% H)

#---------------------------------------------------------------#
# listas                                                        #

l <- list (nom  = "Dupond",  # lista clave-valor
           age  = 25,     
           vect = v)
l$nom                        # valores
l$age
l$vect

l[[1]]                       # por índice
l[[2]]
l[[3]]

is.vector(l[[3]])            # es un vector
l[[3]][2]                    # su segundo elemento

#---------------------------------------------------------------#
# factores                                                       #

coul <- factor(c("azul","verde",
                 "rojo","azul","verde")) # factor sin orden
coul
str(coul)         # muestra los niveles y su índice
color[2]         # verde
niveles(col)         # los niveles

t <- (coul[2] == "verde")         # prueba si es verde
usted

which(coul == "verde")         # índice si verde
which(coul != "verde")         # índice si no es verde

# dividir una serie en factores #
set.seed(0)         # inicialización aleatoria
v <- c(rnorm(100))         # vector de prueba de creación
cadena (v) #
range(v)         # min y max de v
resumen(v)         # resumen
sd(v, na.rm = TRUE)         # desviación típica

hist(v) # distribución obtenida
                      # separación en cuartiles
w <- cut(v, breaks = quantile(v), labels = FALSE)
w

table(w)                   # reparto efectivos
sum(table(w)) == length(w) # diferentes

which(is.na(w))       # oups valor desconocido
w[59]
v[59]                 # uno de los límites

Position(is.na,w)     # una alternativa da la primera pos

                      # vuelve a fundoir los límites 
limites <- c(quantile(v)[1]- 0.0001*abs(min(v)),
            quantile(v)[2],
            quantile(v)[3],
            quantile(v)[4],
            quantile(v)[5]+ 0.0001*abs(max(v))
            )
limites
w <- cut(v, breaks = limites, labels =c("Q1","Q2","Q3","Q4"))
w           
which(is.na(w))
w[59]
v[59] 
                            # verificación de las clases
which(w == "Q1")            # índices de los Q1
v[which(w == "Q1")]         # valor original de los Q1

quantile(v)                 # recordar
range(v[which(w == "Q1")])  # Q1 
range(v[which(w == "Q2")])
range(v[which(w == "Q3")])
range(v[which(w == "Q4")])


#---------------------------------------------------------------#
#  con orden                                                   #

orden <- factor(c("pequenio","medio","grande"),
                ordered=TRUE,         # creación orden
                ) 
orden


orden <- factor(c("0_pequenio","1_medio","2_grande"),
                ordered=TRUE,         # creación orden
                )  
orden

orden[1] < orden[2]               # TRUE


#---------------------------------------------------------------#
# matrices                                                      #

o <- c( 1,1,1,111,   # un vector de observaciones
        1,1,2,112,
        1,1,3,113,
        1,2,1,121,
        1,2,2,122,
        1,2,3,123,
        2,1,1,211,
        2,1,2,212,
        2,1,3,213,
        2,2,1,221,
        2,2,2,222,
        2,2,3,223
       )

m <- matrix(byrow = TRUE,        # la matriz correspondiente
            nrow  = length(o)/4,
            o)

m

m[2,4] # celda línea 2, col 4
m[2,]  # línea 2
m[,4]  # valores transpuestos de la col 4
matrix(m[,4])  # columna 4

                                 # cubo olap
cube <- xtabs( V4 ~ V1 + V2 + V3, data = m)
cube
dim(cube)
cube[1,2,3]  # línea 1, col 2, profundidad 3
cube[,,1]    # rango de profundidad = 1
cube[,,2]    # rango de profundidad = 2
cube[,,3]    # rango de profundidad = 3

cube[,1,]    # rango de col = 1
cube[,2,]    # rango de col = 2

cube[1,,]    # rango de ln = 1
cube[2,,]    # rango de ln = 2

cube[1,1,]   # intersección ln=1,col=1

is.matrix(cube[1,,]) # coherencia matriz array
dim(cube[1,,])       # respeta dimensiones

sum(cube[,,])        # suma todos los valores

apply(cube,1,sum)  # suma segunda y tercera dim
sum(cube[1,,])     # suma todo ln = 1
sum(cube[2,,])     # suma todo ln = 2

apply(cube,3,sum)  # suma primera y segunda dim
sum(cube[,1,])     # suma todo col = 1
sum(cube[,2,])     # suma todo col = 2

apply(cube,3,sum)  # suma primera y segunda dim
sum(cube[,,1])     # suma todo profundidad = 1
sum(cube[,,2])     # suma todo profundidad = 2
sum(cube[,,3])     # suma todo profundidad = 3

apply(cube,c(1,2),sum) # suma de la tercera dim
sum(cube[1,1,])
sum(cube[1,2,])
sum(cube[2,1,])
sum(cube[2,2,])

apply(cube,c(1,3),sum) # suma de la segunda dim
apply(cube,c(2,3),sum) # suma de la primera dim


apply(cube,c(1,2,3),sum) == cube  # suma de nada

apply(cube,c(1,2), max) # max de la tercera dim
apply(cube,1, min) # min de segunda y tercera dim



#---------------------------------------------------------------#
# tablas de verdad                                              #


x <- c(NA, FALSE, TRUE)                 # nuestro ejemplo
x 
names(x) <- c("Desconocido","Falso","Verdadero")  # añadimo nombres de col
x
outer(x, x, "&")                        # tabla de verdad

#---------------------------------------------------------------#
# pruebas                                                        #

tabla_v <- expand.grid(0:1,0:1,0:1,0:1)
tabla_v
nrow(tabla_v)

num<- apply(tabla_v,1,sum)
num

(num ==2)

sum(num==2)

sum(num==2)/nrow(tabla_v)

f <- function(x){sum(num==x)/nrow(tabla_v)}
res <- sapply(0:4,f)
names(res) <- as.character(0:4)
res
sum(res)

array(1:8, c(2,4)) # crear una tabla 

#---------------------------------------------------------------#
# funciones básicas                                           #

f <- function(x){x*1.1}          # función simple
f(100)
f(x = 10)                        # podemos indicar los nombres de
                                 # variables

f <- function(x = 1){x*1.1}      # f  con x por defecto
f()                              # f(1)                  

#---------------------------------------------------------------#
v <- c(1,2,3,4,5)
sapply(v,f)                      # aplicar f de los miembros
                                 # de v 

#---------------------------------------------------------------#
# demostración eficaz, contar lugar el num de duplicados   #
x <- c(10,25,4,10,9,9)
y <- sapply(x,function(z){sum((x==z))})
y

#---------------------------------------------------------------#
g <- function(x,y){ a <- 10^x    # función de 2 variables
                    b <- 10^y
                    (b-a)/(b+a)}
g(1,1)
g(1,1.5)
g(1.5,1.5)


#---------------------------------------------------------------#
# operadores                                                    #

`%g_op%`    <- g                  # un operador 
1 %g_op% 1                        # idem g(1,1)
1 %g_op% 1.5                      # idem g(1,1.5)

v <- c(1, 1  ,1 ,1.5, 1.5, 1.5)
w <- c(1, 1.5,1 ,1.5, 1,   1.5)
v %g_op% w                        # operador vectorizable


#---------------------------------------------------------------#
## función y ámbito de las variables                            ##

rm(list =ls()) # esta instrucción vacía el entorno
# normalmente es útil

#---------------------------------------------------------------#
f <- function(){
  100
  }
f()            # devuelve el último valor


f <- function(){
  return(200) # la función termina aquí
  return(300) # 
  100         # 
  }
f()              # devuelve 200

#---------------------------------------------------------------#
f <- function(x = 100){
  y <- x + 1
  y
  }
f()            # utiliza el valor por defecto
f(200)         # suma 1

y <- 300       # 
f(y)           # suma 1
y              # y permanece intacto


#---------------------------------------------------------------#
f <- function(x = 100){ # ¡¡no revisar el valor!!
  x <<- x + 1 # aviso <<-
}
f() # no hace nada?
f(200) # no hace nada?

y<-300#
f(y) # no hace nada?
y # y está intacto

x # ahora existe una variable global x
# y es 301
#---------------------------------------------------------------#
rm(list =ls()) # esta instrucción vuelca el entorno

f <- function(x = 100){
  y <<- x - 1 # aviso <<-
  z <- x + 1
  z # esta z es local
}

año <- 300
z <- 400
f(z) # añadir 1
y # y es 399: ¡cuidado!
z#z está intacto

z <- f(z) # para aplicar desde z
z#z es 401

z <- c(10,100,1000)
z <- f(z)      # para aplicar desde z
z

# Fabricación de un cubo 
o <- c( 1,1,1,111,
        1,1,2,112,
        1,1,3,113,
        1,2,1,121,
        1,2,2,122,
        1,2,3,123,
        2,1,1,211,
        2,1,2,212,
        2,1,3,213,
        2,2,1,221,
        2,2,2,222,
        2,2,3,223
)

m <- matrix(byrow = TRUE,        # la matriz correspondiente
            nrow  = length(o)/4,
            o)
cube <- xtabs( V4 ~ V1 + V2 + V3, data = m)

cube <- f(cube)                  # de nuestro cubo 
cube

cube <- 2 * cube + 1             # es suficiente con hacer esto
cube

cube <- xtabs( V4 ~ V1 + V2 + V3, data = m)
isImpair <- function(n){as.logical(n%%2)}
isImpair(cube)                   # sin el resultado deseado
cube_imp <- apply(cube,c(1,2,3),isImpair)
cube_imp

#---------------------------------------------------------------#
# aplicación de funciones matriciales con apply #

m <- matrix(1:12,nfila=3)
metro

# Aplicación de una función de cada término
h <- apply(m,c(1,2),exp) # aplicación exponencial en todas partes
print(h) # c(1,2) significa desde la línea y
# columna

# suma de cada línea
h <- matrix(apply(m,1,sum)) # vector-columna, suma por línea
print(h) # "1" significa "por línea"

# suma cada columna
h <- aperm(matrix(apply(m,2,sum)), # línea-vector
           c(2,1)) # transponemos la
# dimensión 2 y 1
# con suma por columna
# "2" significa "por columna"
print(h)

# aplicación de una función lambda sobre cada término
# ejemplo, transformar en 1 siempre que el valor sea >=3, 0 de lo contrario

h <- apply(m, c(1.2), function(x) {
  ifelse(x>=3,1,0)
})
print(h)

#---------------------------------------------------------------#
# más con las funciones #


# acceso explícito a una variable global #
rm(x) # destrucción de x

f <- function() { get( "x" ) # acceso explícito
  x+1
}

f() # error
X <- 10
f() # función
#---------------------------------------------------------------#
# funciones anónimas                                            #

(function(x) 2*x+1)(100)
(function(x,y) {c(x+y,x*y,x-y,x/y)})(1,2)

v <- c(10,21,30)
sapply(v,(function(x){as.logical(x%%2)}))

f <- function(x,y){x+y}
z <- 100
sapply(v,(function(x) f(x,z))) # sapply función 2 variables
sapply(v,f(x,z))               # porque esto no funciona


x <- c(10,25,4,10,9,9)
y <- sapply(x,function(z){sum((x==z))})
y

#---------------------------------------------------------------#
# acceder al código de la función                                #

f <- function(x=0) {x^2}
body(f)

f(2)
body(f) <- quote(x^3)
body(f)
f(2)
              # estudiar una función
args(sapply)  # argumentos
body(sapply)  # cuerpo

#---------------------------------------------------------------#
# funciones que devuelven otras funciones                         #

f <- function(n){ 
                g <- function(z) {summary(z)}
                h <- function(z) {sd(z)}
                k <- function(z) {range(z)}
                l <- list(k,g,h)
                l[[(n%%3)+1]]
                }

v <- c(1,2,3,4)
f(1)(v)         # resumen
f(2)(v)         # desviación típica
f(3)(v)         # min y max

#---------------------------------------------------------------#
# paso función como argumento                               #

v_ <- function(f) {f(v)} #dualizar 
v_(function(x) {2*x})
v_(mean)

second_degre <- function(f,a,b,c,x){a*f(x)^2+b*f(x)+c}
second_degre(cos,2,0,-1,v)          # 2 cos(x)**2 - 1  =
cos(2*v)                            # cos(2x)

#---------------------------------------------------------------#
## estructuras de control                                      ##

x <- 20                              # variable test
if (x < 10) {print("x < 10")}   else 
            {print ("x >= 10")}


for (x in c(1,10,20)) {print(2*x)}   # bucle for de secuencia

s <- seq(from= 1,to= 20,by = 4)      # fabrica une secuencia
s

for (x in s) {print (x)}             # bucle de la secuencia

l <- list("tres","dos","uno")       # lists 
while (length(l) > 0) {              # hacer mientras:
  print(l[[length(l)]])
  l[[length(l)]] <- NULL             # vacía una posición
  }                                  # fin de depil
length(l)

l <- list()
repeat {                             # 999 primeros límites
  i <- max(length(l),0)
  l[[length(l)+1]] <- i^2 
  if (length(l) >= 1000) {break}     # repeat until break 
  }
head(l)                              # los 6 primeros                       
tail(l)                              # los 6 últimos

                                     # ídem pero más  R
l <- as.list(seq(from  =1, to = 999)^2)
tail(l)


#---------------------------------------------------------------#
# bucle de una matriz y devuelve posiciones que se ajustan     #

check_matrice <- function(mat,valor = TRUE){  
  k <- 0
  x <- vector()
  y <- vector()
  for (i in 1:nrow(mat)){
    for (j in 1:ncol(mat)){
      if (mat[i,j] == valor){
        k <- k+1
        x[k] <- i
        y[k] <- j
        }
      }
    }
  xy <- matrix(rbind(x,y),nrow = 2)
  }

m <- matrix(1:12,nrow = 3)
m

(m > 5)

c <- check_matrice((m>5))
c

for ( k in 1:ncol(c)) {
  cat(k,"nésimo valor > 5 : ",m[c[1,k],c[2,k]],"\n")
  }

(function(k)(m[c[1,k],c[2,k]]))(3)

sapply(1:ncol(c),(function(k)(m[c[1,k],c[2,k]])))


#---------------------------------------------------------------#
# bases de la gestión de las cadenas de caracteres                 #

paste("el","es","bonito")          # pega con espacio
paste0("g","a","t","o")           # pega sin espacio

r <- list("un","pequeño","gato")    # una lista de palabras
str(r)
paste(r,collapse ="-")       # pega elementos de la lista con guión

r <- c("p","e","r","r","o")  
str(r)
paste(r,collapse ="")        # pega elementos de vector sin espacio  
 
substr("un pequeño gato",4,8)   # extracción subcadena de caracteres

strsplit("un pequeño gato"," ") # devide cadena con blancos
strsplit("un pequeño gato"," ")[[1]][2]

t <- c("un pequeño gato","un pequenio perro")
strsplit(t," ")

strsplit("un pequeño gato","t") # separa cadena usando las "t"

sub("peque;o","grande","un pequeño gato") # sustituye cadena 

chartr("H.","Mr...","H. Laude") #sustituye un número de caracters
chartr("H.","           ","H. Laude")

grep("pequenio",t)
grep("chat" ,t)


tolower("UN gran DÍA")        # pasa a minúsculas
toupper("UN gran DÍA")        # pasa a mayúsculas

toupper("& # $ ? ??????+} \132 \n \" ") 

gsub("[a/e/i]","_","un pequeño gato") # sustitución via expresión
                                    # regular

#---------------------------------------------------------------#
# eliminación naive de las URL                                     # 

f_sup_url <- function(es){ # suprimir URL
  t <- unlist(strsplit(s," ")) # dividir en palabras
  l <- length(t) # l es el número de palabras
  # i = índice de palabras que son URL
  i <- grep("(http://|https://|www.//|ftp://)",t) #regex
  
  if (longitud(i)>0){ # si hay una URL
    j <- setdiff(1:l,i) # todos los índices excepto i
    s <- t[(j)] # mantener lo que no está en una URL
    s <- paste(s,collapse =" ") # recomponer la cadena  } 
  s 
} 

#---------------------------------------------------------------# 
# eliminación naive de las URL - test                              # 

t1 <- "bla bla http://t.co/Orl2YyU7xv ftp://x.us fin" 
t2 <- "bla bla https://www.bidule.fr http://truc/eee.com?x=27" 
t3 <- "https://t.co/v1cAvs2" 
t4 <- "il n'y a pas d'url" 

print(f_sup_url(t1)) 
print(f_sup_url(t2)) 
print(f_sup_url(t3)) 
print(f_sup_url(t4))

#---------------------------------------------------------------#
# formatear números antes de editar, por ejemplo #

w <- v*pi # para tener comas!
w
w1 <- format(w) # convertir a carácter
w1

w2 <- format(w, digits = 2) # igual con 2 dígitos
w2

as.numeric(w1)-as.numeric(w2) # estos ya no son los mismos valores

format(w, nsmall = 10) # 10 después de la coma
format(w, digits = 1) # round (no trunc)



#---------------------------------------------------------------#
# fechas y horas

d <- as.Date("01/01-2016","%d/%m-%y") # decodificar una fecha
D
str(d) # es una fecha

d+366 # suma 366 días

Sys.Date() # fecha actual de nuestra máquina

format(Sys.Date(), "%a %d %b") # formato de fecha

? strptime # ¡Veamos las opciones!

Sys.time() # hora del sistema de la máquina
#---------------------------------------------------------------#
# Bench comparativo sapply y bucle for                         #

f <- function(x){x^3+x^2+1/(x+10)} # una función

x_ <- vector()                # init eje x
big <- vector()                 # init gran vector para procesar
big2 <- vector()                 # init gran vector para procesar
y1_ <- vector()                 # eje y inicial para la curva 1
y2_ <- vector()                 # eje y inicial para la curva 2
for (j in 1:10) {
  n <- 50000 *(j^2 * round(log(j+1))+1) # brecha creciente de n
  x_[j] <- n # esta iteración de j
  # está hecho de n líneas
  
  set.seed(1789) # iniciar generador aleatorio
  big <- runif(n) # big: n valores aleatorios
  t_ <- Sys.time() # t al inicio
  
  big2 <- sapply(big,f) # aplica f de big
  
  d_ <- Tiempo sist.() - t_ # t fin
  y1_[j] <- d_ # memo t final para iter j

  set.seed(1789)
  big   <- runif(n)
  t_    <- Sys.time()
  
  for (i in 1:n ) {big2[i] <- f(big[i])}
  
  d_    <- Sys.time() - t_
  y2_[j] <- d_
  }

#---------------------------------------------------------------#
# almacenar el resultado

bench_sapply <- cbind(x_,y1_) # j líneas n, tiempo delta
bench_for <- cbind(x_,y2_) # j líneas n, tiempo delta


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

# trazar el resultado

op <- par()                     # almacena el diseño del valor antiguo
# plots y parámetros generales
par(mfrow = c(1,2))                     # diseñar 2 plots de 1 línea
# plots simples no muy bonitos
plot(bench_sapply,
     xlab = "número de líneas",
     ylab="tiempo de ejecución para sapply")
plot(bench_for,
     xlab = "número de líneas",
     ylab="tiempo de ejecución para bucle for")
par(op)                     # importante! reiniciado por()!

#---------------------------------------------------------------#
# mejora de los plots                                        #

? par                              # parametros de plot
? points                           # parametros de plot

plot(rbind(bench_sapply,bench_for),   # marco vacío a escala
     type = "n",                      # no dibujamos nada
     xlab = "número de líneas (0 - 10 millions)",
     ylab = "tiempo en segundos",
     cex.axis = 0.8,               # caract ejes más pequeños
     las  = 2)                     # escritura  perpendicular  a los ajes

                                   # curva sapply, después puntos
lines(bench_sapply, type ="l",lwd=1,col = "blue")
lines(bench_sapply, type ="b",lwd=1,col = "blue"
                             ,pch = 1,cex =0.5)
                                   # curva for, despues puntos
lines(bench_for, type ="l",lwd=1,col = "red")
lines(bench_for, type ="b",lwd=1,col = "red"
                          ,pch = 4,cex =0.5)

leyenda("topleft", # una leyenda en la parte superior izquierda
        leyenda=c("sapply","for"),# leyenda
        lty=1, # línea continua
        lwd=1, # línea delgada
        pch=c(1,4), # tipo de símbolo
        col=c("azul","rojo"),
        ncol=2, # leyenda de 2 columnas
        bty="n", # sin marco
        cex=0.8, # escribe mas pequeño
        texto.col=c("azul","rojo"),
        recuadro = 0.01) # posicionamiento de la leyenda

#---------------------------------------------------------------#
# números complejos                                             #

z <- 4 + 3i # un número complejo
Mod(z) # longitud de z
Re(z) # la parte real
Im(z) # la parte imaginaria

z1 <- 1 + 1i
Arg(z1)*180/pi # ángulo en grados
Arg(z1) # ángulo en radianes (argumento)


#---------------------------------------------------------------#
# visualizar números complejos #

# una función de visualización
plot_complex <- función(v){
  mr <- max(abs(Re(v))) # max del eje horizontal abs (Re)
  mi <- max(abs(Im(v))) # max del eje verde abs (Im)
  
  w1 <- c(-mr,-mi) # cálculo 2 pts gráfico extremo
  w2 <- c(mr, mi)
  w <- rbind(w1,w2) # convertirlo en una pestaña con 2 líneas
  
  t <- paste(as.character(v),
             "/longitud",
             as.character(round(Mod(v),3)),
             "/ángulo",
             as.character( round(Arg(v)*180/pi)),
             "?"
             )

  plot(w,                     # plot marco invible puntos extrm
       type ="n", 
       bty ="n",
       xlab="1 -> Re(z)",
       ylab="i -> Im(z)"
       )
  abline(v=0, lty = 4)        # ajes centrales punteados
  abline(h=0, lty = 4)

  for (i in 1:length(v)) {    # línea+punto para cada complejo
    lines(c(0,v[i]),type ="l", asp = 1)
    lines(c(v[i])  ,type ="p", asp = 1)
    text(c(v[i]),labels =t[i], pos = 2,offset=0.5,cex=0.7)
    }
  }

z2 <- -1 - 1i
z3 <- -1 + 2i

plot_complex(z)               # primer  intento de z
plot_complex(z2)              # segundo intento de z2

v <- c(z,z1,z2,z3)            # varios complejos
plot_complex(v)


#---------------------------------------------------------------#
## BONUS                                                       ##
#---------------------------------------------------------------#
# encontrar ayuda #

? mean # ayuda de la función mean()

?? base::mean # busca auxiliares con la palabra
# mean en el paquete base

help.search("mean") # significa en todos los paquetes
RSiteSearch("media") # buscar http://search.r-project.org
RSiteSearch("covarianza media") # media Y covarianza

#------------------------------------------------- --------------#
# gestión de la memoria #

longitud (l)
ls() # lista de variables
rm(l) # eliminar variable l
I
rm(lista = ls()) # eliminar todas las variables
ls() # de hecho

#------------------------------------------------- --------------#
# pruebas unitarias integradas                                   # 

a <- 1
b <- 2
stopifnot(a == 1, b==3 )



#---------------------------------------------------------------#
# paso por valor y no por referencia                       #

a <- 1                             
b <- a                        # copia de a en b
a <- 2                      
b                             # comportamiento diferente de py

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

