3.2: Variables y Datos
- Page ID
- 55116
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)Como la mayoría de los idiomas, R nos permite asignar datos a variables. De hecho, podemos hacerlo usando el operador =
asignación o el operador <-
, aunque este último es el más comúnmente encontrado y generalmente preferido.

Aquí, print ()
es una función, que imprime el contenido de su parámetro (a la ventana del intérprete en RStudio, o salida estándar en la línea de comandos). Esta función tiene el “efecto secundario” de imprimir la salida pero no devuelve nada. [1] Por el contrario, la función abs ()
devuelve el valor absoluto de su entrada sin ningún otro efecto.

El intérprete ignora #
caracteres y cualquier cosa después de ellos en una sola línea, por lo que podemos usarlos para insertar comentarios en nuestro código para explicación o para mejorar la legibilidad. Se ignoran las líneas en blanco, por lo que podemos agregarlas para mejorar la legibilidad también.
Puede que tengas curiosidad por qué el extra [1]
está incluido en la salida impresa; pronto volveremos a ese punto, pero por ahora, que baste decir que el número 4.4
es el primero (y único) de una colección de valores que se está imprimiendo.
El lado derecho de una asignación generalmente se evalúa primero, por lo que podemos hacer cosas complicadas como reutilizar nombres de variables en expresiones.

Los nombres de variables y funciones en R merecen una discusión especial. Hay una variedad de convenciones, pero una común que usaremos es la misma convención que usamos para Python: los nombres de variables deben (1) consistir solo en letras y números y guiones bajos, (2) comenzar con una letra minúscula, (3) usar guiones bajos para separar palabras y (4) ser significativos y descriptivos para hacer código más legibles.
En R, los nombres de variables y funciones también pueden incluir el.
carácter, que no contiene ningún significado especial (a diferencia de muchos otros idiomas). Entonces, alpha.abs <- abs (alpha)
no es algo raro de ver, aunque nos quedaremos con la convención alpha_abs <- abs (alpha)
. Las variables R pueden ser casi cualquier cosa, siempre y cuando estemos dispuestos a rodear el nombre con caracteres de retroceso. Entonces, `alpha abs` <- abs (alpha)
sería una línea válida de código, al igual que una siguiente línea como print (`alpha abs`)
, aunque esto no es recomendable.
Números, enteros, caracteres y lógicas
Uno de los tipos de datos más básicos en R es el “numérico”, también conocido como número flotante, o número flotante en otros idiomas. [2] R incluso apoya la notación científica para estos tipos.

R también proporciona un tipo separado para enteros, números que no tienen un valor fraccional. Son importantes, pero se ven con menos frecuencia en R principalmente porque los números se crean como números numéricos, aunque parezcan enteros.

Es posible convertir tipos numéricos a tipos enteros reales con la función.integer ()
, y viceversa con la función.numeric ()
.

Al convertir a un tipo entero, se eliminan las partes decimales y, por lo tanto, los valores se redondean hacia 0
(4.8
se convierte en 4
, y -4.8
se convertiría en -4
.)
El tipo de datos “carácter” contiene una cadena de caracteres (aunque, por supuesto, la cadena puede contener solo un carácter, o ningún carácter como en "
). Estos se pueden especificar usando comillas simples o dobles.

