Sintaxis R

Aprender un lenguaje de programación es como aprender un segundo idioma (sólo que más simple). Si visitamos un pais extranjero , podríamos aprender frases para salir del paso sin entender como está estructurado el lenguaje. De forma similar, si sólo queremos hacer un par de cosas con R (p. ej. dibujar gráficos), probablemente sea suficiente con estudiar a partir de unos cuantos ejemplos.

Sin embargo, si lo que queremos es aprender realmente bien un nuevo lenguaje, tendremos que aprender su sintaxis y gramática: conjugación verbos, estructuras gramaticales, etc. Lo mismo es cierto para R: si queremos aprender a programar en R, tendremos que aprender la sintaxis y gramática.

Objetos

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. A continuación se muestran algunos ejemplos de objetos:

# Una función es un objeto
function() {
    x <- 1
    y <- 2
    x + y
}
## function() {
##     x <- 1
##     y <- 2
##     x + y
## }

también su nombre (symbol)

f <- function(x, y) {
    x + y
}
f(1, 2)
## [1] 3

incluso las expresiones

{
    x <- 1
    y <- 2
    x + y
}
## [1] 3

Symbols

Formalmente, los nombres de las variables en R se designan como symbol. Cuando realizamos una asignación de un objeto al nombre de una variable, estamos en realidad asignando el objeto a un symbol. Por ejemplo, la instrucción:

x <- 1

asigna el symbol “\(x\)” al objeto “1” en el entorno actual.

Cada Objeto es Miembro de una Clase

Todos los objetos en R tienen una clase, la cual define que información contiene y como usarlo. Por ejemplo, la mayoría de números son numeric (lo veremos en la siguiente sección), y los valores lógicos pertenecen a la clase logical. En particular, puesto que R no dispone de un tipo para representar escalares, los vectores de números son numeric y los vectores de valores lógicos son logical. El tipo de dato “más pequeño” en R es un vector.

Podemos encontrar la clase de un objeto mediante la función class(objeto):

vector_numerico <- c(1, 2, 3, 4, 5)
class(vector_numerico)
## [1] "numeric"

Cada Objeto tiene un Tipo

Cada objeto en R tiene un tipo. El tipo define como es almacenado el objeto en R.

Podemos conocer el tipo de objeto con la función typeof(objeto):

vector_numerico <- c(1, 2, 3, 4, 5)
typeof(vector_numerico)
## [1] "double"

Comprobar la Clase de un Objeto en scripts

El uso de la función class() es útil para examinar nuestros objetos en un trabajo interactivo con la consola de R, pero si necesitamos comprobar el tipo de un objeto en nuestros scripts, es mejor el uso de la función is(). En una situación típica, nuestro test se parecerá al siguiente:

if (!is(x, "alguna_clase")) {

    # alguna acción correctiva
}
## NULL

La mayoría de las clases tienen su propia función is.*(), utilizar esta función es mas efectivo que el uso de la función general is().

Por ejemplo:

is.character("Ciencia de Datos con R")
## [1] TRUE

Podemos ver una lista completa de las funciones is() en el paquete base mediante la siguiente instrucción:

ls(pattern = "^is", baseenv())
##  [1] "is.array"                "is.atomic"              
##  [3] "is.call"                 "is.character"           
##  [5] "is.complex"              "is.data.frame"          
##  [7] "is.double"               "is.element"             
##  [9] "is.environment"          "is.expression"          
## [11] "is.factor"               "is.finite"              
## [13] "is.function"             "is.infinite"            
## [15] "is.integer"              "is.language"            
## [17] "is.list"                 "is.loaded"              
## [19] "is.logical"              "is.matrix"              
## [21] "is.na"                   "is.na.data.frame"       
## [23] "is.na.numeric_version"   "is.na.POSIXlt"          
## [25] "is.na<-"                 "is.na<-.default"        
## [27] "is.na<-.factor"          "is.na<-.numeric_version"
## [29] "is.name"                 "is.nan"                 
## [31] "is.null"                 "is.numeric"             
## [33] "is.numeric_version"      "is.numeric.Date"        
## [35] "is.numeric.difftime"     "is.numeric.POSIXt"      
## [37] "is.object"               "is.ordered"             
## [39] "is.package_version"      "is.pairlist"            
## [41] "is.primitive"            "is.qr"                  
## [43] "is.R"                    "is.raw"                 
## [45] "is.recursive"            "is.single"              
## [47] "is.symbol"               "is.table"               
## [49] "is.unsorted"             "is.vector"              
## [51] "isatty"                  "isBaseNamespace"        
## [53] "isdebugged"              "isFALSE"                
## [55] "isIncomplete"            "isNamespace"            
## [57] "isNamespaceLoaded"       "isOpen"                 
## [59] "isRestart"               "isS4"                   
## [61] "isSeekable"              "isSymmetric"            
## [63] "isSymmetric.matrix"      "isTRUE"

