Saltar al contenido principal
LibreTexts Español

3.3: Vectores

  • Page ID
    55117
  • \( \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}}\)

    Los vectores (similares a las matrices de tipo único en otros lenguajes) son colecciones ordenadas de tipos simples, generalmente numéricos, enteros, caracteres o lógicas. Podemos crear vectores usando la función c () (para concatenar), que toma como parámetros los elementos a poner en el vector:

    III.3_1_R_18_Numeric_Vector

    La función c () también puede tomar otros vectores como parámetros; “deconstruirá” todos los subvectores y devolverá un vector grande, en lugar de un vector de vectores.

    III.3_2_R_19_C_deconstructo

    Podemos extraer elementos individuales de un vector usando la sintaxis []; aunque tenga en cuenta que, a diferencia de muchos otros lenguajes, el primer elemento está en el índice 1.

    III.3_3_R_20_Bracket_Extract

    La función length () devuelve el número de elementos de un vector (o tipos similares, como listas, que cubriremos más adelante) como un entero:

    III.3_4_R_21_vec_longitud

    Podemos usar esto para extraer el último elemento de un vector, por ejemplo.

    imagen

    Sin “datos desnudos”: los vectores tienen (a) clase

    En lo que va de nuestra discusión sobre los tipos de datos de R, hemos estado haciendo una simplificación, o al menos hemos estado dejando algo fuera. Incluso los valores individuales como el 4.6 numérico son en realidad vectores de longitud uno. Es decir, gc_content <- 0.34 es equivalente a gc_content <- c (0.34), y en ambos casos, length (gc_content) devolverá 1, que en sí mismo es un vector de longitud uno. Esto se aplica a los números, enteros, lógicos y tipos de caracteres. Así, al menos comparado con otros lenguajes, R no tiene “datos desnudos”; el vector es la unidad de datos más básica que tiene R. Esto es un poco más confuso para los tipos de caracteres que otros, ya que cada elemento individual es una cadena de caracteres de cualquier longitud (incluyendo potencialmente la cadena “vacía” “”).

    III.3_6_R_22_2_Char_VEC

    Esto explica bastante sobre R, incluyendo algunas curiosidades como por qué print (gc_content) imprime [1] 0.34. Esta salida indica que gc_content es un vector, cuyo primer elemento es 0.34. Considere la función seq (), que devuelve un vector de números; toma tres parámetros: [1] (1) el número en el que comenzar, (2) el número en el que terminar, y (3) el tamaño del paso.

    III.3_7_R_23_SEQ_Range

    Cuando imprimimos el resultado, obtendremos una salida como la siguiente, donde la lista de números está formateada de tal manera que abarca el ancho de la ventana de salida.

    III.3_8_R_24_SEQ_RANGE_OUT

    Los números entre paréntesis indican que el primer elemento del vector impreso es 1.0, el decimosexto elemento es 8.5 y el trigésimo primer elemento es 16.0.

    Por cierto, para producir una secuencia de enteros (en lugar de numéricos), se puede dejar el argumento de tamaño de paso, como en seq (1,20). Esto equivale a una taquigrafía comúnmente vista, 1:20.

    Si todos nuestros enteros, lógicas, etc. son realmente vectores, y podemos decir su tipo ejecutando la función class () en ellos, entonces los vectores deben ser las cosas de las que estamos examinando la clase. Entonces, ¿y si intentamos mezclar tipos dentro de un vector, por ejemplo, incluyendo un entero con algunas lógicas?

    III.3_9_R_25_Mix_Class1

    Ejecutar print (class (mix)) dará como resultado “integer”. De hecho, si intentamos imprimir mezcla con print (mix), encontraríamos que las lógicas se han convertido en enteros!

    III.3_10_R_26_mix_class1_out

    R ha optado por convertir TRUE en 1 y FALSE en 0; estos son valores binarios estándar para true y false, mientras que no hay un valor lógico estándar para un entero dado. Del mismo modo, si se agrega un numérico, todo se convierte a numérico.

    III.3_11_R_27_Mix_Class2

    Y si se agrega una cadena de caracteres, todo se convierte en una cadena de caracteres (con 3.5 convirtiéndose en “3.5", TRUE convirtiéndose en “TRUE”, y así sucesivamente).

    III.3_12_R_28_MIX_CLASS3

    En resumen, los vectores son la unidad más básica de datos en R, y no pueden mezclar tipos: R autoconvertirá cualquier tipo mixto en un solo vector a un “denominador común más bajo”, en el orden de lógico (más específico), entero, numérico, carácter (más general). Esto a veces puede resultar en errores difíciles de encontrar, especialmente al leer datos de un archivo. Si un archivo tiene una columna de lo que parece ser números, pero un solo elemento no puede interpretarse como un número, todo el vector se puede convertir a un tipo de carácter sin advertencia ya que se lee el archivo. Discutiremos la lectura de datos de archivos de texto después de examinar los vectores y sus propiedades.

    Subestablecimiento de Vectores, Sustitución Selectiva

    Considere el hecho de que podemos usar la sintaxis [] para extraer elementos individuales de vectores:

    III.3_13_R_29_extracto_vec1

    Con base en lo anterior, sabemos que los 20 extraídos son un vector de longitud uno. El 2 utilizado entre corchetes también es un vector de longitud uno; así la línea anterior es equivalente a second_el <- nums [c (2)]. ¿Significa esto que podemos usar vectores más largos para extraer elementos? ¡Sí!

    III.3_14_R_30_extracto_vec2

    De hecho, los elementos extraídos incluso se colocaron en el vector de dos elementos resultante en el orden en que se extrajeron (el tercer elemento seguido del segundo elemento). Podemos usar una sintaxis similar para reemplazar selectivamente elementos por índices específicos en vectores.

    III.3_15_R_31_selective_replace_index

    El reemplazo selectivo es el proceso de reemplazar elementos seleccionados de un vector (o estructura similar) especificando qué elementos reemplazar con [] sintaxis de indexación combinada con asignación <-. [2]

    Los vectores R (y muchos otros tipos de contenedores de datos) pueden ser nombrados, es decir, asociados con un vector de caracteres de la misma longitud. Podemos establecer y posteriormente obtener este vector de nombres usando la función names (), pero la sintaxis es un poco extraña.

    imagen

    Los vectores con nombre, cuando se imprimen, también muestran sus nombres. El resultado de arriba:

    III.3_17_R_33_Nombrado_Vec1_out

    Los vectores nombrados pueden no parecer tan útiles ahora, pero el concepto será bastante útil más adelante. Los vectores con nombre nos dan otra forma de subconjunto y reemplazar selectivamente en vectores: por nombre.

    III.3_18_R_34_Nombre_Vec_Set

    Aunque R no lo hace cumplir, los nombres deben ser únicos para evitar confusiones a la hora de seleccionar o reemplazar selectivamente de esta manera. Al actualizar la puntuación de Estudiantes A y Estudiantes B, el cambio se refleja en la salida:

    III.3_19_R_35_Nombrado_Vec_Set_out

    Hay una forma final y extremadamente poderosa de subestablecer y reemplazar selectivamente en un vector: por vector lógico. Al indexar con un vector de lógicas de la misma longitud que el vector a indexar, podemos extraer solo aquellos elementos donde el vector lógico tenga un valor VERDADERO.

    III.3_20_R_36_Selección_lógica

    Si bien la indexación por número de índice y por nombre nos permite extraer elementos en cualquier orden dado, la indexación por lógica no nos brinda esta posibilidad.

    También podemos realizar el reemplazo selectivo de esta manera; supongamos que Estudiantes A y C retoman sus cuestionarios y mejoran moderadamente sus puntajes.

    III.3_21_R_37_Lógical_Repuesto

    Y la salida impresa:

    III.3_22_R_38_Logical_Replacement_out

    En este caso, la longitud del vector de reemplazo (c (159, 169)) es igual al número de valores VERDADEROS en el vector de indexación (c (VERDADERO, FALSO, VERDADERO)); exploraremos si esto es un requisito a continuación.

    En resumen, tenemos tres formas importantes de indexar en/seleccionar desde/reemplazar selectivamente en vectores:

    1. por vector de número de índice,
    2. por vector de caracteres (si se nombra el vector), y
    3. por vector lógico.

    Operaciones vectorizadas, valores NA

    Si los vectores son la unidad de datos más básica en R, todas las funciones y operadores con los que hemos estado trabajando, como.numeric (), * e incluso comparaciones como > —funcionan implícitamente sobre vectores enteros.

    III.3_23_R_39_Vectorizado_Conversion

    En este ejemplo, cada elemento del vector de caracteres se ha convertido, de modo que la clase (numérica) devolverá “numérico”. La cadena de caracteres final, “9b3x”, no se puede convertir razonablemente a un tipo numérico, por lo que ha sido reemplazada por NA. Cuando esto sucede, el intérprete produce un mensaje de advertencia: NA introducidos por coerción.

    NA es un valor especial en R que indica datos faltantes o un cálculo fallido de algún tipo (como al intentar convertir “9b3x” a un numérico). La mayoría de las operaciones que involucran valores NA devuelven valores NA; por ejemplo, NA + 3 devuelve NA, y muchas funciones que operan en vectores enteros devuelven un NA si algún elemento es NA. Un ejemplo canónico es la función mean ().

    III.3_24_R_40_Mean_na

    Dichas funciones suelen incluir un parámetro opcional que podemos dar, na.rm = TRUE, especificando que los valores NA deben eliminarse antes de que se ejecute la función.

    III.3_25_R_41_Mean_na_RM

    Si bien esto es conveniente, hay una manera de eliminar los valores de NA de cualquier vector (ver más abajo).

    Otros valores especiales en R incluyen NaN, para “Not a Number”, devueltos por cálculos como la raíz cuadrada de -1, sqrt (-1) e Inf para “Infinity”, devueltos por cálculos como 1/0. (Inf/Inf, por cierto, devuelve NaN.)

    Volviendo al concepto de operaciones vectorizadas, también se vectorizan operaciones aritméticas simples como +, *,/, -, ^ (exponente) y%% (módulo), lo que significa que una expresión como 3 * 7 es equivalente a c (3) * c (7). Cuando los vectores son más largos que un solo elemento, la operación se realiza elemento por elemento.

    III.3_26_R_42_Vec_mult
    III.3_27_multiplicación_vectorizada_

    Si consideramos el operador *, toma dos entradas (numéricas o enteras) y devuelve una salida (numérica o entera) para cada par de los vectores. Esto es bastante similar a la comparación >, que toma dos entradas (numéricas o enteras o caracteres) y devuelve una lógica.

    III.3_28_R_43_Vec_Comparar

    Reciclaje de vectores

    ¿Qué pasa si tratamos de multiplicar dos vectores que no tienen la misma longitud? Resulta que el más corto de los dos se reutilizará según sea necesario, en un proceso conocido como reciclaje vectorial, o la reutilización del vector más corto en una operación vectorizada.

    III.3_29_R_44_Vector_Reciclaje

    Esto funciona bien cuando se trabaja con vectores de longitud uno contra vectores más largos, ya que el vector de longitud uno se reciclará según sea necesario.

    III.3_30_R_45_Vector_Reciclado_Sencillo

    Si la longitud del vector más largo no es un múltiplo de la longitud del más corto, sin embargo, el último reciclado irá solo a la mitad.

    III.3_31_R_46_vector_reciclado_noneven

    Cuando esto sucede, el intérprete imprime una advertencia: la longitud del objeto más larga no es un múltiplo de la longitud del objeto más corta. Son pocas las situaciones en las que este tipo de reciclaje parcial no sea un accidente, y se debe evitar.

    El reciclaje de vectores también se aplica al reemplazo selectivo; por ejemplo, podemos reemplazar selectivamente cuatro elementos de un vector con elementos de un vector de dos elementos:

    III.3_32_R_46_Vector_Reciclado_Repuesto

    Más a menudo reemplazaremos selectivamente elementos de un vector con un vector de longitud uno.

    III.3_33_R_47_vector_reciclado_reemplazo_individual

    Estos conceptos, cuando se combinan con indexación vectorial de diversos tipos, son bastante poderosos. Considera que una expresión como valores > 35 es ella misma vectorizada, con el vector más corto (sosteniendo solo 35) siendo reciclado de tal manera que lo que se devuelve es un vector lógico con valores VERDADEROS donde los elementos de valores son mayores que 35. Podríamos usar este vector como vector de indexación para reemplazo selectivo si lo deseamos.

    III.3_34_R_48_vector_reciclado_reemplazo_lógico

    Más sucintamente, en lugar de crear una variable temporal para select_vec, podemos colocar los valores de expresión > 35 directamente entre paréntesis.

    III.3_35_R_49_vector_reciclado_reemplazo_lógico2

    Del mismo modo, podríamos usar el resultado de algo así como media (valores) para reemplazar todos los elementos de un vector mayor que la media con 0 fácilmente, ¡sin importar el orden de los elementos!

    III.3_36_R_50_vector_reciclado_reemplazo_logical3

    Más a menudo, vamos a querer extraer dichos valores usando selección lógica.

    III.3_37_R_51_vector_reciclado_selección

    Este tipo de selecciones vectorizadas, especialmente cuando se combinan con vectores lógicos, son una parte poderosa e importante de R, así que estudiarlas hasta que tengas confianza con la técnica.

    Ejercicios

    1. Supongamos que tenemos r como un rango de números de 1 a 30 en pasos de 0.3; r<- seq (1, 30, 0.3). Usando solo la función.integer (), la indexación lógica y las comparaciones como >, genera una secuencia r_decimales que contiene todos los valores de r que no son enteros redondos. (Es decir, debe contener todos los valores de r excepto 1.0, 2.0, 3.0, y así sucesivamente. Debe haber 297 de ellos.)
    2. Mencionamos brevemente el operador%%, o “módulo”, que devuelve el resto de un número después de la división entera (por ejemplo, 4%% 3 == 1 y 4%% 4 == 0; también se vectoriza). Dado cualquier vector r, por ejemplo r <- seq (1, 30, 0.3), producir un vector r_every_other que contiene todos los demás elementos de r. Es probable que desee usar%%, la comparación de igualdad ==, y también puede que desee usar seq () para generar un vector de índices de la misma longitud que r.

      Vuelva a hacer lo mismo, pero modifique el código para extraer cada tercer elemento de r en un vector llamado r_every_third.

    3. Del capítulo 27, “Variables y Datos”, sabemos que las comparaciones como ==,! =, >= también están disponibles. Además, ¡eso lo sabemos! niega los valores de un vector lógico, mientras que & combina dos vectores lógicos con “y” y | combina dos vectores lógicos con “o”. Úselos, junto con el operador%% discutido anteriormente, para producir un vector div_3_4 de todos los enteros entre 1 y 1,000 (inclusive) que son uniformemente divisibles por 3 y uniformemente divisibles por 4. (Hay 83 de ellos.) Crear otro, not_div_5_6, de números que no sean divisibles uniformemente por 5 o 6. (Son 667 de ellos. Por ejemplo, no se debe incluir 1,000 porque es divisible por 5, y 18 no debe incluirse porque es divisible por 6, sino 34 debe ser porque no es divisible por ninguno.)

    Funciones Vectoriales Comunes

    Como los vectores (específicamente los vectores numéricos) son tan ubicuos, R tiene docenas (cientos, en realidad) de funciones que hacen cosas útiles con ellos. Si bien no podemos cubrirlos todos, podemos cubrir rápidamente algunos que serán importantes en futuros capítulos.

    Primero, ya hemos visto las funciones seq () y length (); la primera genera un vector numérico que comprende una secuencia de números, y la segunda devuelve la longitud de un vector como un vector entero de un solo elemento.

    III.3_38_R_52_SEQ_LONGITUD

    Presentados sin un ejemplo, la media (), sd () y la mediana () devuelven la media, la desviación estándar y la mediana de un vector numérico, respectivamente. (Siempre que ninguno de los elementos de entrada sea NA, aunque los tres aceptan el parámetro na.rm = TRUE). Generalizando median (), la función quantile () devuelve el percentil Y de una función, o múltiples percentiles si el segundo argumento tiene más de un elemento.

    III.3_39_R_53_Cuantil

    La salida es un vector numérico con nombre:

    III.3_40_R_54_cuantile_out

    La función unique () elimina duplicados en un vector, dejando los elementos restantes en orden de su primera aparición, y la función rev () invierte un vector.

    III.3_41_R_55_Unique_rev

    Existe la función sort (), que ordena un vector (en orden natural para números y enteros, y orden lexicográfico (diccionario) para vectores de caracteres). Quizás más interesante es la función order (), que devuelve un vector entero de índices que describen dónde se necesitarían colocar los elementos originales del vector para producir un orden ordenado.

    III.3_42_R_56_Orden

    En este ejemplo, el vector de orden, 2 5 3 4 1, indica que el segundo elemento de rev_uniq vendría primero, seguido del quinto, y así sucesivamente. Así podríamos producir una versión ordenada de rev_uniq con rev_uniq [order_rev_uniq] (en virtud de la selección basada en índices de vectores), o más sucintamente con rev_uniq [order (rev_uniq)].

    III.3_43_pedido_ejemplo

    Es importante destacar que esto nos permite reorganizar múltiples vectores con un orden común determinado por uno único. Por ejemplo, dados dos vectores, id y score, que están relacionados por elementos, podríamos decidir reorganizar ambos conjuntos en orden alfabético para id.

    III.3_44_R_57_Order_Multisort

    La función sample () devuelve un muestreo aleatorio a partir de un vector de un tamaño dado, ya sea con reemplazo o sin como se especifica con el parámetro replace = (FALSE es el valor predeterminado si no se especifica).

    III.3_45_R_58_Muestra

    La función rep () repite un vector para producir un vector más largo. Podemos repetir de manera elemento por elemento, o sobre todo el vector, dependiendo de si se usa o no el parámetro each =.

    III.3_46_R_59_rep

    Por último (pero no menos importante) para esta discusión es la función is.na (): dado un vector con elementos que posiblemente sean valores NA, devuelve un vector lógico elementos enteros son TRUE en índices donde el original era NA, permitiéndonos indicar fácilmente cuál elementos de vectores son NA y los eliminan.

    III.3_47_R_60_es_NA

    Observe el uso del signo de exclamación en lo anterior para negar el vector lógico devuelto por is.na ().

    Generación de datos aleatorios

    R sobresale en trabajar con distribuciones de probabilidad, incluyendo generar muestras aleatorias a partir de ellas. Muchas distribuciones son compatibles, incluyendo la Normal (Gaussiana), Log-Normal, Exponencial, Gamma, T de Student, y así sucesivamente. Aquí solo veremos generar muestras a partir de unas pocas para utilizarlas en ejemplos futuros.

    Primero, la función rnorm () genera un vector numérico de una longitud dada muestreado a partir de la distribución Normal con media especificada (con media =) y desviación estándar (con sd =).

    III.3_48_R_61_RNorm

    De manera similar, la función runif () muestrear a partir de una distribución uniforme limitada por un valor mínimo y máximo.

    III.3_49_R_62_rUnif

    El rexp () genera datos a partir de una distribución exponencial con un parámetro de “tasa” dado, controlando la tasa de decaimiento de la función de densidad (la media de muestras grandes se acercará a 1.0/tasa).

    III.3_50_R_63_REXP
    III.3_51_distribución_formas

    R incluye una gran cantidad de pruebas estadísticas, aunque no vamos a estar cubriendo mucho en la forma de las estadísticas que no sean algunos ejemplos de manejo. La función t.test () ejecuta una prueba t de student de dos lados comparando las medias de dos vectores. Lo que se devuelve es un tipo de datos más complejo con clase “htest”.

    III.3_52_R_63_2_Ttest

    Cuando se imprime, este complejo tipo de datos se formatea a sí mismo en una salida agradable y legible por humanos:

    III.3_53_R_63_3_ttest_out

    Lectura y Escritura de Datos Tabulares, Envoltura de Líneas Largas

    Antes de ir mucho más allá, vamos a querer poder importar datos a nuestros programas R desde archivos externos (que asumiremos que son filas y columnas de datos en archivos de texto). Esto lo haremos con read.table (), y el resultado será un tipo de datos conocido como “data frame” (o data.frame en código). Cubriremos los matices de los marcos de datos más adelante, pero tenga en cuenta por ahora que pueden considerarse como una colección de vectores (de igual longitud), uno por cada columna de la tabla.

    Como ejemplo, supongamos que tenemos un archivo de texto separado por tabulaciones en nuestro directorio de trabajo actual llamado states.txt. [3] Cada fila representa uno de los estados de Estados Unidos junto con información sobre población, ingreso per cápita, tasa de analfabetismo, tasa de homicidios (por 100,000), porcentaje de graduados de secundaria y región (todos medidos en la década de 1970). La primera fila contiene una línea de “encabezado” con nombres de columna.

    III.3_54_R_63_4_Estados_Top

    Posteriormente en el expediente, alguien ha decidido anotar la línea de Michigan, indicándola como el estado “manopla”:

    III.3_55_R_63_5_Estados_Mitten

    Como la mayoría de las funciones, read.table () toma muchos parámetros potenciales (23, de hecho), pero la mayoría de ellos tienen valores predeterminados razonables. Aún así, hay cinco más o menos que comúnmente necesitaremos establecer. Debido a la necesidad de establecer tantos parámetros, el uso de read.table () a menudo resulta en una larga línea de código. Afortunadamente, el intérprete R nos permite romper largas líneas sobre varias líneas, siempre y cuando cada línea termine en un carácter que no complete la expresión (así el intérprete sabe que necesita seguir leyendo las siguientes líneas antes de ejecutarlas). Las opciones de carácter común son la coma y el signo más. Cuando envolvemos una larga línea de esta manera, es costumbre sangrar las siguientes líneas para indicar su continuidad de manera visual.

    III.3_56_R_64_LEER_TABLE_ESTADOS

    Al leer states.txt, el parámetro file = especifica el nombre del archivo a leer, mientras que header = TRUE indica al intérprete que la primera línea del archivo da los nombres de columna (sin él, los nombres de columna serán “V1", “V2", “V3" y así sucesivamente). El parámetro sep = “\ t” indica que los caracteres de tabulación se utilizan para separar las columnas en el archivo (el valor predeterminado es cualquier espacio en blanco), y comment.char = “#” indica que # caracteres y cualquier cosa posterior a ellos deben ser ignorados mientras se lee el archivo (lo cual es apropiado, como es evidente por la anotación # manopla en el archivo). El parámetro stringsasFactors = FALSE es más críptico: le dice al intérprete que deje las columnas character-vector (como region en este ejemplo) como vectores de caracteres, en lugar de convertirlas al tipo de datos de factor más sofisticado (para ser cubierto más adelante capítulos).

    En este punto, la variable states contiene el marco de datos que contiene las columnas (vectores) de datos. Podemos imprimirlo con print (states), pero el resultado es bastante de salida:

    III.3_57_R_65_Estados_Imprimir

    Podría tener más sentido extraer solo las primeras 10 filas de datos e imprimirlas, lo que podemos hacer con la función head () (head () también puede extraer solo los primeros elementos de un vector largo).

    III.3_58_R_66_CABEZA_ESTADOS

    Las funciones nrow () y ncol () devuelven el número de filas y columnas de un marco de datos, respectivamente (que se prefiere sobre length (), que devuelve el número de columnas); la función dim () devuelve un vector de dos elementos con número de filas (en el índice 1) y número de columnas (en el índice 2).

    Como se mencionó anteriormente, las columnas individuales de un marco de datos son (casi siempre) vectores. Para acceder a uno de estos vectores individuales, podemos usar una sintaxis $ especial, con el nombre de la columna siguiendo la $.

    III.3_59_R_67_Estados_Col_extracto

    Siempre y cuando el nombre de la columna sea lo suficientemente simple (en particular, siempre y cuando no tenga espacios), entonces las comillas alrededor del nombre de la columna pueden omitirse (y a menudo son) omitidas.

    III.3_60_R_68_Estados_col_extracto_sincotizaciones

    Aunque esta sintaxis se puede utilizar para extraer una columna de un marco de datos como un vector, tenga en cuenta que también se refiere al vector dentro del marco de datos. En cierto sentido, states$income es el vector almacenado en el marco de datos de estados. Así podemos usar técnicas como el reemplazo selectivo para trabajar con ellos al igual que cualquier otro vector. Aquí, reemplazaremos todas las instancias de “North Central” en el vector states$region con solo el término “Central”, renombrando efectivamente la región. [4]

    III.3_61_R_69_Estados_Col_Rename_Norte_Central

    Escribir un marco de datos en un archivo separado por tabuladores se logra con la función write.table (). [5] Al igual que con read.table (), write.table () puede tomar bastantes parámetros, la mayoría de los cuales tienen valores predeterminados razonables. Pero hay seis más o menos que vamos a querer establecer con más frecuencia que otros. Escribamos el marco de datos de estados modificados en un archivo llamado states_modified.txt como un archivo separado por tabuladores.

    III.3_62_R_69_2_Estados_escribir

    Los dos primeros parámetros aquí son el marco de datos a escribir y el nombre del archivo en el que escribir. El parámetro quote = FALSE especifica que las comillas no deben escribirse alrededor de los tipos de caracteres en la salida (por lo que la columna name tendrá entradas como Alabama y Alaska en lugar de “Alabama” y “Alaska”). El sep = “\ t” indica que las pestañas deben separar las columnas, mientras que fila.names = FALSE indica que los nombres de fila no deben escribirse (porque no contienen ninguna información significativa para este marco de datos), y col.names = TRUE indica que queremos la columna nombres de salida a la primera línea del archivo como una línea de “encabezado”.

    R y la línea de comandos Unix/Linux

    En el capítulo 26, “Una introducción”, mencionamos que los scripts R se pueden ejecutar desde la línea de comandos usando el #! /usr/bin/env Entorno ejecutable Rscript. (Las versiones anteriores de R requerían que el usuario ejecutara un comando como R CMD BATCH Scriptname.r, pero hoy se prefiere usar Rscript). Dedicamos más discusión a interconectar Python con el entorno de línea de comandos que lo haremos R, en parte porque R no se usa con tanta frecuencia de esa manera, sino también porque es bastante fácil.

    Al usar read.table (), por ejemplo, los datos se pueden leer desde la entrada estándar usando el nombre de archivo “stdin”. Cualquier cosa que se imprima a partir de un script R va a la salida estándar por defecto. Debido a que R hace una buena cantidad de formato al imprimir, sin embargo, a menudo es más conveniente imprimir marcos de datos usando write.table () especificando file = “”.

    Finalmente, para obtener los parámetros de la línea de comandos en un script R como vector de caracteres, los args de línea <- CommandArgs (TrailingOnly = TRUE) harán el truco. Aquí hay un script simple que leerá una tabla en la entrada estándar, la escribirá en la salida estándar y también leerá e imprimirá cualquier argumento de línea de comandos:

    III.3_63_R_69_3_Stdin_Stdout

    Intenta hacer que este script sea ejecutable en la línea de comandos, y ejecutarlo en p450s_blastp_yeast_top1.txt con algo como cat p450s_blastp_yeast_top1.txt |. /stdin_stdout_ex.r arg1 'arg 2'.

    Ejercicios

    1. Supongamos que tenemos algún vector numérico de longitud impar (por ejemplo, muestra<- c (3.2, 5.1, 2.5, 1.6, 7.9) o muestra <- runif (25, min = 0, max = 1)). Escribe algunas líneas de código que den como resultado la impresión de la mediana del vector, sin usar las funciones median () o quantile (). Puede que le resulten útiles las funciones length () y as.integer ().
    2. Si muestra es una muestra de una distribución exponencial, por ejemplo, muestra <- rexp (1000, tasa = 1.5), entonces la mediana de la muestra es generalmente menor que la media. Genere un vector, entre_median_media, que contenga todos los valores de muestra que sean mayores que (o iguales a) la mediana de la muestra, y menores que (o iguales a) la media de la muestra.
    3. Lea en el archivo states.txt en un marco de datos como se describe. Extraiga un vector numérico llamado asesino_lowincome que contenga tasas de asesinato solo para aquellos estados con ingresos per cápita menores que la mediana del ingreso per cápita (puede usar la función median () esta vez). De igual manera, extraer un vector llamado asesino_highincome que contiene tasas de asesinato solo para aquellos estados con mayor que (o igual a) el ingreso per cápita medio. Ejecutar una prueba t.test () de dos muestras para determinar si las tasas medias de homicidios son diferentes entre estos dos grupos.
    4. Sea estados el marco de datos de información de estado descrito anteriormente. Describir lo que hacen las diversas operaciones a continuación en términos de indexación, reemplazo selectivo, reciclaje de vectores y los tipos de datos involucrados (por ejemplo, vectores numéricos y vectores lógicos). Para comenzar, la primera línea agrega una nueva columna al marco de datos de estados llamada “newpop” que contiene la misma información que la columna “population”. III.3_64_R_70_Describe_Selective_Replacement_HW
    5. Determine el número de regiones únicas que se enumeran en el marco de datos de estados. Determinar el número de regiones únicas representadas por estados con ingresos mayores a la mediana.
    6. ¿Qué informa la función sum () para un vector numérico c (2, 3, 0, 1, 0, 2)? ¿Qué tal para c (1, 0, 0, 1, 1, 0)? Y, finalmente, ¿qué tal para el vector lógico c (VERDADERO, FALSO, FALSO, VERDADERO, CIERTO, FALSO) ¿Cómo podría ser útil la función sum () en un contexto lógico?

    1. La mayoría de las funciones R toman una gran cantidad de parámetros, pero muchos de ellos son opcionales. En el siguiente capítulo, veremos cómo se ven estos parámetros opcionales y cómo obtener una extensa lista de todos los parámetros que pueden tomar las funciones R incorporadas.
    2. El término “reemplazo selectivo” no es ampliamente utilizado fuera de este libro. En algunas situaciones se emplea el término “reemplazo condicional”, pero quisimos definir alguna terminología concreta para plasmar la totalidad de la idea.
    3. Cuando se ejecuta en la línea de comandos, el directorio de trabajo actual se hereda del shell. En RStudio, el directorio de trabajo actual se establece en el directorio “proyecto” si el archivo forma parte de una carpeta de proyecto. En cualquier caso, es posible cambiar el directorio de trabajo desde dentro de R usando el directorio setwd (), como en setwd (“/home/username/rproject”) en Unix/Linux y setwd (“C: /Documents and settings/username/my documents/rproject”) en Windows. También es posible especificar nombres de archivo por ruta absoluta, como en /home/username/rproject/states.txt, sin importar el directorio de trabajo actual.
    4. Si tiene alguna familiaridad con R, es posible que se haya topado con la función attach (), que toma un marco de datos y da como resultado la creación de un vector separado para cada columna. Generalmente, “desmontar” un marco de datos de esta manera es una mala idea; después de todo, ¡las columnas de un marco de datos generalmente están asociadas entre sí por una razón! Además, esta función da como resultado la creación de muchas variables con nombres basados en los nombres de columna del marco de datos. Debido a que estos nombres no están claramente delimitados en el código, es fácil crear errores difíciles de encontrar y mezclar columnas de múltiples marcos de datos de esta manera.
    5. También hay funciones más especializadas tanto para leer como para escribir datos tabulares, como read.csv () y write.csv (). Nos hemos centrado en read.table () y write.table () porque son lo suficientemente flexibles como para leer y escribir tablas en una variedad de formatos, incluyendo separados por comas, separados por tabuladores, etc.

    This page titled 3.3: Vectores is shared under a CC BY-NC-SA license and was authored, remixed, and/or curated by Shawn T. O’Neil (OSU Press) .