Repaso tipos de datos

Una aseguradora está evaluando la prima anual de un seguro de vida individual. Para simplificar, se utilizará un modelo aproximado donde:

  • Se calcula una prima base proporcional a la suma asegurada.
  • Se analiza el perfil del cliente usando operadores lógicos y comparaciones.
  • Se aplican recargos según características de riesgo.

La información del cliente es:

  • Nombre: María
  • Edad: 47
  • Suma asegurada: 1,200,000
  • Años como cliente en la compañía: 8
  • Historial de reclamaciones médicas relevantes: 1
  • Fumador: No


Instrucciones

  1. Crea las variables correspondientes.
nombre <- "María"
edad <- 47
suma_asegurada <- 1200000
anios_cliente <- 8
reclamaciones <- 1
fumador <- FALSE


  1. Verifica el tipo de dato de cada una.
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"


  1. Construye una variable llamada 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) + (isTRUE(fumador)) + (reclamaciones > 0)
perfil_alto_riesgo
## [1] 2
class(perfil_alto_riesgo)
## [1] "integer"
# En Environment, aparece el valor de 2L porque estamos 
# sumando condiciones lógicas.
# Por coerción implícita: TRUE se convierte en 1 y FALSE en 0.
# Al usar '+', las condiciones se transforman en enteros y la suma devuelve un integer.
# La 'L' indica que el resultado es de tipo integer (R usa double por defecto,
# pero cuando la operación es entre enteros, mantiene el tipo integer).

perfil_alto_riesgo <- ((edad > 45) + (isTRUE(fumador)) + (reclamaciones > 0)) >=2
perfil_alto_riesgo
## [1] TRUE
class(perfil_alto_riesgo)
## [1] "logical"


  1. Calcula la prima anual bajo el siguiente esquema:
  • Prima base equivalente al 2% de la suma asegurada.
  • Si hay perfil de alto riesgo, se aplica un recargo adicional del 10%.
  • Si tiene más de 5 años como cliente, se aplica un descuento del 3%.
prima_base <- 0.02 * suma_asegurada

recargo <- perfil_alto_riesgo * 0.10
class(recargo)
## [1] "numeric"
descuento <- (anios_cliente > 5) * 0.03

prima_final <- prima_base * (1 + recargo - descuento)

prima_base; recargo; descuento; prima_final
## [1] 24000
## [1] 0.1
## [1] 0.03
## [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



Objetos de datos

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:

I. Vectores

II. Matrices

III. Data frames

IV. Listas

Comenzaremos con la estructura más básica y fundamental en R: los vectores.


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.

Propiedades de los vectores

Tipo de dato 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 → integer → double → character.

vector1 <- c(1,2,3,4,5)
vector1
## [1] 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)
vector2
## [1] "1"    "2"    "hola" "4"    "5"
# predomina el tipo de dato character por la coerción implícita
class(vector2)
## [1] "character"
is.vector(vector2)
## [1] TRUE
is.numeric(vector2)
## [1] FALSE
is.character(vector2)
## [1] TRUE
edades <- c(20,25,29,32,"8s",21)
edades
## [1] "20" "25" "29" "32" "8s" "21"
mean(edades)
## Warning in mean.default(edades): argument is not numeric or logical: returning
## NA
## [1] NA
# Warning: el vector se convirtió a character
# y mean() solo opera sobre datos numéricos

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 length()

vector1
## [1] 1 2 3 4 5
length(vector1)
## [1] 5
edades; length(edades)
## [1] "20" "25" "29" "32" "8s" "21"
## [1] 6

Aritmética vectorial

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
# 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


Vectorización

En R, muchas operaciones están vectorizadas. Esto significa que una operación aplicada a un vector se realiza automáticamente sobre cada uno de sus elementos, sin necesidad de utilizar ciclos o bucles.

salarios <- c(8000, 9000, 10000, 15000)

salarios
## [1]  8000  9000 10000 15000
# Aumento salarial del 5%
salarios * 1.05
## [1]  8400  9450 10500 15750
salarios
## [1]  8000  9000 10000 15000
# Bono fijo de $500
salarios + 500
## [1]  8500  9500 10500 15500
salarios
## [1]  8000  9000 10000 15000
## Cada elemento del vector recibe el aumento de forma automática