Nombres de los Objetos

Los nombres de los objetos pueden contener letras, números, puntos y guiones bajos, pero no pueden empezar con un número o un punto seguido de un número. Además, no podemos hacer uso de las palabras reservadas del lenguaje como if y for. La instrucción ?make.names describe en detalle lo que está y no permitido.

En resumen, los nombres de nuestros objetos :

  • Pueden contener:

– letras

– número

– guión bajo (_)

– punto (.)

  • Deben empezar con una letra.
  • No podemos utilizar las palabras reservadas del lenguaje.

Para la comunidad hispanohablante, cabe mencionar que para que nuestro código sea lo mas portable posible no debemos utilizar acentos y la letra “ñ”, es decir, debemos limitarnos a los caracteres de la “a” a la “z” ( y de la“A” a la “Z”).

Ejemplos:

  • alejandro
  • ALEJANDRO123
  • las_variables_pueden_contener_guiones
  • las.variables.pueden.contener.puntos
  • ALEJO_123.0

Convención para Nombres con Varias Palabras

Puesto que queremos que nuestros objetos tengan nombres descriptivos, necesitaremos una convención para objetos con múltiples palabras. Recomendamos usar el método snake_case dónde separamos las palabras en minúsculas con el guión bajo:

Ejemplos:

  • yo_uso_snake_case
  • otraGenteUsaCamelCase
  • alguna.gente.usa.puntos
  • Y_otra.Gente.RENUNICAconvención

Tipos de datos en R

R proporciona cuatro tipos básicos de datos, también conocidos como vectores atómicos.

  • logical
  • numeric
  • integer
  • character

Logical

El tipo logical es la forma que tiene R para los datos binarios. Usados en test lógicos son conocidos como valores boleanos y toman los valores TRUE y FALSE. TRUE y FALSE pueden ser abreviados con las T y F en mayúsculas respectivamente. Sin embargo, recomendamos utilizar la versión completa de TRUE y FALSE

3 < 4
## [1] TRUE
class(TRUE)
## [1] "logical"
class(T)
## [1] "logical"

también podemos identificar el tipo de dato, con el comando typeof()

typeof(FALSE)
## [1] "logical"

Es posible construir condiciones lógicas utilizando los operadores &, | y ! (en lenguaje formal, yy, oo y nono respectivamente). La comparación de valores se lleva a cabo mediante == (es igual a) y != (es distinto de):

a <- 2
b <- 4
a == b  # ¿es igual a b?
## [1] FALSE
a != b  # ¿es a distindo de b?
## [1] TRUE
(a < 3) & (b < 5)  # ¿es a menor que 3 y b menor que 3?
## [1] TRUE
(a < 1) | (b < 3)  # ¿es a menor que 1 o b menor que 3?
## [1] FALSE

A continuación se muestran los operadores de comparación y lógicos en R:

Símbolo Significado
& y(boleano)
| o(boleano)
! no
any Cualquiera verdadero
all Todos los valores
Símbolo Significado
> Mayor que
>= Mayor igual que
< Menor que
<= Menor igual que
== Igual
!= Diferente
%in% Pertenece a
is.na() Es un valor NA?
!is.na() Es valor distinto a NA?

Para mas información sobre la sintaxis de los operadores y su precedencia consultar la documentación R:

# Sintaxis de comparación
`?`(Comparison)
# Operadores lógicos
`?`(base::Logic)

Numeric

Para representar los números reales R proporciona el tipo numeric. Podemos realizar toda clase de operaciones con ellos como por ejemplo sumas, restas, multiplicaciones, divisiones y utilizarlos en el amplio catálogo de funciones matemáticas con las que cuenta R:

mi_altura_en_m <- 1.80
mi_altura_en_m
## [1] 1.8
mi_peso <- 79.5
mi_peso
## [1] 79.5
IMC <- mi_peso/mi_altura_en_m^2
IMC
## [1] 24.53704
round(mi_peso)
## [1] 80

