Programación en R: tutorial para principiantes

El lenguaje de programación R es un popular lenguaje de programación estadística utilizado principalmente en la ciencia y las matemáticas para la computación estadística. R es un lenguaje interesante con peculiaridades distintivas. Una vez lo entiendes, trabajar con este lenguaje puede ser divertido.

¿Qué distingue al lenguaje de programación R?

R no es un lenguaje de programación general como Java o Python. Sirve para un área de aplicación especial, la computación estadística. En este campo, R se ha mantenido durante años entre los 20 lenguajes de programación más populares, a pesar de la fuerte competencia.

Lo que hace que R sea especial no es solo el lenguaje en sí, sino todo el paquete. La programación en R suele realizarse en un entorno interactivo, con un loop de Read Eval Print (REPL) y ayuda integrada. Este lenguaje de código abierto está respaldado por un ecosistema muy desarrollado. La comunidad mantiene actualizado el repositorio de paquetes “The Comprehensive R Archive Network” (CRAN). También se aportan continuamente conjuntos de datos y libros blancos científicos sobre nuevos enfoques y paquetes.

En conjunto, estas características hacen de R el entorno de programación perfecto para la estadística y las ciencias de datos. El carácter interactivo del entorno invita a la investigación y permite el aprendizaje ameno del lenguaje y las matemáticas subyacentes.

R: un lenguaje de programación estadística y de datos

R es un lenguaje de programación estadística y conoce conceptos como la distribución normal, las pruebas estadísticas, los modelos y la regresión. Además de R, existen más lenguajes científicos comparables. Aparte del producto comercial Matlab, cabe mencionar el joven lenguaje Julia. Otro competidor fuerte en los últimos años también es Python.

A diferencia de Python, R tiene asistencia para la programación estadística. La principal diferencia radica en la forma en que el lenguaje opera sobre los valores. Los datos suelen ser plurales, por lo que en R se suele calcular con varios valores a la vez. Mientras que en casi todos los demás lenguajes el valor más simple es un solo número, en R este es un caso especial.

Veamos el enfoque de R para el procesamiento de datos con un ejemplo sencillo. Las operaciones matemáticas pueden realizarse en cualquier lenguaje de programación, también con R. Sumaremos dos números:


10 + 5
R

Hasta ahora, nada inusual. Sin embargo, en R se puede aplicar la misma operación de suma a una lista de números. Combinamos dos números en una lista y añadimos un valor constante:

# returns 15, 25
c(10, 20) + 5
R

Para los programadores experimentados, este es un resultado sorprendente. Ni siquiera un lenguaje moderno y dinámico como Python lo permite:

# throws an error
[10, 20] + 5
R

En R, incluso se pueden sumar dos listas. En este caso, los elementos de la lista no se combinan en una sola lista, sino que se realiza la operación matemática adecuada para cada elemento:

# returns 42, 69
c(40, 60) + c(2, 9)
R

En lenguajes más antiguos como Java o C++, se necesita un bucle para procesar varios elementos de una lista. Esto se debe a que estos lenguajes separan estrictamente los valores individuales (escalares) de las estructuras de datos compuestas (vectores). En R, el vector es la unidad básica: un escalar es un caso especial en la programación de R como vector de un elemento.

Lo especial de la estadística es que la característica precisión matemática se debilita. Se calcula con incertidumbres y datos imperfectos derivados de la realidad. Siempre puede fallar algo. Por suerte, R es tolerante a los errores hasta cierto punto. El lenguaje puede manejar los valores que faltan sin que se bloquee un script en ejecución.

Ilustremos la solidez del lenguaje con un ejemplo. Normalmente, en cualquier lenguaje de programación se puede provocar un fallo dividiendo un número por cero. A R, sin embargo, esto no le supone un problema. El resultado de la división por cero es el valor Inf, que puede ser fácilmente filtrado de los datos en un paso posterior de limpieza:

# list of divisors, containing zero
divisors = c(2, 4, 0, 10)
# returns `c(50, 25, Inf, 10)`
quotients = 100 / divisors
# filter out Inf; returns `c(50, 25, 10)`
cleaned_quotients = quotients[quotients != Inf]
R

