R es un lenguaje de programación de código abierto y un entorno de software para la computación estadística.
El lenguaje R se utiliza ampliamente entre los estadísticos y los mineros de datos para el desarrollo de software estadístico y el análisis de datos.
Todo el código R manipula objetos. El objeto, es el concepto principal sobre el cual se fundamenta la tecnología orientada a objetos. Un objeto puede ser visto como una entidad que posee atributos y efectúa acciones. Ejemplos de objetos en R incluyen las funciones, symbols (nombre objetos) e incluso las expresiones.
Principales características de R
Open Source y multiplataforma
Alto y creciente número de “paquetes”
Amplia comunidad de usuarios (individuos y empresas)
Ciclo completo de trabajo:
Implementación
Preparación de datos
Análisis
Despliegue
Documentación
Completo IDE (RStudio)
Para el caso de vectores, matrices y array, todos los elementos deben ser del mismo tipo.
# enteros forzados con "L"
numeros <- c(1L, 2L, 5L, 65L, 78L, 2L, 12L)
typeof(numeros)## [1] "integer"
# agregando un double '9'
numeros <- c(1L, 2L, 5L, 65L, 78L, 2L, 12L, 9)
typeof(numeros)## [1] "double"
# agregamos un caracter
numeros <- c(1L,2L,5L,65L,78L,2L,12L, 9, "a")
typeof(numeros)## [1] "character"
# cuantos datos hay
length(numeros)## [1] 9
# caracteres
letras <- c("a", "b", "c")
typeof(letras)## [1] "character"
Expresiones de asignación:
x <- 1
x## [1] 1
Un vector es un arreglo de datos. En R, es el tipo básico de almacenaminto de datos. El vector puede ser numerico, caracter, y logico basado en sus elementos.
vector1 <- c(1,3,5,7,9)
vector1## [1] 1 3 5 7 9
numbers.vec <- c(-3,-2,-1,0,1,2,3)
numbers.vec## [1] -3 -2 -1 0 1 2 3
num2char <- as.character(numbers.vec)
num2char## [1] "-3" "-2" "-1" "0" "1" "2" "3"
num2logical <- as.logical(numbers.vec)
num2logical## [1] TRUE TRUE TRUE FALSE TRUE TRUE TRUE
char.vec <- c("1","3","five","7")
char.vec## [1] "1" "3" "five" "7"
# acceso al segundo elemento del "vector1"
vector1[2]## [1] 3
# accediendo a los 3 elementos iniciado desde el segundo elemento.
vector1[2:4]## [1] 3 5 7
Un factor es otro tipo de dato importante en R, especialmente cuando se trata de variables categóricas. En un vector R, no hay límite en el número de elementos distintos, pero en las variables factoriales, sólo se requiere un número limitado de elementos distintos.
#
factor1 <- factor(c(1,2,3,4,5,6,7,8,9))
factor1## [1] 1 2 3 4 5 6 7 8 9
## Levels: 1 2 3 4 5 6 7 8 9
Un arreglo es una entrada de datos de múltiples suscripciones que permite el almacenamiento de tramas de datos, matrices o vectores de diferentes tipos. Los marcos y matrices de datos son de dos dimensiones solamente, pero un arreglo puede ser de cualquier número de dimensiones.
mat.array=array(dim=c(2,2,3))
# To produce the same results over time we set a seed value
set.seed(12345)
mat.array[,,1]<-rnorm(4)
mat.array[,,2]<-rnorm(4)
mat.array[,,3]<-rnorm(4)
mat.array## , , 1
##
## [,1] [,2]
## [1,] 0.5855288 -0.1093033
## [2,] 0.7094660 -0.4534972
##
## , , 2
##
## [,1] [,2]
## [1,] 0.6058875 0.6300986
## [2,] -1.8179560 -0.2761841
##
## , , 3
##
## [,1] [,2]
## [1,] -0.2841597 -0.1162478
## [2,] -0.9193220 1.8173120
Para poder realizar operaciones matemáticas en matrices deben ser valores numéricos.
# creating a matrix with numeric elements only
# To produce the same matrix over time we set a seed value
set.seed(12345)
num.mat <- matrix(rnorm(9),nrow=3,ncol=3)
num.mat## [,1] [,2] [,3]
## [1,] 0.5855288 -0.4534972 0.6300986
## [2,] 0.7094660 0.6058875 -0.2761841
## [3,] -0.1093033 -1.8179560 -0.2841597
# matrix multiplication
t(num.mat) %*% num.mat## [,1] [,2] [,3]
## [1,] 0.8581332 0.36302951 0.20405722
## [2,] 0.3630295 3.87772320 0.06350551
## [3,] 0.2040572 0.06350551 0.55404860
resultado <- 2 * (5 + 1)
resultado## [1] 12
Es un objeto que puede almacenar otros objetos de cualquier tipo.
var1 <- c(101,102,103,104,105)
var2 <- c(25,22,29,34,33)
var3 <- c("Non-Diabetic", "Diabetic", "Non-Diabetic", "Non-Diabetic",
"Diabetic")
var4 <- factor(c("male","male","female","female","male"))
diab.dat <- data.frame(var1,var2,var3,var4)
mat.array=array(dim=c(2,2,3))
set.seed(12345)
mat.array[,,1]<-rnorm(4)
mat.array[,,2]<-rnorm(4)
mat.array[,,3]<-rnorm(4)
# creating list
obj.list <- list(elem1=var1, elem2=var2, elem3=var3, elem4=var4, elem5=diab.dat, elem6=mat.array)
obj.list## $elem1
## [1] 101 102 103 104 105
##
## $elem2
## [1] 25 22 29 34 33
##
## $elem3
## [1] "Non-Diabetic" "Diabetic" "Non-Diabetic" "Non-Diabetic" "Diabetic"
##
## $elem4
## [1] male male female female male
## Levels: female male
##
## $elem5
## var1 var2 var3 var4
## 1 101 25 Non-Diabetic male
## 2 102 22 Diabetic male
## 3 103 29 Non-Diabetic female
## 4 104 34 Non-Diabetic female
## 5 105 33 Diabetic male
##
## $elem6
## , , 1
##
## [,1] [,2]
## [1,] 0.5855288 -0.1093033
## [2,] 0.7094660 -0.4534972
##
## , , 2
##
## [,1] [,2]
## [1,] 0.6058875 0.6300986
## [2,] -1.8179560 -0.2761841
##
## , , 3
##
## [,1] [,2]
## [1,] -0.2841597 -0.1162478
## [2,] -0.9193220 1.8173120
Acceso a elementos de la lista.
obj.list[[1]]## [1] 101 102 103 104 105
Un marco de datos es una disposición rectangular de filas y columnas de vectores y/o factores, como una hoja de cálculo en MS Excel.
#creating vector of different variables and then creating data frame
var1 <- c(101,102,103,104,105)
var2 <- c(25,22,29,34,33)
var3 <- c("Non-Diabetic", "Diabetic", "Non-Diabetic", "Non-Diabetic", "Diabetic")
var4 <- factor(c("male","male","female","female","male"))
# now we will create data frame using two numeric vectors one
# character vector and one factor
midata <- data.frame(var1,var2,var3,var4)
midata## var1 var2 var3 var4
## 1 101 25 Non-Diabetic male
## 2 102 22 Diabetic male
## 3 103 29 Non-Diabetic female
## 4 104 34 Non-Diabetic female
## 5 105 33 Diabetic male
Determinar las clases de cada columna.
#class of each column before creating data frame
class(var1)## [1] "numeric"
Para acceder a columnas individuales de un dataframe use (“$”)
midata$var1## [1] 101 102 103 104 105
midata[["var1"]]## [1] 101 102 103 104 105
midata[,1]## [1] 101 102 103 104 105
# secuencia de numeros
seq(from = 1, to = 7)## [1] 1 2 3 4 5 6 7
# una forma abreviada de generar una secuencia de datos
seq(1, 7)## [1] 1 2 3 4 5 6 7
print(vector)## function (mode = "logical", length = 0L)
## .Internal(vector(mode, length))
## <bytecode: 0x7f9992aa4f28>
## <environment: namespace:base>
str(vector)## function (mode = "logical", length = 0L)
# generación de una función anónima
f <- function() {
x <- 1
y <- 3
x + y
}
f()## [1] 4
imc <- function(peso, altura) {
peso / (altura/100)^2
}
print(imc(120, 180))## [1] 37.03704
typeof muestra el tipo de dato que contiene el objeto.
vector <- c(1,2,5,65,78,2,12)
typeof(vector)## [1] "double"
# Comprobación mediante is.*(objeto) devuelve TRUE o FALSE si cumple el tipo según la función usada.
is.logical## function (x) .Primitive("is.logical")
is.integer## function (x) .Primitive("is.integer")
is.double## function (x) .Primitive("is.double")
is.numeric## function (x) .Primitive("is.numeric")
is.character## function (x) .Primitive("is.character")
Transforma un tipo de datos en otro, uso de as.*(objeto).
as.logical## function (x, ...) .Primitive("as.logical")
as.numeric## function (x, ...) .Primitive("as.double")
as.double## function (x, ...) .Primitive("as.double")
as.character## function (x, ...) .Primitive("as.character")
as.list## function (x, ...)
## UseMethod("as.list")
## <bytecode: 0x7f998c822630>
## <environment: namespace:base>
as.vector## function (x, mode = "any")
## .Internal(as.vector(x, mode))
## <bytecode: 0x7f998ea42c98>
## <environment: namespace:base>
vector <- c(1,3,5,6,8,9,0)
vector## [1] 1 3 5 6 8 9 0
# posiciones 3, 5 y 7
vector[c(3,5,7)]## [1] 5 8 0
# posiciones 2 x tres veces, 5 y 7
vector[c(2,2,2,5,7)]## [1] 3 3 3 8 0
matriz <- matrix(1:20, nrow = 4)
matriz## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 5 9 13 17
## [2,] 2 6 10 14 18
## [3,] 3 7 11 15 19
## [4,] 4 8 12 16 20
matriz[1, 3]## [1] 9
# toda la fila 1
matriz[1,] ## [1] 1 5 9 13 17
# toda la columna 2
matriz[,2] ## [1] 5 6 7 8
# elimina la fila 2
matriz[-2,]## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 5 9 13 17
## [2,] 3 7 11 15 19
## [3,] 4 8 12 16 20
# elimina la columna 4
matriz[,-4] ## [,1] [,2] [,3] [,4]
## [1,] 1 5 9 17
## [2,] 2 6 10 18
## [3,] 3 7 11 19
## [4,] 4 8 12 20
lista <- list(1:4, "casa", list(c(4:8),8))
lista## [[1]]
## [1] 1 2 3 4
##
## [[2]]
## [1] "casa"
##
## [[3]]
## [[3]][[1]]
## [1] 4 5 6 7 8
##
## [[3]][[2]]
## [1] 8
# estructura de la lista
str(lista) ## List of 3
## $ : int [1:4] 1 2 3 4
## $ : chr "casa"
## $ :List of 2
## ..$ : int [1:5] 4 5 6 7 8
## ..$ : num 8
# asigna nombres a los elementos de la lista
names(lista) <- c("A", "B", "C")
lista## $A
## [1] 1 2 3 4
##
## $B
## [1] "casa"
##
## $C
## $C[[1]]
## [1] 4 5 6 7 8
##
## $C[[2]]
## [1] 8
# extrae elementos del nombre B
lista$B ## [1] "casa"
# equivalente a lo anterior
lista[["B"]] ## [1] "casa"
# el numero 2 de elemento 1
lista[[1]][2] ## [1] 2
n <- 5
n## [1] 5
res <- seq(1,n)
res## [1] 1 2 3 4 5
for (i in seq_len(n)) {
res[i] <- i^2
}
res## [1] 1 4 9 16 25
Los paquetes son la forma normal de instalar nuevas funcionalidades dentro de RStudio. Estos contienen las funciones y documentación necesaria.
El paquete consta de una librería de funciones orientadas a resolver un determinadao problema.
# desde un repositorio especifico
install.packages("tidyverse", repos = "http://cran.us.r-project.org")##
## The downloaded binary packages are in
## /var/folders/n1/zsbrkfs97sd_4fdl4mnf21g00000gn/T//RtmpsDCetw/downloaded_packages
# luego de instalar un paquete se requiere activar la librería del paquete
library(tidyverse)## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.0 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.2 ✔ tibble 3.1.8
## ✔ lubridate 1.9.2 ✔ tidyr 1.3.0
## ✔ purrr 1.0.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
# vector de muestra
x <- c(2, 4, 3, 6, 3, 7, 5, 8, 12, 23, 24, 27)
# uso de mean
mean(x) # 10.33## [1] 10.33333
# Equivalente a:
sum(x)/length(x) # 10.33## [1] 10.33333
# Si hay valores nulos o ausentes presenta errores.
x <- c(2, 4, 3, 6, 3, 7, 5, 8, 12, 23, 24, 27, NA)
# Si el vector contiene algún valor NA, el resultado será NA
mean(x) # NA## [1] NA
# Eliminar los valores NA
mean(x, na.rm = TRUE) # 10.33## [1] 10.33333
# media aritmetica truncada
# La media aritmética truncada elimina una fracción de las observaciones de cada lado del vector antes de que se calcule la media. Para descartar valores atípicos.
mean(x, trim = 0.1, na.rm = TRUE) # 9.5## [1] 9.5
g <- c(2, 4, 3, 6, 3, 7, 5, 8, 12, 23, 24, 27)
# Varianza
var(g) # 82.60606## [1] 82.60606
# Desviación típica
sd(g)## [1] 9.088788
# Equivalente a:
sqrt(var(g))## [1] 9.088788
mode <- function(x) {
return(as.numeric(names(which.max(table(x)))))
}
mode(g)## [1] 3
barplot(table(g), col = c(4, rep("gray", 4)))
legend("topright", "Moda", fill = 4)exporta el siguiente dataframe a txt, csv y luego importalo a R.
df <- data.frame(x = rnorm(10), y = rnorm(10))
df## x y
## 1 0.3706279 -0.6443284
## 2 0.5202165 -1.5531374
## 3 -0.7505320 -1.5977095
## 4 0.8168998 1.8050975
## 5 -0.8863575 -0.4816474
## 6 -0.3315776 0.6203798
## 7 1.1207127 0.6121235
## 8 0.2987237 -0.1623110
## 9 0.7796219 0.8118732
## 10 1.4557851 2.1968335
missing_dat <- data.frame(v1=c(1,NA,0,1),v2=c("M","F",NA,"M"))
missing_dat## v1 v2
## 1 1 M
## 2 NA F
## 3 0 <NA>
## 4 1 M
is.na(missing_dat$v1)## [1] FALSE TRUE FALSE FALSE
is.na(missing_dat$v2)## [1] FALSE FALSE TRUE FALSE
any(is.na(missing_dat))## [1] TRUE
Formatos comunes:
Comma separated values (.csv)
Text file with Tab delimited
Microsoft Excel file (.xls or .xlsx)
R data object (.RData)
# Antes de correr el siguiente comando ya que no se indica una ruta absoluta (sin directorio) se necesita establecer la ruta a la carpeta donde estén los datos.
# location using setwd(). For example
setwd("~/Documents/Clases/R-basico")
anscombe <- read.csv("data/iris.csv",skip=2)
#skip=2 indica que se salte 2 filas y por tanto los datos se inician en la tercera fila.# import csv file that contains both numeric and character variable
# firstly using default and then using stringsAsFActors=FALSE
iris_a <- read.csv("data/iris.csv")
str(iris_a) # muestra la estructura de los datos## 'data.frame': 150 obs. of 5 variables:
## $ sepal_length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ sepal_width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ petal_length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ petal_width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ species : chr "setosa" "setosa" "setosa" "setosa" ...
# Now using stringsAsFactors=FALSE
iris_b <- read.csv("data/iris.csv",stringsAsFactors=F)Importar archivo csv separado por semicolon (“;”)
iris_semicolon <- read.csv("data/iris.csv",stringsAsFactors=FALSE,sep=";")
str(iris_semicolon)## 'data.frame': 150 obs. of 1 variable:
## $ sepal_length.sepal_width.petal_length.petal_width.species: chr "5.1,3.5,1.4,0.2,setosa" "4.9,3.0,1.4,0.2,setosa" "4.7,3.2,1.3,0.2,setosa" "4.6,3.1,1.5,0.2,setosa" ...
Importar archivo csv separado por tab (“)
# anscombe_tab <- read.csv("anscombe.txt",sep="\t")
# anscombe_tab_2 <- read.table("anscombe.txt",header=TRUE)Importar un archivo Excel
# Calling xlsx library
library(xlsx)
# importing xlsxanscombe.xlsx
ans_xlsx <- read.xlsx2("data/Libro1.xlsx",sheetIndex=1)# Coma como separador y punto como separador decimal
write.csv(df, "data/datos.csv")
# archivo de texto
write.table(df, "data/datos.txt")
# Punto y coma como separador y coma como separador decimal
write.csv2(df, "data/datos.csv")# creando fechas usando la función estandar as.Date()
as.Date("1970-01-01")## [1] "1970-01-01"
# vieno el valor interno de un objeto de tipo fecha
as.numeric(as.Date("1970-01-01"))## [1] 0
# viendo iun objeto de fecha.
as.Date("1970-01-02")## [1] "1970-01-02"
as.numeric(as.Date("1970-01-02"))## [1] 1
# creando una fecha especificando el formato
as.Date("Jan-01-1970",format="%b-%d-%Y")## [1] NA
# uso del paquete lubridate
library(lubridate)
# creando una fecha usando la funcion mdy()
mdy("Jan-01-1970")## [1] "1970-01-01"
# Creating date object using based R functionality
date <- as.POSIXct("23-07-2013",format = "%d-%m-%Y", tz = "UTC")
# extracting month from the date object
as.numeric(format(date, "%m"))## [1] 7
# accediendo a la fecha y hora del sistema
current_time <- now()
current_time## [1] "2023-04-23 20:25:05 -04"
# cambiar la zona a "GMT"
current_time_gmt <- with_tz(current_time,"GMT")
current_time_gmt## [1] "2023-04-24 00:25:05 GMT"
# redondeando la fecha al día mas cercano
round_date(current_time_gmt,"day")## [1] "2023-04-24 GMT"
# creating a 10 element vectornum10 <- c(3,2,5,3,9,6,7,9,2,3)
# accessing fifth element
num10[5]## [1] 9
# checking whether there is any value of num10 object greater
# than 6
num10 > 6## [1] FALSE FALSE FALSE FALSE TRUE FALSE TRUE TRUE FALSE FALSE
# keeping only values greater than 6
num10[num10 > 6]## [1] 9 7 9
# use of negative subscript removes first element "3"
num10[-1]## [1] 2 5 3 9 6 7 9 2 3