Integer

Un tipo especial de numeric es el integer. Este es el modo de representar los números enteros en R. Para especificar que un número es entero, debemos añadir la letra L en mayúscula como sufijo.

mi_edad <- 40L
mi_edad
## [1] 40
mi_edad1 <- 40
mi_edad
## [1] 40

En el ejemplo anterior, no podemos apreciar la diferencia entre el número real y el número entero.Sin embargo, con la función class() podemos comprobar esta diferencia:

class(mi_edad)
## [1] "integer"
class(mi_edad1)
## [1] "numeric"

En lugar de preguntar por la clase de una variable mediante la función class(), podemos utilizar las funciones is.*() para comprobar si un objeto es realmente de un cierto tipo. Por ejemplo, para comprobar si una variable es numeric, usaremos la función is.numeric():

is.numeric(mi_edad)
## [1] TRUE
is.numeric(mi_edad1)
## [1] TRUE

Para comprobar si una variable es integer, usaremos la función is.integer():

is.integer(mi_edad)
## [1] TRUE
is.integer(mi_edad1)
## [1] FALSE

Como podemos ver en el ejemplo anterior los números reales son numeric, pero no todos los numeric son enteros.

Character

Cualquier dato alfanumérico (o cadenas, strings en inglés; todo aquello que no sea un número es una cadena) será interpretado por R como character. Por ejemplo:

nombre<-"Luis Alejanro Ferro Alfonso"
nombre
## [1] "Luis Alejanro Ferro Alfonso"
"Ciencia de Datos con R"
## [1] "Ciencia de Datos con R"

Otros Tipos de Datos Básicos

Por último, cabe señalar que existen otros tipos de datos básicos en R, como el double que es un tipo numérico de doble precisión. El complex para números complejos y el raw para almacenar bytes.Sin embargo, no los trataremos en este curso puesto que raramente se utilizan en el análisis de datos

  • Double (doble precisión)

  • Complex (números complejos)

  • Raw (almacenar bytes)

Coerción

La coerción es una característica de los lenguajes de programación que permite, implícita o explícitamente, convertir un elemento de un tipo de datos en otro, sin tener en cuenta la comprobación de tipos.

Coerción Implícita

Cuando llamamos a una función con un argumento de un tipo erróneo, R intentará convertir los elementos de un tipo de datos en otro, sin tener en cuenta la comprobación de tipos. Por ejemplo, supongamos que definimos un vector \(v\) como en el ejemplo:

v <- c(1, 2, 3, 4, 5)
v
## [1] 1 2 3 4 5

note que:

typeof(v)
## [1] "double"
class(v)
## [1] "numeric"

Si cambiamos el segundo elemento del vector con la palabra “coercion”. R cambiará la clase del objeto a character y todos los elementos del vector a char como podemos ver en el siguiente ejemplo:

v[2] <- "coercion"
typeof(v)
## [1] "character"
class(v)
## [1] "character"

Cuando un vector lógico es convertido a un integer o double, TRUE es cambiado a 1 y FALSE a 0:

v <- c(FALSE, TRUE, FALSE)
as.numeric(v)
## [1] 0 1 0

A continuación se muestra un resumen de las reglas para la coerción:

  • Los valores lógicos son transformados a números: TRUE será cambiado a 1 y FALSE a O.

  • Los valores son convertidos al tipo más simple.

  • El orden es: logical < integer < numeric < complex < character < list.

  • Los objetos de tipo raw no son convertidos a otros tipos.

  • Los atributos de los objetos son borrados cuando un objeto es cambiado de un tipo a otro.

Coerción Explícita

Los objetos pueden ser convertidos en otro tipo de foma explícita mediante el uso de la función as.()*

v <- c(1, 2, 3, 4, 5)
class(v)
## [1] "numeric"
as.logical(v)
## [1] TRUE TRUE TRUE TRUE TRUE
as.character(v)
## [1] "1" "2" "3" "4" "5"

En ocasiones, la conversión no puede ser llevada a cabo, en este caso R devuelve NA.

v <- c("a", "b", "c")
as.numeric(v)
## Warning: NAs introduced by coercion
## [1] NA NA NA
as.logical(v)
## [1] NA NA NA