R es compatible con la POO y la programación funcional

La programación con R es extremadamente flexible. El lenguaje no encaja de forma sencilla en la jerarquía de paradigmas de programación. Aunque se apoya en un sistema POO, es un lenguaje difícil de clasificar. En el uso diario, se emplean principalmente enfoques funcionales e imperativos. Destacan sobre todo las características funcionales, que son muy adecuadas para el procesamiento de datos.

Al igual que JavaScript, el sistema de objetos sobresale por su flexibilidad. Las funciones genéricas son comparables a las de Python, que pueden aplicarse a objetos de diferentes tipos. Por ejemplo, en la programación en R existe la función length(), análoga a la len() de Python.

¿Cómo funciona la programación en R?

La programación en R gira en torno a los datos, porque en eso se basa la estadística. Para desarrollar una solución a un problema en R, se necesita un conjunto de datos. Por desgracia, a menudo estos datos no existen en el momento del desarrollo. Así que muchas veces empezamos un proyecto de programación en R simulando datos. Escribimos el código, probamos la funcionalidad y posteriormente sustituimos los datos de prueba por datos reales.

¿Cómo se ejecuta el código R?

Al igual que Ruby o Python, R es un lenguaje de script dinámico e interpretado. A diferencia de lo que ocurre en el lenguaje de programación C, en R no hay separación entre el código fuente y el código ejecutable. El desarrollo suele realizarse de forma interactiva, es decir, se alimenta al intérprete línea por línea con código fuente, que se ejecuta inmediatamente. Las variables se crean automáticamente cuando se necesitan, y los nombres se vinculan en tiempo de ejecución.

El efecto de esta programación interactiva y dinámica es comparable a estar dentro del programa en marcha. Los objetos ya creados pueden examinarse y modificarse, y las nuevas ideas pueden probarse inmediatamente. El comando help da acceso a la documentación de la sintaxis y las funciones:

# view help for `for` syntax
help('for')
# view help for `c()` function
help(c)
R

Los archivos de script pueden cargarse dinámicamente desde el intérprete. El comando source funciona como el comando equivalente del shell. Cuando se abre, se lee el contenido de un archivo de texto fuente de R y se introduce en la sesión en curso:

source('path/to/file.r')
R

¿Cuál es la sintaxis del lenguaje de programación R?

El lenguaje de scripting utiliza las llaves conocidas de C y Java para delimitar los cuerpos de las funciones y las sentencias de control. A diferencia de Python, la indentación del código no afecta a su función. Los comentarios comienzan con una almohadilla, como en Ruby y Python, y no es necesario el punto y coma al final de una sentencia.

Con un poco de experiencia, se puede reconocer el código R inmediatamente, porque el lenguaje tiene algunas peculiaridades. Además del signo igual como operador de asignación, en la programación en R se utilizan dos operadores tipo flecha para las asignaciones. Esto permite invertir el sentido de la asignación:

# equivalent assignments
age <- 42
'Jack' -> name
person = c(age, name)
R

Otra característica típica del código R es una especie de notación de pseudoobjeto según el patrón object.method():

# test if argument is a number
is.numeric(42)
R

La función is.numeric parece ser un método numeric() que pertenece a un objeto llamado is. Sin embargo, este no es el caso. En la programación en R, el punto es un carácter regular. La función también podría llamarse is_numeric en lugar de is.numeric.

Para crear los omnipresentes vectores en la programación en R, se utiliza la función de concatenación c().

people.ages <- c(42, 51, 69)
R

Si se aplica la función a los vectores, estos se unen para formar un vector consistente:

# yields `c(1, 2, 3, 4)`
c(c(1, 2), c(3, 4))
R

A diferencia de la mayoría de los lenguajes de programación, en R la indexación de los elementos de un vector comienza en 1. Esto requiere acostumbrarse al principio, pero ayuda a evitar los temidos errores off by one. El mayor índice de un vector corresponde a la longitud de este:

# create a vector of names
people <- c('Jack', 'Jim', 'John')
# access the first name
people[1] == 'Jack'
# access the last name
people[length(people)] == 'John'
R

Al igual que en Python, también existe el concepto de “slicing” en la programación en R. Con un corte, se puede indexar un área parcial de un vector. Esto se basa en las secuencias compatibles de forma nativa con R. Creamos una secuencia de números y seleccionamos una parte:

# create vector of numbers between 42 and 69
nums = seq(42, 69)
# equivalent assignment using sequence notation
nums = 42:69
# using a sequence, slice elements 3 through 7
sliced = nums[3:7]
R

¿Cómo funcionan las estructuras de control en la programación en R?

Las operaciones básicas de la programación en R se definen para los vectores. Así, a menudo no se necesitan bucles, sino que se realiza una operación directamente sobre el vector completo, modificando los elementos individuales. Elevamos al cuadrado los diez primeros números positivos sin un bucle:

nums <- seq(10)
squares <- nums ** 2
squares[3] == 9
R

Cuando se utiliza el R For Loop, es importante tener en cuenta que no funciona de la misma manera que en C, Java o JavaScript. Sin los desvíos a través de una variable de bucle, la iteración se realiza directamente sobre los elementos como en Python.

people = c('Jim', 'Jack', 'John')
for (person in people) {
  print(paste('Here comes', person, sep = ' '))
}
R

Por supuesto, existe la bifurcación If else en R como estructura de control básica. Sin embargo, en muchos casos esto también puede sustituirse por funciones de filtro o por la indexación lógica de vectores. Crearemos un vector con la información de la edad y filtraremos los mayores y menores de 18 años en dos variables respectivamente, sin necesidad de un bucle o ramificación:

# create 20 ages between 1 and 99
ages = as.integer(runif(20, 1, 99))
# filter adults
adults = ages[ages > 18]
# filter children
children = ages[ages < 18]
# make sure everyone is accounted for
length(adults) + length(children) == length(ages)
R

En pro de la exhaustividad, el enfoque equivalente con estructuras de control:

# create 20 ages between 1 and 99
ages = as.integer(runif(20, 1, 99))
# start with empty vectors
adults = c()
children = c()

# populate vectors
for (age in ages) {
  if (age > 18) {
    adults = c(adults, age)
  }
  else {
    children = c(children, age)
  }
}
R

¿Qué se necesita para empezar a programar en R?

Para empezar a programar en R, todo lo que necesitas es una instalación local de R. Se pueden descargar instaladores para los principales sistemas operativos. Una instalación estándar de R incluye un intérprete GUI con REPL, ayuda integrada y editor. Para una codificación productiva, hay que utilizar uno de los editores de código establecidos. Con Rstudio dispondrás de una atractiva alternativa al entorno R.

¿Para qué proyectos es adecuado R?

La programación en R se utiliza con especial frecuencia en la ciencia y la investigación, por ejemplo, en la bioinformática y el aprendizaje automático. Sin embargo, el lenguaje es adecuado para todos los proyectos que utilizan modelos estadísticos o matemáticos. R es menos útil para el procesamiento de texto puro. Para ello, Python está claramente por delante.

Los cálculos y visualizaciones habituales en las hojas de cálculo pueden sustituirse por código R. Esto aporta limpieza, ya que los datos y el código no se mezclan en las celdas. También significa que el código puede escribirse una vez y aplicarse a varios conjuntos de datos. Además, no hay peligro de sobrescribir la fórmula de una celda cuando se hacen cambios manuales.

Para las publicaciones científicas, R se considera muy adecuado. La separación del código y los datos es lo que hace posible la reproducibilidad científica en primer lugar. El maduro ecosistema de herramientas y paquetes permite la creación de conductos de publicación eficientes. Las evaluaciones y visualizaciones se generan automáticamente a partir del código y los datos y se integran en documentos LaTeX o RMarkdown de alta calidad.

Consejo

La base perfecta para tu página web: escoge el alojamiento web con tráfico ilimitado económico de IONOS.