¿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 <- c(2,3,4)
y
## [1] 2 3 4
length(x)
## [1] 5
length(y)
## [1] 3
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
# Warning:
# longer object length is not a multiple of shorter object length

Un warning no detiene la ejecución del código; simplemente alerta sobre una situación que podría producir resultados inesperados.

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.

Funciones especiales aplicadas a vectores

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)

salarios
## [1] 15000  9000 10000  8000
min(salarios)
## [1] 8000
max(salarios)
## [1] 15000
sum(salarios)
## [1] 42000
prod(salarios)
## [1] 1.08e+16
mean(salarios)
## [1] 10500
var(salarios)
## [1] 9666667
sd(salarios)
## [1] 3109.126
salarios
## [1] 15000  9000 10000  8000
sort(salarios)
## [1]  8000  9000 10000 15000
salarios; rev(salarios)
## [1] 15000  9000 10000  8000
## [1]  8000 10000  9000 15000
# salarios <- rev(salarios)

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)
## [1] NA
mean(salarios, na.rm = TRUE)
## [1] 10500


Vectores con caracteres

nombres <- c("Adrian","Cintia","Keyla","Diego")
print(nombres); class(nombres)
## [1] "Adrian" "Cintia" "Keyla"  "Diego"
## [1] "character"
edades <- c(18,20,22,29)

vector_combinado <- paste(nombres, edades)
print(vector_combinado)
## [1] "Adrian 18" "Cintia 20" "Keyla 22"  "Diego 29"
vector_combinado <- paste(nombres,", su edad es:", edades)
print(vector_combinado)
## [1] "Adrian , su edad es: 18" "Cintia , su edad es: 20"
## [3] "Keyla , su edad es: 22"  "Diego , su edad es: 29"

Vectores con índices

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.

En R los índices comienzan en 1, no en 0 como ocurre en muchos lenguajes de programación.

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"
class(vector)
## [1] "character"
print(vector)
## [1] "10"   "20"   "Hola" "40"   "50"


Tipos de índices

Vectores con índices “enteros positivos”

salarios
## [1]  8000  9000 10000 15000    NA
salarios <- sort(salarios)
salarios
## [1]  8000  9000 10000 15000
# 3 salarios más bajos
salarios[1]; salarios[2]; salarios[3]
## [1] 8000
## [1] 9000
## [1] 10000
salarios[c(1,2,3)]
## [1]  8000  9000 10000
# Secuencias numéricas con el operador ":"
salarios[1:3]
## [1]  8000  9000 10000
length(salarios[1:3])
## [1] 3
salarios[2:4]
## [1]  9000 10000 15000
# La longitud de un vector de tipo a:b será b-a+1
length(salarios[2:4])
## [1] 3
4 - 2 + 1
## [1] 3

Vectores con índices “enteros negativos”

En este caso, indican los elementos del vector referido que deben ser excluidos.

salarios; salarios[-1]
## [1]  8000  9000 10000 15000
## [1]  9000 10000 15000
salarios; salarios[-(2:4)]
## [1]  8000  9000 10000 15000
## [1] 8000

Vectores con índices lógicos

Solo se mostrarán los elementos que cumplan una condición lógica como índice.

salarios
## [1]  8000  9000 10000 15000
salarios > 10000
## [1] FALSE FALSE FALSE  TRUE
salarios[salarios > 10000]
## [1] 15000


Tratamiento de valores faltantes a través de índices

En la práctica, las bases de datos suelen contener valores faltantes (NA). Por ejemplo, algunos clientes pueden no reportar su salario, edad o antigüedad laboral.

Podemos usar indexación lógica y reasignación para eliminar los valores NA del vector.