En resumen, la mayoría de las funciones producen un error cuando el tipo de datos que esperan no coincide con los que pasamos como argumentos. En esta situación tenemos dos posibilidades:

  • Comprobar el tipo de datos utilizando las funciones is.*(), que nos responden con un valor lógico.

  • Forzar el tipo de datos deseados coercionando, para lo cual podemos utilizar funciones del tipo as.*(), que fuerzan el tipo de datos.

A continuación se muestra una lista con los tipos más importantes que se pueden comprobar o forzar:

Comprobación y coerción de los tipos más importantes

Podemos ver una lista completa de todas las funciones is.() en el paquete base mediante:

ls(pattern = "^is", baseenv())
##  [1] "is.array"                "is.atomic"              
##  [3] "is.call"                 "is.character"           
##  [5] "is.complex"              "is.data.frame"          
##  [7] "is.double"               "is.element"             
##  [9] "is.environment"          "is.expression"          
## [11] "is.factor"               "is.finite"              
## [13] "is.function"             "is.infinite"            
## [15] "is.integer"              "is.language"            
## [17] "is.list"                 "is.loaded"              
## [19] "is.logical"              "is.matrix"              
## [21] "is.na"                   "is.na.data.frame"       
## [23] "is.na.numeric_version"   "is.na.POSIXlt"          
## [25] "is.na<-"                 "is.na<-.default"        
## [27] "is.na<-.factor"          "is.na<-.numeric_version"
## [29] "is.name"                 "is.nan"                 
## [31] "is.null"                 "is.numeric"             
## [33] "is.numeric_version"      "is.numeric.Date"        
## [35] "is.numeric.difftime"     "is.numeric.POSIXt"      
## [37] "is.object"               "is.ordered"             
## [39] "is.package_version"      "is.pairlist"            
## [41] "is.primitive"            "is.qr"                  
## [43] "is.R"                    "is.raw"                 
## [45] "is.recursive"            "is.single"              
## [47] "is.symbol"               "is.table"               
## [49] "is.unsorted"             "is.vector"              
## [51] "isatty"                  "isBaseNamespace"        
## [53] "isdebugged"              "isFALSE"                
## [55] "isIncomplete"            "isNamespace"            
## [57] "isNamespaceLoaded"       "isOpen"                 
## [59] "isRestart"               "isS4"                   
## [61] "isSeekable"              "isSymmetric"            
## [63] "isSymmetric.matrix"      "isTRUE"

Asimismo, para obtener las funciones as.*() podemos hacerlo mediante la siguiente instrucción:

ls(pattern = "^as", baseenv())
##   [1] "as.array"                      "as.array.default"             
##   [3] "as.call"                       "as.character"                 
##   [5] "as.character.condition"        "as.character.Date"            
##   [7] "as.character.default"          "as.character.error"           
##   [9] "as.character.factor"           "as.character.hexmode"         
##  [11] "as.character.numeric_version"  "as.character.octmode"         
##  [13] "as.character.POSIXt"           "as.character.srcref"          
##  [15] "as.complex"                    "as.data.frame"                
##  [17] "as.data.frame.array"           "as.data.frame.AsIs"           
##  [19] "as.data.frame.character"       "as.data.frame.complex"        
##  [21] "as.data.frame.data.frame"      "as.data.frame.Date"           
##  [23] "as.data.frame.default"         "as.data.frame.difftime"       
##  [25] "as.data.frame.factor"          "as.data.frame.integer"        
##  [27] "as.data.frame.list"            "as.data.frame.logical"        
##  [29] "as.data.frame.matrix"          "as.data.frame.model.matrix"   
##  [31] "as.data.frame.noquote"         "as.data.frame.numeric"        
##  [33] "as.data.frame.numeric_version" "as.data.frame.ordered"        
##  [35] "as.data.frame.POSIXct"         "as.data.frame.POSIXlt"        
##  [37] "as.data.frame.raw"             "as.data.frame.table"          
##  [39] "as.data.frame.ts"              "as.data.frame.vector"         
##  [41] "as.Date"                       "as.Date.character"            
##  [43] "as.Date.default"               "as.Date.factor"               
##  [45] "as.Date.numeric"               "as.Date.POSIXct"              
##  [47] "as.Date.POSIXlt"               "as.difftime"                  
##  [49] "as.double"                     "as.double.difftime"           
##  [51] "as.double.POSIXlt"             "as.environment"               
##  [53] "as.expression"                 "as.expression.default"        
##  [55] "as.factor"                     "as.function"                  
##  [57] "as.function.default"           "as.hexmode"                   
##  [59] "as.integer"                    "as.list"                      
##  [61] "as.list.data.frame"            "as.list.Date"                 
##  [63] "as.list.default"               "as.list.difftime"             
##  [65] "as.list.environment"           "as.list.factor"               
##  [67] "as.list.function"              "as.list.numeric_version"      
##  [69] "as.list.POSIXct"               "as.list.POSIXlt"              
##  [71] "as.logical"                    "as.logical.factor"            
##  [73] "as.matrix"                     "as.matrix.data.frame"         
##  [75] "as.matrix.default"             "as.matrix.noquote"            
##  [77] "as.matrix.POSIXlt"             "as.name"                      
##  [79] "as.null"                       "as.null.default"              
##  [81] "as.numeric"                    "as.numeric_version"           
##  [83] "as.octmode"                    "as.ordered"                   
##  [85] "as.package_version"            "as.pairlist"                  
##  [87] "as.POSIXct"                    "as.POSIXct.Date"              
##  [89] "as.POSIXct.default"            "as.POSIXct.numeric"           
##  [91] "as.POSIXct.POSIXlt"            "as.POSIXlt"                   
##  [93] "as.POSIXlt.character"          "as.POSIXlt.Date"              
##  [95] "as.POSIXlt.default"            "as.POSIXlt.factor"            
##  [97] "as.POSIXlt.numeric"            "as.POSIXlt.POSIXct"           
##  [99] "as.qr"                         "as.raw"                       
## [101] "as.single"                     "as.single.default"            
## [103] "as.symbol"                     "as.table"                     
## [105] "as.table.default"              "as.vector"                    
## [107] "as.vector.factor"              "asin"                         
## [109] "asinh"                         "asNamespace"                  
## [111] "asplit"                        "asS3"                         
## [113] "asS4"                          "assign"