Concatenar cadenas de caracteres es más complicado en R que en algunos otros idiomas, así que lo cubriremos en el capítulo 32, “Carácter y datos categóricos”. (La función cat ()
funciona de manera similar, y nos permite incluir caracteres especiales como tabulaciones y nuevas líneas usando\ t
y\ n
, respectivamente; cat (“Shawn\ to'neil”)
generaría algo como Shawn O'Neil
.)
Los tipos de caracteres son diferentes de los enteros y los números, y no pueden ser tratados como ellos aunque se vean como ellos. Sin embargo, las funciones.character ()
y as.numeric ()
convertirán cadenas de caracteres al tipo respectivo si es posible hacerlo.

Por defecto, el intérprete R producirá una advertencia (NA inducidos por la conversión
) si tal conversión no tiene sentido, como en como.numeric (“Shawn”)
. También es posible convertir un tipo numérico o entero a un tipo de carácter, usando como.character ()
.

El tipo de datos “lógico”, conocido como tipo booleano en otros idiomas, es uno de los tipos más importantes para R. Estos tipos simples almacenan ya sea el valor especial TRUE
o el valor especial FALSE
(por defecto, estos también pueden ser representados por la taquigrafía T
y F
, aunque esta taquigrafía es menos preferida porque algunos codificadores usan ocasionalmente T
y F
para nombres de variables también). Las comparaciones entre otros tipos devuelven valores lógicos (a menos que resulten en una advertencia o error de algún tipo). Es posible comparar tipos de caracteres con comparadores como <
y >
; la comparación se realiza en orden lexicográfico (diccionario).

Pero ten cuidado: en R (y Python), tales comparaciones también funcionan cuando tal vez deberían resultar en un error: los tipos de caracteres pueden compararse válidamente con los tipos numéricos, y los valores de caracteres siempre se consideran más grandes. Esta propiedad en particular ha resultado en una serie de errores de programación.

R soporta <
, >
, <=
, >=
, ==
, y!
= comparaciones, y éstas tienen el mismo significado que para las comparaciones en Python (ver capítulo 17, “Flujo de control condicional”, para más detalles). Para los tipos numéricos, R sufre de la misma advertencia sobre la comparación de igualdad que Python y otros lenguajes: los errores de redondeo para números con expansiones decimales pueden componerse de formas peligrosas, por lo que la comparación numérica para la igualdad debe hacerse con cuidado. (Se puede ver esto tratando de ejecutar print (0.2 * 0.2/0.2 == 0.2)
, lo que resultará en FALSO
; nuevamente, vea el capítulo 17 para más detalles. [3]) La forma “oficial” de comparar dos números para la igualdad aproximada en R es bastante torpe:
Exploraremos algunas alternativas en capítulos posteriores.iSue (all.equal (a, b))
devuelve TRUE
si a y b
son aproximadamente iguales (o, si contienen múltiples valores, todos los elementos son).

Hablando de errores de programación, porque <-
es el operador de asignación preferido pero =
también es un operador de asignación, se debe tener cuidado al codificar con estos y los operadores de comparación ==
o <
. Considera las siguientes afirmaciones similares, todas las cuales tienen diferentes significados.
R también admite conexiones lógicas, aunque éstas adquieren una sintaxis ligeramente diferente a la de la mayoría de los otros lenguajes.
Conectivo | Significado | Ejemplo (con a <- 7 , b <- 3 ) |
---|---|---|
& | y: True si ambos lados son True | a < 8 & b == 3 # Verdadero |
| | o: True si uno o ambos lados son True | a < 8 | b == 9 # Verdadero |
! | not: Verdadero si lo siguiente es False | ! a < 3 # Verdadero |
Estos pueden agruparse con paréntesis, y por lo general deben ser para evitar confusiones.

Al combinar expresiones lógicas de esta manera, cada lado de un ampersand o |
debe dar como resultado una lógica, el código a == 9 | 7
no es lo mismo que un == 9 | a == 7
(y, de hecho, el primero siempre resultará en VERDADERO
sin previo aviso).
Debido a que R es un lenguaje tan dinámico, a menudo puede ser útil verificar a qué tipo de datos se refiere una variable en particular. Esto se puede lograr con la función class ()
, que devuelve una cadena de caracteres del tipo apropiado.

Esto lo haremos con frecuencia a medida que continuemos aprendiendo sobre varios tipos de datos R.
Ejercicios
Dado un conjunto de variables, a,
b
,c
yd
, encuentran asignaciones de ellas aVERDADERO
oFALSO
de tal manera que la variable deresultado
contengaVERDADERO
.- Sin ejecutar el código, intente razonar en qué resultaría
print (class (class (4.5)))
. - Intente convertir un tipo de carácter como
“1e-50"
a un tipo numéricocon.numeric ()
, y uno como“1x10^5"
. ¿Cuáles son los valores numéricos después de la conversión? Intente convertir el valor numérico0.00000001
a un tipo de carácter: ¿cuál es la cadena producida? ¿Cuáles son los números más pequeños y grandes que puedes crear? - La función
is.numeric ()
devuelve elTRUE
lógico si su entrada es de tipo numérico, yFALSE
en caso contrario. Las funcioneses.character ()
,is.integer ()
eis.logical ()
hacen lo mismo para sus respectivos tipos. Intente usar estos para probar si las variables específicas son tipos específicos. - ¿Qué sucede cuando ejecutas una línea como
print (“ABC"* 4)
? ¿Qué pasacon la impresión (“ABC” + 4)
? ¿Por qué crees que los resultados son lo que son? ¿Qué talimprimir (“ABC” + “DEF”)
? Por último, intente lo siguiente:imprimir (VERDADERO + 5)
,imprimir (VERDADERO + 7)
,imprimir (FALSO + 5)
,imprimir (FALSO + 7)
,imprimir (VERDADERO * 4)
eimprimir (FALSO * 4)
. ¿Qué crees que está pasando aquí?
- El intérprete R también imprimirá el contenido de cualquier variable o valor devuelto sin ser asignado a una variable. Por ejemplo, las líneas
alfa
y3 + 4
son equivalentes aprint (alpha)
eprint (3 + 4)
. Tales impresiones “sin impresión” son comunes en el código R, pero preferimos la llamada más explícita y legible a la funciónprint ()
. - Esto refleja el uso más común del término “numérico” en R, aunque quizás no el más preciso. R tiene un tipo
doble
que implementa números de coma flotante, y técnicamente tanto estos como los enteros son subtipos denúmeros
. - Debido a que los números enteros se almacenan por defecto como números numéricos (en lugar de enteros), esto puede causar cierta incomodidad al intentar compararlos. Pero debido a que los números enteros se pueden almacenar exactamente como números (sin redondear), declaraciones como
4 + 1 == 5
, equivalente a4.0 + 1.0 == 5.0
, resultarían enTRUE
. Aún así, algunos casos de división pueden causar un problema, como en(1/5) * (1/5)/(1/5) == (1/5) == (1/5)
.