Una aseguradora está evaluando la prima anual de un seguro de vida individual. Para simplificar, se utilizará un modelo aproximado donde:
La información del cliente es:
Instrucciones
nombre <- "María"
edad <- 47
suma_asegurada <- 1200000
anios_cliente <- 8
reclamaciones <- 1
fumador <- FALSE
class(nombre)
## [1] "character"
class(edad)
## [1] "numeric"
class(suma_asegurada)
## [1] "numeric"
class(anios_cliente)
## [1] "numeric"
class(reclamaciones)
## [1] "numeric"
class(fumador)
## [1] "logical"
perfil_alto_riesgo que
indique si la persona asegurada presenta al menos dos condiciones de
riesgo. Consideramos condiciones de riesgo una edad mayor a 45 años, ser
fumador, y haber presentado reclamaciones médicas previas.edad > 45
## [1] TRUE
isTRUE(fumador)
## [1] FALSE
reclamaciones > 0
## [1] TRUE
perfil_alto_riesgo <- (edad>45)|isTRUE(fumador)|(reclamaciones>0)
perfil_alto_riesgo
## [1] TRUE
perfil_alto_riesgo <- ((edad > 45) + fumador + (reclamaciones > 0)) >= 2
perfil_alto_riesgo
## [1] TRUE
prima_base <- 0.02 * suma_asegurada
recargo <- perfil_alto_riesgo * 0.10
class(perfil_alto_riesgo)
## [1] "logical"
descuento <- (anios_cliente > 5) * 0.03
prima_final <- prima_base * (1 + recargo - descuento)
prima_base
## [1] 24000
recargo
## [1] 0.1
descuento
## [1] 0.03
prima_final
## [1] 25680
Una pregunta que puede surgir es, ¿por qué no hacemos…
prima_base * (1 + recargo) * (1 - descuento) ?
Revisemos el impacto del descuento sobre la prima base si hiciéramos eso.
prima_base <- 0.02 * suma_asegurada
prima_final <- prima_base * (1 + recargo) * (1 - descuento)
descuento_neto <- (prima_base*(1+recargo)) - prima_final
# ¿Qué tan grande es el efecto del descuento respecto a la prima original?
descuento_neto/prima_base*100
## [1] 3.3
En el esquema multiplicativo, el descuento se aplica sobre una prima ya incrementada por el recargo, generando así una tasa efectiva de descuento ligeramente mayor al 3%. Dado que tanto el recargo como el descuento deben aplicarse sobre la prima base, utilizamos un modelo lineal.
prima_base <- 0.02 * suma_asegurada
prima_final <- prima_base * (1 + recargo - descuento)
descuento_neto <- (prima_base*(1+recargo)) - prima_final
descuento_neto/prima_base*100
## [1] 3
En R, toda la información se almacena en objetos. Dependiendo de cómo estén organizados los datos, estos objetos pueden adoptar distintas estructuras. Existen cuatro estructuras principales en R:
Comenzaremos con la estructura más básica y fundamental en R: los vectores.
Un vector en R es una colección ordenada de datos. Esta estructura almacena una secuencia de elementos del mismo tipo, es decir, los vectores pueden tener elementos numéricos, carácteres, lógicos, etc.
Para crear un vector se utiliza la función c() que puede
tener un número arbitrario de datos.
En R, los vectores permiten guardar conjuntos de valores numéricos y hacer operaciones con todos ellos al mismo tiempo.
En cálculo actuarial, por ejemplo, si las probabilidades de que una persona de edad x sobreviva k años se almacenan en un vector, la esperanza de vida discreta puede obtenerse simplemente sumando esos valores. Así, los vectores facilitan hacer cálculos actuariales de forma directa y ordenada, sin tener que trabajar elemento por elemento.
Tipo y Clase: En R, los vectores son atómicos por definición: esto significa que todas sus entradas deben ser del mismo tipo de dato (logical, numeric, character, etc.).
Cuando intentamos combinar distintos tipos de datos en un mismo vector, R aplica coerción implícita para convertir todos los elementos al tipo más general en la jerarquía logical → numeric → character.
vector1 <- c(1,2,3,4,5)
class(vector1)
## [1] "numeric"
is.vector(vector1)
## [1] TRUE
is.numeric(vector1)
## [1] TRUE
vector2 <- c(1,2,"hola",4,5)
class(vector2)
## [1] "character"
is.character(vector2)
## [1] TRUE
# predomina el tipo de dato character por la coercion implícita
edades <- c(20,25,28,39,"8s",24)
mean(edades)
## Warning in mean.default(edades): argument is not numeric or logical: returning
## NA
## [1] NA
class(edades)
## [1] "character"
Largo: Es el número de elementos que contiene un vector. Es la única dimensión que tiene un vector. Para calcular el largo se utiliza la función lenght()
length(vector1)
## [1] 5
length(edades)
## [1] 6
Los vectores pueden usarse para realizar operaciones aritméticas. Estas operaciones se realizan elemento a elemento.
vector3 <- c(1,3,5,7,9)
vector4 <- c(2,4,6,8,10)
# Suma
vector_suma <- vector3 + vector4
vector_suma #autoprint
## [1] 3 7 11 15 19
print(vector_suma)
## [1] 3 7 11 15 19
# Resta
vector_resta <- vector3 - vector4
print(vector_resta)
## [1] -1 -1 -1 -1 -1
# Producto
vector_producto <- vector3 * vector4
print(vector_producto)
## [1] 2 12 30 56 90
# División
vector_division <- vector3 / vector4
print(vector_division)
## [1] 0.5000000 0.7500000 0.8333333 0.8750000 0.9000000
# Potencia
vector_potencia <- vector3 ^ vector4
print(vector_potencia)
## [1] 1 81 15625 5764801 3486784401
¿Qué ocurre cuando aplicamos operadores entre vectores de distinta longitud?
x <- c(1,1,1,1,1)
x
## [1] 1 1 1 1 1
y <- 2:4
length(y)
## [1] 3
y
## [1] 2 3 4
x * y
## Warning in x * y: longitud de objeto mayor no es múltiplo de la longitud de uno
## menor
## [1] 2 3 4 2 3
R aplica la regla de reciclaje (recycling rule): repite los elementos del vector más corto hasta completar la longitud del más largo.
Idealmente, la longitud del vector más largo debe ser múltiplo de la del más corto. Si no lo es (como en este ejemplo, 5 no es múltiplo de 3), R realiza la operación pero muestra un warning, porque el reciclaje no es exacto.
Existen funciones matemáticas como log(),
exp(), sin(), cos(),
tan() y sqrt().
También hay funciones estadísticas y de resumen como
min(), max(), sum(),
prod(), mean(), var(),
sd(). Éstas devuelven un único valor a partir del
vector.
Asimismo, existen funciones de ordenamiento y resumen descriptivo,
como sort(), rev() y
summary().
salarios <- c(15000, 9000, 10000, 8000)
min(salarios)
## [1] 8000
max(salarios)
## [1] 15000
sum(salarios)
## [1] 42000
mean(salarios)
## [1] 10500
var(salarios)
## [1] 9666667
sd(salarios)
## [1] 3109.126
sort(salarios)
## [1] 8000 9000 10000 15000
rev(salarios)
## [1] 8000 10000 9000 15000
summary(salarios)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 8000 8750 9500 10500 11250 15000
Si el vector contiene valores NA, debemos agregar un
argumento adicional para que la función los ignore en el cálculo.
salarios <- c(8000, 9000, 10000, 15000, NA)
class(salarios)
## [1] "numeric"
# mean(salarios)
mean(salarios,na.rm=TRUE)
## [1] 10500
nombres <- c("Ana","David","Joshua","María")
edades <- c(18,20,22,29)
vector_combinado <- paste(nombres,", su edad es:",edades)
vector_combinado
## [1] "Ana , su edad es: 18" "David , su edad es: 20"
## [3] "Joshua , su edad es: 22" "María , su edad es: 29"
En R, los “vectores con índices” se refiere a la forma de acceder y manipular a los elementos individuales de un vector mediante índices numéricos.
Cada elemento en un vector tiene una posición única que se identifica mediante un índice numérico. Estos comienzan desde 1 hasta la longitud del vector.
vector <- c(10,20,30,40,50)
# Recuperamos el 3er elemento del vector
elemento <- vector[3]
print(elemento)
## [1] 30
# Reasignamos valores por posición
vector[3] <- 33
print(vector)
## [1] 10 20 33 40 50
class(vector)
## [1] "numeric"
vector[3] <- "hola"
print(vector)
## [1] "10" "20" "hola" "40" "50"
class(vector)
## [1] "character"
salarios
## [1] 8000 9000 10000 15000 NA
salarios_ord <- sort(salarios)
salarios_ord[1]; salarios_ord[2]
## [1] 8000
## [1] 9000
# 3 salarios más bajos
salarios_ord[c(1,2,3)]
## [1] 8000 9000 10000
# Secuencias numéricas con el operador ":"
salarios_ord[1:3]
## [1] 8000 9000 10000
length(salarios_ord[1:3])
## [1] 3
# La longitud de un vector de tipo a:b será b-a+1
salarios_ord[2:4]
## [1] 9000 10000 15000
length(salarios_ord[2:4])
## [1] 3
4-2+1
## [1] 3
En este caso, indican los elementos del vector referido que deben ser excluidos.
salarios_ord
## [1] 8000 9000 10000 15000
salarios[-1]
## [1] 9000 10000 15000 NA
salarios; salarios[-(2:4)]
## [1] 8000 9000 10000 15000 NA
## [1] 8000 NA
Este tipo de índices tiene una gran importancia en el análisis de
datos y se aplican en el proceso de imputación, que logra reemplazar
valores faltantes (NA) por estimaciones razonables basadas
en la información disponible, evitando eliminar observaciones
completas.
salarios <- c(8000, 9000, 10000, 15000, NA, NA)
salarios
## [1] 8000 9000 10000 15000 NA NA
# Identificamos las posiciones NA
posiciones_NA <- which(is.na(salarios))
posiciones_NA
## [1] 5 6
# Eliminamos los valores NA (si son pocos)
salarios_sin_NA <- salarios[-posiciones_NA]
salarios_sin_NA
## [1] 8000 9000 10000 15000
# O reemplazamos a los NA por la media
media_salarios <- mean(salarios, na.rm =TRUE)
media_salarios
## [1] 10500
salarios[posiciones_NA] <- media_salarios
salarios
## [1] 8000 9000 10000 15000 10500 10500
Solo se mostrarán los elementos que cumplan una condición lógica como índice.
salarios
## [1] 8000 9000 10000 15000 10500 10500
salarios > 10000
## [1] FALSE FALSE FALSE TRUE TRUE TRUE
salarios[salarios>10000]
## [1] 15000 10500 10500
También podemos usar indexación lógica y reasignación para eliminar
los valores NA del vector.
salarios <- c(8000, 9000, 10000, 15000, NA, NA)
salarios
## [1] 8000 9000 10000 15000 NA NA
is.na(salarios)
## [1] FALSE FALSE FALSE FALSE TRUE TRUE
!is.na(salarios)
## [1] TRUE TRUE TRUE TRUE FALSE FALSE
salarios[!is.na(salarios)]
## [1] 8000 9000 10000 15000
salarios <- salarios[!is.na(salarios)]
salarios
## [1] 8000 9000 10000 15000
mean(salarios)
## [1] 10500
La función seq() permite generar secuencias más complejas. Esta función dispone de cinco argumentos, aunque no todos se utilizan simultáneamente.
seq(from = 1, to = 10)
## [1] 1 2 3 4 5 6 7 8 9 10
seq(from = 1, to = 10, by = 2)
## [1] 1 3 5 7 9
seq(1, 10, length = 4)
## [1] 1 4 7 10
a <- 1:5
b <- seq(from = 14, along.with = a)
a ; b
## [1] 1 2 3 4 5
## [1] 14 15 16 17 18
is.element(1,a)
## [1] TRUE
is.element(1,b)
## [1] FALSE
La función rep() también es útil para generar patrones repetitivos en secuencias.
rep(c(4,6,1), times = 3)
## [1] 4 6 1 4 6 1 4 6 1