Valores Especiales

Para ayudarnos con los cálculos aritméticos R, soporta cuatro valores numéricos especiales:

  • Inf

  • -Inf

  • NaN

  • Na

Los dos primeros, son la forma positiva y negativa para valores infinitos. NaN (del inglés, “not-a-number”) significa que nuestro cálculo o no tiene sentido matemático o que podría no haberse realizado correctamente. NA (del inglés, “not available”) representa un valor desconocido.

Inf y -Inf

Si una computación resulta en un número que es demasiado grande, R devolverá Inf para un numero positivo y -Inf para un número negativo (esto es un valor infinito positivo y infinito negativo, respectivamente):

2^1024
## [1] Inf
-2^1024
## [1] -Inf

Esto es también cierto cuando hacemos la división entre 0:

1/0
## [1] Inf

NaN

En ocasiones, una computación producirá un resultado que no tiene sentido. En estos casos, R devolverá NaN (del inglés, “not a number”):

Inf - Inf
## [1] NaN
0/0
## [1] NaN

NA

En R, los valores NA son usados para representar valores desconocidos. (NA es la abreviación “not available”). Nos encontraremos valores NA en texto importado a R (representando valores desconocidos) o datos importados desde bases de datos (para reemplazar valores NULL).

A modo de ejemplo, si el vector peso recoge los pesos de 5 personas, habiéndose perdido el cuarto valor, se codificaría como:

peso <- c(77, 68, 85, NA, 73)

Si pretendemos calcular el peso medio, obtendremos como resultado un valor perdido:

mean(peso)
## [1] NA

Si, en cualquier caso, deseamos calcular la media de los pesos efectivamente disponibles, utilizaríamos la opción de eliminar valores perdidos (del inglés, NA remove) que se declara como na.rm=TRUE:

mean(peso, na.rm = TRUE)
## [1] 75.75

también se puede usar la siguiente función na.omit()

peso1<-na.omit(peso)

ahora calculamos la media

mean(peso1)
## [1] 75.75

Guía Estilo R

Los estándares para el estilo en el código no son lo mismo que la sintaxis del lenguaje, aunque están estrechamente relacionados. Es importante adoptar un buen estilo para maximizar la legibilidad de nuestro código para que su mantenimiento sea más fácil tanto para nosotros como otros programadores o usuarios.

Nombres de Archivos

En los nombres de los archivos debemos usar nombres descriptivos, no tienen que incluir caracteres especiales (tildes, eñes) y asegurarse que su extensión es “.R”

# Bien

regresion_lineal.R

lectura_datos.R

# Mal

regresión_lineal.R

version del lunes.R

Nombres de los Objetos