salarios <- c(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
sd(salarios)
## [1] 3109.126


Otra alternativa es reemplazar estos valores faltantes por una estimación razonable basada en la información disponible. A este proceso se le conoce como imputación y evita eliminar observaciones completas.

salarios <- c(8000, 9000, 10000, 15000, NA, NA)

salarios
## [1]  8000  9000 10000 15000    NA    NA
# Identificamos las posiciones NA
is.na(salarios)
## [1] FALSE FALSE FALSE FALSE  TRUE  TRUE
which(is.na(salarios))
## [1] 5 6
posiciones_NA <- which(is.na(salarios))
posiciones_NA
## [1] 5 6
# Reemplazamos a los NA por la media
salarios
## [1]  8000  9000 10000 15000    NA    NA
media_salarios <- mean(salarios, na.rm = TRUE)
media_salarios
## [1] 10500
salarios[posiciones_NA] <- media_salarios
salarios
## [1]  8000  9000 10000 15000 10500 10500

Secuencias

La función seq() permite generar secuencias más complejas. Esta función dispone de cinco argumentos, aunque no todos se utilizan simultáneamente.

  1. from: Valor inicial de la secuencia
  2. to: valor final de la secuencia
  3. by: Incremento entre los elementos sucesivos de la secuencia
  4. length.out: Longitud deseada de la secuencia
  5. along.with: Una secuencia existente que define la longitud de la nueva secuencia.
seq(from = 1, to = 10)
##  [1]  1  2  3  4  5  6  7  8  9 10
length(seq(from = 1, to = 10))
## [1] 10
class(seq(from = 1, to = 10))
## [1] "integer"
is.vector(seq(from = 1, to = 10))
## [1] TRUE
seq(from = 1, to = 10, by = 2)
## [1] 1 3 5 7 9
seq(1, 10, length.out = 20) # seq(1, 10, length = 20)
##  [1]  1.000000  1.473684  1.947368  2.421053  2.894737  3.368421  3.842105
##  [8]  4.315789  4.789474  5.263158  5.736842  6.210526  6.684211  7.157895
## [15]  7.631579  8.105263  8.578947  9.052632  9.526316 10.000000
a <- 1:5
a
## [1] 1 2 3 4 5
length(a)
## [1] 5
b <- seq(from = 14, along.with = a) # seq(from = 14, along = 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
length(rep(c(4,6,1), times = 3))
## [1] 9

Repaso vectores

  1. Genera una sucesión de números pares de 2 al 20 utilizando seq().
seq(from = 2, to = 20, by = 2)
##  [1]  2  4  6  8 10 12 14 16 18 20


  1. Genera una sucesión de números decimales de 0 a 1 con incrementos de 0.1
seq(from = 0, to = 1, by = 0.1)
##  [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0


  1. Genera una secuencia de cuadrados de los primeros 10 números naturales.
(1:10)^2
##  [1]   1   4   9  16  25  36  49  64  81 100


  1. Genera una secuencia de números de 1 al 100 divisibles por 3.
(1:100) %% 3 == 0
##   [1] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
##  [13] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
##  [25] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
##  [37] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
##  [49] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
##  [61] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
##  [73] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
##  [85] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE
##  [97] FALSE FALSE  TRUE FALSE
(1:100)[(1:100) %% 3 == 0]
##  [1]  3  6  9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75
## [26] 78 81 84 87 90 93 96 99
seq(from = 3, to = 100, by = 3)
##  [1]  3  6  9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75
## [26] 78 81 84 87 90 93 96 99


  1. Genera una secuencia de fechas a lo largo del mes de febrero de 2026.
seq(from = as.Date("2026-02-01"), to = as.Date("2026-02-28"), by = "day")
##  [1] "2026-02-01" "2026-02-02" "2026-02-03" "2026-02-04" "2026-02-05"
##  [6] "2026-02-06" "2026-02-07" "2026-02-08" "2026-02-09" "2026-02-10"
## [11] "2026-02-11" "2026-02-12" "2026-02-13" "2026-02-14" "2026-02-15"
## [16] "2026-02-16" "2026-02-17" "2026-02-18" "2026-02-19" "2026-02-20"
## [21] "2026-02-21" "2026-02-22" "2026-02-23" "2026-02-24" "2026-02-25"
## [26] "2026-02-26" "2026-02-27" "2026-02-28"
seq(from = as.Date("2026-02-01"), to = as.Date("2026-02-28"), by = 2)
##  [1] "2026-02-01" "2026-02-03" "2026-02-05" "2026-02-07" "2026-02-09"
##  [6] "2026-02-11" "2026-02-13" "2026-02-15" "2026-02-17" "2026-02-19"
## [11] "2026-02-21" "2026-02-23" "2026-02-25" "2026-02-27"