R es un lenguaje de tipado dinámico, por lo que, en general, no es necesario especificar el tipo de una variable. El tipo predeterminado es numeric, que normalmente se implementa como un número de coma flotante de doble precisión. Para forzar el uso de enteros de 32 bits, usa el sufijo L (abreviatura de Long).
Obtener el «tipo» de un objeto puede resultar confuso (por razones históricas).
Las funciones typeof() y class() son similares, pero pueden devolver resultados ligeramente distintos:
typeof(50)
#> [1] "double" # more specific: an implementation detail
typeof(50L)
##> [1] "integer"
class(50)
#> [1] "numeric" # less specific: ignores implementation details
class(50L)
#> [1] "integer"
También puedes ver referencias a mode(), que es similar a typeof().
Ignora mode() y storage.mode().
Solo se incluyen por retrocompatibilidad.
El operador de asignación preferido es <-.
Si trabajas en RStudio, puedes introducirlo con el atajo de teclado Alt-minus.
x <- 42
avogadro <- 6.02e23
mystr <- "Hello, World!"
Usar = en lugar de <- a menudo funciona, pero no siempre, y se desaconseja por ser un mal estilo.
Los operadores son en su mayoría similares a los de muchos otros lenguajes, aunque %% y %/% son más inusuales.
Esta sintaxis con % es una forma de llamar a operadores infijos implementados como macros.
2 + 3 # 5
2 - 3 # -1
2 * 3 # 6
2 / 3 # 0.6666667
8 %/% 3 # 2 (integer division)
8 %% 3 # 2 (remainder)
2 ^ 3 # 8 (exponential)
En R, # inicia un comentario de una sola línea.
No hay una sintaxis aparte para los comentarios de varias líneas.
Para definir una función:
squareit <- function(x) {
x * x
}
Las funciones pueden tener cero o más argumentos, separados por comas.
Los paréntesis () son necesarios con function(), incluso si no hay parámetros.
Se pueden especificar valores predeterminados para los argumentos de una función, aunque estos deben ir después de los argumentos que no tienen valor predeterminado, y se usa = en lugar de <- para asignar el valor predeterminado.
Como ejemplo un tanto inútil:
squareit <- function(x = 42) {
x * x
}
squareit()
#> [1] 1764
Las llaves { } no son estrictamente necesarias para cuerpos de función de una sola línea, pero incluirlas se considera un buen estilo.
R devolverá automáticamente el valor final de una función, como en los ejemplos anteriores.
Se puede usar return() en cualquier parte del cuerpo de la función para hacer explícito un valor devuelto.
Devolverá el valor especificado de inmediato y terminará la función sin ejecutar el resto de las expresiones del cuerpo de la función.
Normalmente, solo es necesario llamar explícitamente a return() si se quiere salir antes de la función y devolver un valor concreto por algún motivo.
Un ejemplo podría ser dentro de una cláusula if-else.
No obstante, algunos desarrolladores prefieren los retornos explícitos por una cuestión de estilo de código.
Llamar a una función es igual que en muchos otros lenguajes:
squareit(3)
#> [1] 9
En futuros conceptos veremos que el resultado 9 es en realidad un vector de longitud 1, no un número escalar.
De ahí la inclusión de [1] para indicar que este es el comienzo del vector.
is.vector(9)
#> [1] TRUE
¡La mayoría de las cosas en R son algún tipo de vector!
La consola de R mostraría el ejemplo anterior así:
> squareit(3)
[1] 9
Los documentos de este temario siguen en su mayoría la convención usada en varios libros de texto de R: quitar el prompt y comentar el resultado. Esto facilita copiar y pegar los ejemplos de código en la consola y ejecutarlos.