Los nombres de los objetos y funciones deben ser en minúscula y hemos de separar con guión bajo (_) aquellos nombres compuestos de varias palabras. Wickham recomienda usar sustantivos para los nombres de los objetos y verbos para las funciones. Debemos elegir nombres concisos y descriptivos para nuestros objetos (tarea nada fácil). Para la comunidad hispanohablante recomendamos no utilizar tildes y eñes en los nombres de los objetos.

# Bien

primer_cuartil

cuartil_1

# Mal

CuartilUno

C1

está_en_el_primer_cuartil

Espacios

Antes y después de todos los operadores infijos (=, +, <-, etc) hay que colocar un espacio. No hay que dejar espacios después de una coma, pero una coma siempre es seguida de un espacio.

# Bien
hipotenusa <- sqrt( a ^ 2 + b ^ 2)
v <- c(1, 2, 3)
hipotenusa <- sqrt(a^2 + b^2)
v <- c(1, 2, 3)

La excepción a esta regla

# Bien
vector <- 1:10
# Mal
vector <- 1 : 10

Antes del paréntesis izquierdo va un espacio, a no ser que estemos llamando a una función.

# Bien
if (1 > 2) "mayor" else "menor"
## [1] "menor"
mean(1:10)
## [1] 5.5
# Mal
if(1 > 2) "mayor" else "menor"
## [1] "menor"
mean (1:10)
## [1] 5.5

Punto y coma

Se recomienda no usar punto y coma en nuestras expresiones.

# Bien
x <- 1
y <- 2
z <- 3
# Mal
x <- 1; y <- 2; z <- 3

Llaves

Abrir una llave nunca debería ocurrir en su propia línea y siempre se sigue con una línea nueva. La llave que cierra siempre tiene que ir su propia línea, a menos que se trate de else. Siempre usaremos llaves aunque el cuerpo de la estructura de control contenga sólo una instrucción.

Dentro de las llaves utilizaremos sangrado para indicar que se trata de un bloque de instrucciones.

# Bien
if (1 < 2) {
  "mayor"
  } else {
  "menor"
}
## [1] "mayor"
if (x == 0) {
  "cero"
}
# Mal 
if (1 < 2) 
{
"mayor"
} 
else {
"menor"
}

if (x == 0) 
"cero"

Longitud de Líneas

La longitud de nuestras líneas debe tener como máximo 80 caracteres. Si usamos RStudio podemos activarlo en:

\[Tools -> Global\, \, Options -> Code -> Display\] seleccionando la casilla \[[] Show \, \, margin\, \, Margin \, \, column\, \, [80]\]

nos aparecerá una guía en el editor indicando el límite hasta donde podemos escribir nuestra línea (ver figura ).

Longitud linea en RStudio

Sangría

Respecto a la sangría en nuestro código se sugiere usar dos espacios para añadir sangría a nuestro código y nunca la tecla TAB. En el caso que usemos RStudio podemos configurar la tecla TAB para que utilice dos espacios en:(ver figura )

\[Tools -> Global\, \, Options -> Code -> Editing\]

Tabulador en RStudio

Asignación

En la instrucción de asignación se aconseja el uso del operador \(<-\) en lugar de \(=\), reservando este último para declarar argumentos dentro de las funciones.

# Bien
x <- 2

# Mal
x = 2

Comentarios

Recomendamos documentar el código mediante el uso de comentarios. Cada linea debe comenzar con el signo almohadilla \((\#)\) seguido de un espacio en blanco. Los comentarios deben explicar el porqué, y no el qué.

Para separa y estructurar el código en bloques es común el uso de más de una almohadilla #. RStudio ofrece las características de Code Folding y Sections que nos permite mostrar y ocultar bloques de código permitiendo una navegación más fácil en nuestros archivos.(ver figura ).

Code folding & Sections en RStudio

Resumen

  • Creamos nuevos objetos con el operador de asignación <-.

  • Podemos conocer el tipo de un objeto con la función typeof().

  • Todos los objetos pertenecen a una clase.

  • Mediante la función class() hallaremos la clase a la que pertenece un objeto.

  • Alternativamente, podemos comprobar la clase de un objeto mediante la función is, o mediante una de sus variantes específicas.

  • Podemos cambiar la clase de un objeto mediante la función as, o una de sus variantes específicas.

  • R proporciona valores especiales para el \(\infty\) y \(-\infty\), NaN (not-a-number) y NA (valores desconocidos).