Antes de importar datos a R, es recomendable definir una carpeta de trabajo (directorio). Esa carpeta será el lugar donde:
Guardaremos nuestros conjuntos de datos (archivos que vamos a analizar).
R buscará automáticamente los archivos cuando le indiquemos cargarlos.
Se guardarán los resultados que generemos (por ejemplo: tablas, gráficos o bases de datos nuevas).
Esto facilita mantener todo el trabajo organizado en un mismo lugar.
Por defecto, R selecciona una carpeta. Para ver cuál es corremos la siguiente función:
getwd()
## [1] "C:/Users/diori/Documents/CursoR_docentes"
Para cambiar la carpeta, usamos la función setwd("ruta")
o podemos hacerlo desde Session → Set Working
Directory → Choose Directory…
setwd("~/CursoR_docentes")
Tip: Es útil crear una carpeta para cada curso, proyecto o análisis y guardar todo ahí dentro (datos, scripts y resultados).
R permite importar distintos tipos de archivos. A continuación, veremos cómo cargar los tres más comunes: .txt, .csv y Excel.
Además de cargar los datos escribiendo código, en RStudio existe una herramienta visual llamada Import Dataset, que genera automáticamente el código por nosotros.
Para usarla:
Ir a File → Import Dataset.
Elegir el tipo de archivo:
From Text (base): Para archivos .txt.
From Text (readr): Para archivos .csv.
From Excel: Para archivos de Excel.
Buscar y seleccionar el archivo.
RStudio mostrará una vista previa de los datos. Desde allí podemos:
Elegir si los datos tienen encabezado.
Cambiar el separador (por ejemplo: coma, punto y coma, tabulación).
Elegir la hoja de Excel (si corresponde).
Si todo está bien, hacemos clic en Import.
Los datos se cargarán y RStudio mostrará el código que se ejecutó (esto es útil para aprender).
Incluso podemos copiar el código que se ejecutó para volverlo a correr cuando deseemos.
Existen varias funciones en R para importar archivos de texto (.txt).
Una de las más utilizadas es read.table(), que permite leer
archivos especificando el nombre del archivo, si el archivo contiene un
encabezado (header = TRUE) y el tipo de separador entre los
campos (argumento sep). En el caso de archivos .txt
separados por tabulaciones, es habitual utilizar
sep = "\t". Una alternativa más sencilla para este tipo de
archivos es la función read.delim(), que está pensada
específicamente para leer archivos delimitados por tabulaciones. Esta
función asume por defecto sep = "\t" y
header = TRUE, por lo que no es necesario indicar estos
argumentos manualmente.
read.table(file, # Archivo de datos TXT indicado como string o ruta completa al archivo
header = FALSE, # Si se muestra el encabezado (TRUE) o no (FALSE)
sep = "", # Separador de las columnas del archivo
dec = ".") # Carácter utilizado para separar decimales de los números en el archivo
datos_txt <- read.table("datos_txt.txt", header = TRUE, sep = "\t")
head(datos_txt)
## Nombre_Fondo Tipo_Fondo Activos_Netos
## 1 American Century Intl. Disc Capital internacional 14.37
## 2 American Century Tax-Free Bond Renta fija 10.73
## 3 American Century Ultra Capital nacional 24.94
## 4 Artisan Small Cap Capital nacional 16.92
## 5 Brown Cap Small Capital nacional 35.73
## 6 DFA U.S. Micro Cap Capital nacional 13.47
## Rentabilidad_5_Años Ratio_Gastos Ranking_Morningstar
## 1 30.53 1.41 3-star
## 2 3.34 0.49 4-star
## 3 10.88 0.99 3-star
## 4 15.67 1.18 3-star
## 5 15.85 1.20 4-star
## 6 17.23 0.53 3-star
O también
datos_txt <- read.delim("datos_txt.txt")
head(datos_txt)
## Nombre_Fondo Tipo_Fondo Activos_Netos
## 1 American Century Intl. Disc Capital internacional 14.37
## 2 American Century Tax-Free Bond Renta fija 10.73
## 3 American Century Ultra Capital nacional 24.94
## 4 Artisan Small Cap Capital nacional 16.92
## 5 Brown Cap Small Capital nacional 35.73
## 6 DFA U.S. Micro Cap Capital nacional 13.47
## Rentabilidad_5_Años Ratio_Gastos Ranking_Morningstar
## 1 30.53 1.41 3-star
## 2 3.34 0.49 4-star
## 3 10.88 0.99 3-star
## 4 15.67 1.18 3-star
## 5 15.85 1.20 4-star
## 6 17.23 0.53 3-star
Otra función comúnmente utilizada en R es read.csv(),
que permite importar archivos separados por comas (.csv).
read.csv() está diseñada específicamente para leer archivos
CSV, asumiendo por defecto sep = ",",
dec = "." y header = TRUE. Esto significa que,
en la mayoría de los casos, sólo es necesario indicar el nombre del
archivo, sin especificar otros argumentos adicionales. Este formato es
muy utilizado para intercambiar datos entre distintos programas y es
compatible con la mayoría de las hojas de cálculo y bases de datos.
read.csv(file, # Nombre del archivo o ruta completa del archivo
header = TRUE, # Leer el encabezado (TRUE) o no (FALSE)
sep = ",", # Separador de los valores
quote = "\"'", # Carácter de citaciones
dec = ".", # Punto decimal
fill = TRUE, # Rellenar celdas vacías (TRUE) o no (FALSE)
comment.char = "", # Carácter de los comentarios o cadenas vacías
encoding = "unknown", # Codificación del archivo
...) # Argumentos adicionales
datos_csv <- read.csv("datos_csv.csv")
head(datos_csv)
## Nombre_Fondo Tipo_Fondo Activos_Netos
## 1 American Century Intl. Disc Capital internacional 14.37
## 2 American Century Tax-Free Bond Renta fija 10.73
## 3 American Century Ultra Capital nacional 24.94
## 4 Artisan Small Cap Capital nacional 16.92
## 5 Brown Cap Small Capital nacional 35.73
## 6 DFA U.S. Micro Cap Capital nacional 13.47
## Rentabilidad_5_Años Ratio_Gastos Ranking_Morningstar
## 1 30.53 1.41 3-star
## 2 3.34 0.49 4-star
## 3 10.88 0.99 3-star
## 4 15.67 1.18 3-star
## 5 15.85 1.20 4-star
## 6 17.23 0.53 3-star
Para importar archivos de Excel (.xlsx o .xls) en R, se utiliza la
función read_excel() del paquete readxl. A
diferencia de read.table() o read.csv(),
read_excel() está diseñada específicamente para leer
archivos de Excel sin necesidad de convertirlos previamente a otro
formato. Permite especificar el nombre del archivo y, opcionalmente, la
hoja de cálculo que se desea importar mediante el argumento
sheet. La función reconoce automáticamente si el archivo
contiene un encabezado y no requiere indicar el tipo de separador, ya
que Excel gestiona internamente la estructura de los datos.
Antes de utilizar read_excel(), es necesario cargar el
paquete readxl con library(readxl).
# Cargar readxl
library(readxl)
datos_excel <- read_excel("datos_excel.xlsx", #Ruta del archivo
sheet = 1) #Puedo elegir una hoja específica
head(datos_excel)
## # A tibble: 6 × 6
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años Ratio_Gastos
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 American Century In… Capital i… 14.4 30.5 1.41
## 2 American Century Ta… Renta fija 10.7 3.34 0.49
## 3 American Century Ul… Capital n… 24.9 10.9 0.99
## 4 Artisan Small Cap Capital n… 16.9 15.7 1.18
## 5 Brown Cap Small Capital n… 35.7 15.8 1.2
## 6 DFA U.S. Micro Cap Capital n… 13.5 17.2 0.53
## # ℹ 1 more variable: Ranking_Morningstar <chr>
Tip: Algunas buenas prácticas son:
Guardar todos los archivos de datos en una carpeta específica del proyecto.
Usar nombres de archivos simples y descriptivos (sin espacios ni tildes).
Siempre verificar si los datos tienen encabezados (nombres de columnas).
Si al cargar un archivo los datos no se ven bien, revisar si el separador es correcto.
Antes de comenzar a trabajar con un conjunto de datos, es importante conocer cómo están organizados y cómo los está interpretando R. Esto nos permite asegurarnos de que las variables se hayan cargado correctamente y evitar errores en los análisis posteriores.
Existen varias funciones que nos ayudan a obtener esta información y vimos en el encuentro anterior:
head(): muestra las primeras filas del conjunto de
datos.
dim(): informa la cantidad de filas y columnas
(dimensiones).
names(): muestra los nombres de las variables
(columnas).
Además de las funciones básicas, str() es una
herramienta muy útil para obtener un resumen general de un conjunto de
datos. Esta función muestra el tipo de objeto (por ejemplo, data.frame),
la cantidad de filas (observaciones) y columnas (variables), y ofrece
una descripción breve de cada variable, indicando su nombre, tipo de
dato (numérico, texto, etc.) y los primeros valores registrados.
str(datos_excel)
## tibble [25 × 6] (S3: tbl_df/tbl/data.frame)
## $ Nombre_Fondo : chr [1:25] "American Century Intl. Disc" "American Century Tax-Free Bond" "American Century Ultra" "Artisan Small Cap" ...
## $ Tipo_Fondo : chr [1:25] "Capital internacional" "Renta fija" "Capital nacional" "Capital nacional" ...
## $ Activos_Netos : num [1:25] 14.4 10.7 24.9 16.9 35.7 ...
## $ Rentabilidad_5_Años: num [1:25] 30.53 3.34 10.88 15.67 15.85 ...
## $ Ratio_Gastos : num [1:25] 1.41 0.49 0.99 1.18 1.2 0.53 0.89 0.9 0.89 0.45 ...
## $ Ranking_Morningstar: chr [1:25] "3-star" "4-star" "3-star" "3-star" ...
El paquete skimr permite obtener un resumen estadístico
detallado y rápido de un conjunto de datos. A diferencia de
str(), que sólo muestra la estructura de las variables,
skim() agrega información descriptiva adicional como
medias, medianas, porcentajes de valores faltantes y pequeños
histogramas que facilitan una primera exploración visual de las
variables numéricas.
library(skimr)
skim(datos_excel)
| Name | datos_excel |
| Number of rows | 25 |
| Number of columns | 6 |
| _______________________ | |
| Column type frequency: | |
| character | 3 |
| numeric | 3 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| Nombre_Fondo | 0 | 1 | 9 | 30 | 0 | 25 | 0 |
| Tipo_Fondo | 0 | 1 | 10 | 21 | 0 | 3 | 0 |
| Ranking_Morningstar | 0 | 1 | 6 | 6 | 0 | 4 | 0 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| Activos_Netos | 1 | 0.96 | 27.52 | 16.18 | 8.60 | 15.07 | 24.68 | 35.49 | 73.11 | ▇▆▃▂▁ |
| Rentabilidad_5_Años | 0 | 1.00 | 16.50 | 10.39 | 2.37 | 13.41 | 15.46 | 17.23 | 51.10 | ▃▇▂▁▁ |
| Ratio_Gastos | 0 | 1.00 | 0.94 | 0.39 | 0.16 | 0.62 | 1.05 | 1.25 | 1.41 | ▂▃▃▂▇ |
Esta función es útil para tener una visión general del tipo de variables, la cantidad de datos faltantes y la distribución de las variables, antes de realizar análisis más avanzados.
En muchos conjuntos de datos es común encontrarse con valores
faltantes. En R, los valores faltantes se representan como
NA (Not Available). Es importante identificarlos y
decidir cómo tratarlos, ya que pueden influir en los resultados de los
análisis.
Podemos detectar los valores faltantes con las siguientes funciones:
is.na(): indica para cada elemento si es faltante
(TRUE) o no (FALSE).
sum(is.na()): cuenta la cantidad total de valores
faltantes.
colSums(is.na()): muestra la cantidad de valores
faltantes en cada variable (columna).
# Devuelve TRUE en cada posición donde encuentra un NA (uno por celda)
is.na(datos_excel)
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años Ratio_Gastos
## [1,] FALSE FALSE FALSE FALSE FALSE
## [2,] FALSE FALSE FALSE FALSE FALSE
## [3,] FALSE FALSE FALSE FALSE FALSE
## [4,] FALSE FALSE FALSE FALSE FALSE
## [5,] FALSE FALSE FALSE FALSE FALSE
## [6,] FALSE FALSE FALSE FALSE FALSE
## [7,] FALSE FALSE FALSE FALSE FALSE
## [8,] FALSE FALSE TRUE FALSE FALSE
## [9,] FALSE FALSE FALSE FALSE FALSE
## [10,] FALSE FALSE FALSE FALSE FALSE
## [11,] FALSE FALSE FALSE FALSE FALSE
## [12,] FALSE FALSE FALSE FALSE FALSE
## [13,] FALSE FALSE FALSE FALSE FALSE
## [14,] FALSE FALSE FALSE FALSE FALSE
## [15,] FALSE FALSE FALSE FALSE FALSE
## [16,] FALSE FALSE FALSE FALSE FALSE
## [17,] FALSE FALSE FALSE FALSE FALSE
## [18,] FALSE FALSE FALSE FALSE FALSE
## [19,] FALSE FALSE FALSE FALSE FALSE
## [20,] FALSE FALSE FALSE FALSE FALSE
## [21,] FALSE FALSE FALSE FALSE FALSE
## [22,] FALSE FALSE FALSE FALSE FALSE
## [23,] FALSE FALSE FALSE FALSE FALSE
## [24,] FALSE FALSE FALSE FALSE FALSE
## [25,] FALSE FALSE FALSE FALSE FALSE
## Ranking_Morningstar
## [1,] FALSE
## [2,] FALSE
## [3,] FALSE
## [4,] FALSE
## [5,] FALSE
## [6,] FALSE
## [7,] FALSE
## [8,] FALSE
## [9,] FALSE
## [10,] FALSE
## [11,] FALSE
## [12,] FALSE
## [13,] FALSE
## [14,] FALSE
## [15,] FALSE
## [16,] FALSE
## [17,] FALSE
## [18,] FALSE
## [19,] FALSE
## [20,] FALSE
## [21,] FALSE
## [22,] FALSE
## [23,] FALSE
## [24,] FALSE
## [25,] FALSE
# Cuenta la cantidad total de NA en todo el conjunto de datos
sum(is.na(datos_excel))
## [1] 1
# Cuenta la cantidad de NA por cada variable (columna)
colSums(is.na(datos_excel))
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años
## 0 0 1 0
## Ratio_Gastos Ranking_Morningstar
## 0 0
Una vez identificados los NA, hay varias estrategias
para tratarlos. La elección depende del tipo de análisis y del contexto
de los datos. A continuación se presentan las opciones más
habituales:
| Opción | Base R |
dplyr
|
Uso |
|---|---|---|---|
| Omitir filas con NA |
na.omit()
|
drop_na()
|
Cuando las filas con valores faltantes son pocas y no afectan el análisis. |
| Reemplazar por un valor definido (por ejemplo, 0 o “Sin dato”) |
ifelse(is.na(), valor, valor_original)
|
replace_na()
|
Cuando tiene sentido completar el dato con una categoría o valor fijo que represente la ausencia. |
| Reemplazar por la media (en una variable numérica) |
mean() + ifelse()
|
mean() + replace_na() ó if_else()
|
Si puede asumirse que el dato faltante es similar al promedio de la muestra. |
# Crear un nuevo objeto sin filas con NA
datos_sin_na <- na.omit(datos_excel)
#chequeamos si hay NA
colSums(is.na(datos_sin_na))
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años
## 0 0 0 0
## Ratio_Gastos Ranking_Morningstar
## 0 0
# Reemplazar los NA por cero
datos_excel$Activos_Netos <- ifelse(is.na(datos_excel$Activos_Netos), 0, datos_excel$Activos_Netos)
#chequeamos si hay NA
colSums(is.na(datos_excel))
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años
## 0 0 0 0
## Ratio_Gastos Ranking_Morningstar
## 0 0
#Vuelvo a cargar el excel original para recuperar el NA
datos_excel <- read_excel("datos_excel.xlsx", sheet = 1)
# Reemplazar los NA de una variable por su media
media_AN <- mean(datos_excel$Activos_Netos, na.rm = TRUE)
datos_excel$Activos_Netos <- ifelse(is.na(datos_excel$Activos_Netos), media_AN, datos_excel$Activos_Netos)
#chequeamos si hay NA
colSums(is.na(datos_excel))
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años
## 0 0 0 0
## Ratio_Gastos Ranking_Morningstar
## 0 0
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.2 ✔ tibble 3.2.1
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.0.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::group_rows() masks kableExtra::group_rows()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
#Vuelvo a cargar el excel original para recuperar el NA
datos_excel <- read_excel("datos_excel.xlsx", sheet = 1)
# Eliminar filas que tengan NA en cualquier variable
datos_sin_NA <- datos_excel %>%
drop_na()
#chequeamos si hay NA
colSums(is.na(datos_sin_NA))
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años
## 0 0 0 0
## Ratio_Gastos Ranking_Morningstar
## 0 0
# Eliminar filas con NA solo en variables específicas
datos_sin_na_var <- datos_excel %>%
drop_na(Activos_Netos)
#chequeamos si hay NA
colSums(is.na(datos_sin_na_var))
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años
## 0 0 0 0
## Ratio_Gastos Ranking_Morningstar
## 0 0
# Reemplazar NA por 0 en una variable numérica
datos_reem <- datos_excel %>%
mutate(Activos_Netos = replace_na(Activos_Netos, 0))
#chequeamos si hay NA
colSums(is.na(datos_reem))
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años
## 0 0 0 0
## Ratio_Gastos Ranking_Morningstar
## 0 0
# Calcular la media
media_AN <- mean(datos_excel$Activos_Netos, na.rm = TRUE)
# Reemplazar NA por la media
datos_reem_media <- datos_excel %>%
mutate(Activos_Netos = replace_na(Activos_Netos, media_AN))
#chequeamos si hay NA
colSums(is.na(datos_reem_media))
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años
## 0 0 0 0
## Ratio_Gastos Ranking_Morningstar
## 0 0
# o también
datos_reem_media2 <- datos_excel %>%
mutate(Activos_Netos = if_else(is.na(Activos_Netos), media_AN, Activos_Netos))
#chequeamos si hay NA
colSums(is.na(datos_reem_media2))
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años
## 0 0 0 0
## Ratio_Gastos Ranking_Morningstar
## 0 0
Cuando la variable es cualitativa suele reemplazarse el NA por “Sin dato”. Esto puede hacerse con:
dplyrEl paquete dplyr es una herramienta muy utilizada para
la manipulación de datos en R. Aunque las operaciones que permite
realizar también se pueden hacer con la sintaxis base de R,
dplyr ofrece una forma más clara, legible y eficiente de
escribir el código. Su principal ventaja es que proporciona una
gramática simple e intuitiva para trabajar con conjuntos de datos,
especialmente con objetos del tipo data.frame o
tibble. Además, muchas de sus funciones están optimizadas
internamente en C++, lo que las hace más rápidas cuando
se trabaja con grandes volúmenes de datos.
dplyr forma parte del conjunto de paquetes llamado
tidyverse, que también incluye otros paquetes importantes
como tidyr (para ordenar y transformar datos),
ggplot2 (para visualización de datos), readr
(para importar datos), stringr (para manejar cadenas de
texto), entre otros.
Algunas de sus funciones más importantes son:
| Función | Descripción | Ejemplo |
|---|---|---|
select()
|
Selecciona columnas (variables) del conjunto de datos. |
datos %>% select(variable1, variable2) |
filter()
|
Filtra filas (observaciones) que cumplen una condición. |
datos %>% filter(variable > 10) |
arrange()
|
Ordena las filas según una o más variables. |
datos %>% arrange(variable) |
mutate()
|
Crea nuevas variables o transforma variables existentes. |
datos %>% mutate(nueva_var = variable * 2) |
summarise()
|
Resume los datos calculando estadísticas (promedio, suma, etc.). |
datos %>% summarise(promedio = mean(variable)) |
group_by()
|
Agrupa los datos según una o más variables, para aplicar resúmenes por grupo. |
datos %>% group_by(grupo) %>% summarise(promedio = mean(variable)) |
distinct()
|
Elimina filas duplicadas, conservando solo las únicas. |
datos %>% distinct(variable) |
rename()
|
Cambia el nombre de una o más variables. |
datos %>% rename(nuevo_nombre = nombre_original) |
slice()
|
Selecciona filas por su posición (por ejemplo, las primeras, las últimas o una fila específica). |
datos %>% slice(1:5) |
drop_na()
|
Elimina las filas con valores faltantes (NA). |
datos %>% drop_na() |
Para comenzar a utilizarlo, cargamos el paquete
tidyverse:
#Cargamos las librerías
library("tidyverse")
La función arrange permite ordear el data frame en
función de una o más variables. Por defecto, ordena de forma ascendente
(de menor a mayor o de A a Z).
Ordenamos los datos por el Ratio de gastos de menor a mayor:
data_ord_rat <- datos_excel %>%
arrange(Ratio_Gastos)
head(data_ord_rat)
## # A tibble: 6 × 6
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años Ratio_Gastos
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 Vanguard Sht-Tm TE Renta fija 15.7 2.37 0.16
## 2 Vanguard Sm Cp Idx Capital n… 32.6 17.0 0.23
## 3 Vanguard Equity-Inc Capital n… 24.4 13.4 0.29
## 4 Fidelity Sh-Term Bo… Renta fija 8.6 2.76 0.45
## 5 American Century Ta… Renta fija 10.7 3.34 0.49
## 6 DFA U.S. Micro Cap Capital n… 13.5 17.2 0.53
## # ℹ 1 more variable: Ranking_Morningstar <chr>
Odenamos los datos primero por Ratio de gastos y luego por la
Rentabilidad de los últimos 5 años, ambas de mayor a menor con la
función desc:
data_ord_ratyrent <- datos_excel %>%
arrange(desc(Ratio_Gastos), desc(Rentabilidad_5_Años))
head(data_ord_ratyrent)
## # A tibble: 6 × 6
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años Ratio_Gastos
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 American Century In… Capital i… 14.4 30.5 1.41
## 2 RS Value A Capital n… 26.3 23.7 1.36
## 3 Gabelli Asset AAA Capital n… 49.8 16.7 1.36
## 4 Kalmar Gr Val Sm Cp Capital n… 15.3 15.3 1.32
## 5 Marsico 21st Century Capital n… 17.5 15.2 1.31
## 6 Thornburg Value A Capital n… 32.5 15.5 1.27
## # ℹ 1 more variable: Ranking_Morningstar <chr>
Para eliminar duplicados usamos la función distinct:
data_sin_dup <- datos_excel %>%
distinct()
Usamos la función rename para renombrar las
variables.
Renombramos la variable Ratio_Gastos a “Ratio de gastos”:
data_ren <- datos_excel %>%
rename(`Ratio de gastos` = Ratio_Gastos)
names(data_ren)
## [1] "Nombre_Fondo" "Tipo_Fondo" "Activos_Netos"
## [4] "Rentabilidad_5_Años" "Ratio de gastos" "Ranking_Morningstar"
Usamos la función filter para seleccionar filas según
condiciones específicas.
Filtramos los fondos de Renta fija
data_rf <- datos_excel %>%
filter(Tipo_Fondo == "Renta fija")
head(data_rf)
## # A tibble: 5 × 6
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años Ratio_Gastos
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 American Century Ta… Renta fija 10.7 3.34 0.49
## 2 Fidelity Sh-Term Bo… Renta fija 8.6 2.76 0.45
## 3 PIMCO Emerg Mkts Bd… Renta fija 10.7 13.6 1.25
## 4 USAA Income Renta fija 12.1 4.31 0.62
## 5 Vanguard Sht-Tm TE Renta fija 15.7 2.37 0.16
## # ℹ 1 more variable: Ranking_Morningstar <chr>
Filtramos los fondos con un Ratio de gastos mayor a 1.
data_ra <- datos_excel %>%
filter(Ratio_Gastos > 1)
head(data_ra)
## # A tibble: 6 × 6
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años Ratio_Gastos
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 American Century In… Capital i… 14.4 30.5 1.41
## 2 Artisan Small Cap Capital n… 16.9 15.7 1.18
## 3 Brown Cap Small Capital n… 35.7 15.8 1.2
## 4 Gabelli Asset AAA Capital n… 49.8 16.7 1.36
## 5 Kalmar Gr Val Sm Cp Capital n… 15.3 15.3 1.32
## 6 Marsico 21st Century Capital n… 17.5 15.2 1.31
## # ℹ 1 more variable: Ranking_Morningstar <chr>
Filtramos los fondos de Renta fija con un Ratio de gastos mayor a 1.
data_rfyra <- datos_excel %>%
filter(Tipo_Fondo == "Renta fija" & Ratio_Gastos > 1)
head(data_rfyra)
## # A tibble: 1 × 6
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años Ratio_Gastos
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 PIMCO Emerg Mkts Bd… Renta fija 10.7 13.6 1.25
## # ℹ 1 more variable: Ranking_Morningstar <chr>
Una gran utilidad de esta función es que nos permite eliminar las
filas con datos faltantes o NA que haya en alguna/s
variable/s del conjunto de datos.
data_sin_na <- datos_excel %>%
filter(!is.na(Activos_Netos))
La función drop_na permite eliminar las filas que tengan
NA en cualquier variable (en todo el conjunto de
datos).
data_sin_na2 <- datos_excel %>%
drop_na() # si acá especificamos una varialbe, sólo se eliminan los NA de esa variable
La función select permite elegir qué columnas mantener
en el conjunto de datos. Seleccionamos las columnas Tipo_Fondo y
Activos_Netos:
data_2var <- datos_excel %>%
select(Tipo_Fondo, Activos_Netos)
names(data_2var)
## [1] "Tipo_Fondo" "Activos_Netos"
Eliminamos la columna de Tipo de Fondo:
data_sinTF <- datos_excel %>%
select(-Tipo_Fondo)
names(data_sinTF)
## [1] "Nombre_Fondo" "Activos_Netos" "Rentabilidad_5_Años"
## [4] "Ratio_Gastos" "Ranking_Morningstar"
Damos un nuevo orden a las columnas:
data_ordcol <- datos_excel %>%
select(Nombre_Fondo, Ranking_Morningstar, Rentabilidad_5_Años, Activos_Netos, Tipo_Fondo, Ratio_Gastos)
names(data_ordcol)
## [1] "Nombre_Fondo" "Ranking_Morningstar" "Rentabilidad_5_Años"
## [4] "Activos_Netos" "Tipo_Fondo" "Ratio_Gastos"
Con la función slice podemos podemos seleccionar filas
específicas del conjunto de datos.
primeros3 <- datos_excel %>%
slice(1:3) # seleccionamos las primeras 3 filas
primeros3
## # A tibble: 3 × 6
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años Ratio_Gastos
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 American Century In… Capital i… 14.4 30.5 1.41
## 2 American Century Ta… Renta fija 10.7 3.34 0.49
## 3 American Century Ul… Capital n… 24.9 10.9 0.99
## # ℹ 1 more variable: Ranking_Morningstar <chr>
ultimos3 <- datos_excel %>%
slice((n() - 2):n()) # seleccionamos las primeras 3 filas
ultimos3
## # A tibble: 3 × 6
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años Ratio_Gastos
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 Vanguard Sht-Tm TE Renta fija 15.7 2.37 0.16
## 2 Vanguard Sm Cp Idx Capital n… 32.6 17.0 0.23
## 3 Wasatch Sm Cp Growth Capital n… 35.4 14.0 1.19
## # ℹ 1 more variable: Ranking_Morningstar <chr>
filas_2y5 <- datos_excel %>%
slice(c(2, 5)) # seleccionamos las filas 2 y 5
filas_2y5
## # A tibble: 2 × 6
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años Ratio_Gastos
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 American Century Ta… Renta fija 10.7 3.34 0.49
## 2 Brown Cap Small Capital n… 35.7 15.8 1.2
## # ℹ 1 more variable: Ranking_Morningstar <chr>
Con la función mutate podemos crear y transformar
variables:
Categorizamos la variable Ratio de Gastos en Alto y Bajo:
data_cat <- datos_excel %>%
mutate(Ratio_cat = case_when(
Ratio_Gastos >= 1 ~ "Alto",
Ratio_Gastos < 1 ~ "Bajo"
))
#La nueva variable se agrega al final
names(data_cat)
## [1] "Nombre_Fondo" "Tipo_Fondo" "Activos_Netos"
## [4] "Rentabilidad_5_Años" "Ratio_Gastos" "Ranking_Morningstar"
## [7] "Ratio_cat"
#vemos sus valores
print(data_cat$Ratio_cat)
## [1] "Alto" "Bajo" "Bajo" "Alto" "Alto" "Bajo" "Bajo" "Bajo" "Bajo" "Bajo"
## [11] "Alto" "Alto" "Alto" "Alto" "Alto" "Alto" "Alto" "Alto" "Bajo" "Alto"
## [21] "Bajo" "Bajo" "Bajo" "Bajo" "Alto"
A partir de la rentabilidad promedio anual de los últimos 5 años, podemos calcular la rentabilidad promedio mensual:
data_rentmens <- datos_excel %>%
mutate(Rentabilidad_5_Años = Rentabilidad_5_Años/12)
#La nueva variable se agrega al final
names(data_rentmens)
## [1] "Nombre_Fondo" "Tipo_Fondo" "Activos_Netos"
## [4] "Rentabilidad_5_Años" "Ratio_Gastos" "Ranking_Morningstar"
#vemos sus valores
print(data_rentmens$Rentabilidad_5_Años)
## [1] 2.5441667 0.2783333 0.9066667 1.3058333 1.3208333 1.4358333 1.4991667
## [8] 1.9550000 1.1250000 0.2300000 1.3916667 1.2758333 1.2633333 2.7250000
## [15] 0.7925000 1.1308333 1.9733333 4.2583333 1.4091667 1.2883333 0.3591667
## [22] 1.1175000 0.1975000 1.4175000 1.1650000
Podemos construir una nueva variable compleja combinando categorías o valores de otras dos. Por ejemplo, podemos construir una variable a partir de Tipo_fondo y si la Rentabilidad_5_años es mayor a la media.
datos_otro <- datos_excel %>%
mutate(Variable_compleja=case_when(
Tipo_Fondo == "Renta fija" & Rentabilidad_5_Años > mean(Rentabilidad_5_Años) ~ "Renta fija y rentabilidad mayor a la media",
Tipo_Fondo == "Capital nacional" & Rentabilidad_5_Años > mean(Rentabilidad_5_Años) ~ "Capital nacional y rentabilidad mayor a la media",
Tipo_Fondo == "Capital internacional" & Rentabilidad_5_Años > mean(Rentabilidad_5_Años) ~ "Capital internacional y rentabilidad mayor a la media",
Tipo_Fondo == "Renta fija" & Rentabilidad_5_Años <= mean(Rentabilidad_5_Años) ~ "Renta fija y rentabilidad menor o igual a la media",
Tipo_Fondo == "Capital nacional" & Rentabilidad_5_Años <= mean(Rentabilidad_5_Años) ~ "Capital nacional y rentabilidad menor o igual a la media",
Tipo_Fondo == "Capital internacional" & Rentabilidad_5_Años <= mean(Rentabilidad_5_Años) ~ "Capital internacional y rentabilidad menor o igual a la media"
))
datos_otro$Variable_compleja
## [1] "Capital internacional y rentabilidad mayor a la media"
## [2] "Renta fija y rentabilidad menor o igual a la media"
## [3] "Capital nacional y rentabilidad menor o igual a la media"
## [4] "Capital nacional y rentabilidad menor o igual a la media"
## [5] "Capital nacional y rentabilidad menor o igual a la media"
## [6] "Capital nacional y rentabilidad mayor a la media"
## [7] "Capital nacional y rentabilidad mayor a la media"
## [8] "Capital internacional y rentabilidad mayor a la media"
## [9] "Capital nacional y rentabilidad menor o igual a la media"
## [10] "Renta fija y rentabilidad menor o igual a la media"
## [11] "Capital nacional y rentabilidad mayor a la media"
## [12] "Capital nacional y rentabilidad menor o igual a la media"
## [13] "Capital nacional y rentabilidad menor o igual a la media"
## [14] "Capital internacional y rentabilidad mayor a la media"
## [15] "Capital nacional y rentabilidad menor o igual a la media"
## [16] "Renta fija y rentabilidad menor o igual a la media"
## [17] "Capital nacional y rentabilidad mayor a la media"
## [18] "Capital internacional y rentabilidad mayor a la media"
## [19] "Capital nacional y rentabilidad mayor a la media"
## [20] "Capital nacional y rentabilidad menor o igual a la media"
## [21] "Renta fija y rentabilidad menor o igual a la media"
## [22] "Capital nacional y rentabilidad menor o igual a la media"
## [23] "Renta fija y rentabilidad menor o igual a la media"
## [24] "Capital nacional y rentabilidad mayor a la media"
## [25] "Capital nacional y rentabilidad menor o igual a la media"
Usando la función summarise podemos calcular
estadísticas descriptivas, usando las siguientes funciones:
mean(x) devuelve el promedio del argumento
x.median(x) devuelve la mediana del argumento
x.moda(x) devuelve la moda del argumento
x.quantile(x) devuelve el mínimo, el primer, segundo y
tercer cuartil, y el máximo de x.quantile(x, a) devuelve el cuantil a de
x (a ∈ [0,1]).range(x) devuelve el valor mínimo y el valor máximo en
x. Para calcular el rango aplicamos sobre esta función la
función diff.IQR(x) devuelve el rango intercuartil del argumento
x.var(x) devuelve la varianza del argumento
x.sd(x) devuelve el desvío estándar del argumento
x.Calculamos las medidas de resumen de Activos Netos:
#Agregamos función para calcular la moda
moda <- function(x) {
freqs <- table(x)
max_freq <- max(freqs)
if (sum(freqs == max_freq) == length(freqs)) {
return("No hay moda")
} else {
return(as.numeric(names(freqs[freqs == max_freq])))
}
}
medidas <- datos_sin_NA %>%
summarise(
Media = mean(Activos_Netos),
Mediana = median(Activos_Netos),
Moda = moda(Activos_Netos),
C1 = quantile(Activos_Netos, 0.25),
C3 = quantile(Activos_Netos, 0.75),
Rango = diff(range(Activos_Netos)),
RIC = IQR(Activos_Netos),
Varianza = var(Activos_Netos),
Desvío = sd(Activos_Netos),
CV = sd(Activos_Netos) / mean(Activos_Netos) * 100
)
medidas
## # A tibble: 1 × 10
## Media Mediana Moda C1 C3 Rango RIC Varianza Desvío CV
## <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 27.5 24.7 No hay moda 15.1 35.5 64.5 20.4 262. 16.2 58.8
También podemos calcular las medidas por grupos usando la función
group_by, por ejemplo por Tipo_Fondo:
medidas_grupo <- datos_sin_NA %>%
group_by(Tipo_Fondo) %>%
summarise(
Media = mean(Activos_Netos),
Mediana = median(Activos_Netos),
Moda = moda(Activos_Netos),
C1 = quantile(Activos_Netos, 0.25),
C3 = quantile(Activos_Netos, 0.75),
Rango = diff(range(Activos_Netos)),
RIC = IQR(Activos_Netos),
Varianza = var(Activos_Netos),
Desvío = sd(Activos_Netos),
CV = sd(Activos_Netos) / mean(Activos_Netos) * 100
)
medidas_grupo
## # A tibble: 3 × 11
## Tipo_Fondo Media Mediana Moda C1 C3 Rango RIC Varianza Desvío CV
## <chr> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Capital int… 32.0 27.9 No h… 21.1 40.9 39.5 19.8 404. 20.1 62.7
## 2 Capital nac… 31.7 29.4 No h… 21.2 36.9 59.6 15.7 238. 15.4 48.8
## 3 Renta fija 11.6 10.7 No h… 10.7 12.1 7.08 1.42 6.87 2.62 22.7
El análisis exploratorio de datos (EDA) es una etapa fundamental que permite conocer la distribución, las características y posibles anomalías presentes en los datos antes de realizar un análisis más avanzado.
La función summary() permite obtener un resumen
estadístico de las variables numéricas y categóricas del conjunto de
datos. Proporciona medidas como el mínimo, el primer cuartil, la
mediana, la media, el tercer cuartil y el máximo para las variables
numéricas; y el conteo de frecuencias para las categóricas.
summary(datos_sin_NA)
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años
## Length:24 Length:24 Min. : 8.60 Min. : 2.37
## Class :character Class :character 1st Qu.:15.07 1st Qu.:12.78
## Mode :character Mode :character Median :24.68 Median :15.38
## Mean :27.52 Mean :16.21
## 3rd Qu.:35.49 3rd Qu.:17.07
## Max. :73.11 Max. :51.10
## Ratio_Gastos Ranking_Morningstar
## Min. :0.1600 Length:24
## 1st Qu.:0.5975 Class :character
## Median :1.1050 Mode :character
## Mean :0.9433
## 3rd Qu.:1.2550
## Max. :1.4100
Los outliers o valores atípicos son observaciones que se alejan considerablemente del resto de los datos. Su detección es importante porque pueden distorsionar los análisis posteriores.
boxplot() permite visualizar la distribución
de una variable y detectar posibles outliers. Los valores que aparecen
fuera de los “bigotes” del boxplot son considerados potenciales
atípicos.# Boxplot para detectar valores atípicos
boxplot(datos_sin_NA$Activos_Netos)
boxplot(datos_sin_NA$Rentabilidad_5_Años)
plot() permite generar un gráfico de
dispersión para observar la relación entre dos variables y detectar
posibles patrones o valores atípicos.# Gráfico de dispersión para observar patrones
plot(datos_sin_NA$Activos_Netos, datos_sin_NA$Rentabilidad_5_Años)
Una vez identificados, existen varias formas de tratar los outliers, dependiendo del contexto y los objetivos del análisis. Los outliers pueden eliminarse si se considera que distorsionan los resultados y no son representativos, reemplazarse por un valor más representativo como la mediana, o transformarse la variable para reducir la influencia de los valores extremos. También es posible mantenerlos si representan casos válidos y relevantes para el análisis. Es fundamental justificar cualquier decisión sobre el tratamiento de outliers, considerando siempre el contexto del estudio y los objetivos del análisis. A continuación, veremos cómo realizar estos tratamientos en R.
Una forma simple de eliminar outliers es filtrar las observaciones que están dentro de un rango determinado. Por ejemplo, se pueden eliminar los valores que se encuentran fuera del rango intercuartílico (IQR).
# Calcular los cuartiles y el rango intercuartílico (IQR)
Q1 <- quantile(datos_sin_NA$Activos_Netos, 0.25)
Q3 <- quantile(datos_sin_NA$Activos_Netos, 0.75)
IQR <- Q3 - Q1
# Definir los límites inferior y superior
limite_inferior <- Q1 - 1.5 * IQR
limite_superior <- Q3 + 1.5 * IQR
# Filtrar los datos que están dentro de los límites (sin outliers)
datos_sin_outliers <- datos_sin_NA %>%
filter(Activos_Netos >= limite_inferior & Activos_Netos <= limite_superior)
boxplot(datos_sin_outliers$Activos_Netos)
Otra opción es reemplazar los valores atípicos por un valor más representativo, como la mediana o la media.
# Calcular la mediana
mediana_AN <- median(datos_sin_NA$Activos_Netos, na.rm = TRUE)
# Reemplazar los valores fuera de los límites por la mediana
datos_reemplazo_outliers <- datos_sin_NA %>%
mutate(Activos_Netos = ifelse(Activos_Netos < limite_inferior | Activos_Netos > limite_superior,
mediana_AN,
Activos_Netos))
boxplot(datos_reemplazo_outliers$Activos_Netos)
Otra estrategia es aplicar una transformación que reduzca la influencia de los valores extremos, como la transformación logarítmica o raíz cuadrada.
# Transformación logarítmica (agregando 1 si hay ceros)
datos_transformados <- datos_sin_NA %>%
mutate(Activos_Netos_log = log(Activos_Netos))
boxplot(datos_transformados$Activos_Netos_log)
# Transformación raíz cuadrada
datos_transformados <- datos_sin_NA %>%
mutate(Activos_Netos_sqrt = sqrt(Activos_Netos))
boxplot(datos_transformados$Activos_Netos_sqrt)
Estas transformaciones suavizan la distribución de la variable y disminuyen el efecto de los valores atípicos, sin eliminar datos.