Mapear, unir y pivotar en R

En esta publicación, describiré una serie de pasos de procesamiento de datos en R que a menudo realizo y que involucran la map_df, inner_joiny pivot_longer funciones desde el purrr, dplyry tidyr paquetes, respectivamente. Todos son parte del ordenadoasí que para seguir esta publicación, instale el tidyverse paquete.

install.packages("tidyverse")
library(tidyverse)

El escenario típico es que he usado dos (o más) herramientas para procesar una lista de muestras y las herramientas generan un archivo de salida para cada muestra. Para imitar esto, he escrito una función simple que generará 10 archivos de salida para la «herramienta x» y otros 10 archivos de salida para la «herramienta y».

gen_ran_files <- function(nfiles, suffix, seed)

gen_ran_files(10, "x", 1948)
gen_ran_files(10, "y", 1984)

Ahora tenemos 20 archivos CSV de salida, 10 de cada herramienta.

list.files(pattern = ".csv$")
 [1] "a_x.csv" "a_y.csv" "b_x.csv" "b_y.csv" "c_x.csv" "c_y.csv" "d_x.csv" "d_y.csv" "e_x.csv" "e_y.csv"
[11] "f_x.csv" "f_y.csv" "g_x.csv" "g_y.csv" "h_x.csv" "h_y.csv" "i_x.csv" "i_y.csv" "j_x.csv" "j_y.csv"

Queremos comparar los resultados de cada herramienta, pero los resultados se distribuyen en 20 archivos diferentes. Podemos usar el map_dfr función para crear dos marcos de datos que contienen los resultados de cada herramienta. En el siguiente código, el map_dfr La función se utiliza para «aplicar» el read_csv función a una lista de archivos CSV. Esto devuelve un solo marco de datos que se creó mediante el enlace de filas, es decir, agregando las filas devueltas desde read_csv. Además, el tipo de datos para las columnas (carácter y doble) se proporciona explícitamente para read_csv.

x_output <- map_dfr(list.files(pattern = "x.csv"), read_csv, col_types = cols('c', 'd'))
y_output <- map_dfr(list.files(pattern = "y.csv"), read_csv, col_types = cols('c', 'd'))

x_output
# A tibble: 10 × 2
   sample  purity
   <chr>    <dbl>
 1 a       0.112 
 2 b       2.16  
 3 c      -0.648 
 4 d       0.149 
 5 e      -1.90  
 6 f      -0.204 
 7 g      -0.356 
 8 h      -0.0173
 9 i      -0.378 
10 j      -0.467 

Dado que los resultados aún se dividen en dos, usaremos el inner_join Función para combinarlos. La función necesita saber cómo unir los resultados y especificamos que queremos unir usando el sample columna, que se comparte entre los dos marcos de datos. Si sus herramientas generan diferentes nombres de columna, por ejemplo sample y sample_idpuede usar un vector con nombre como entrada para el by argumento: by = c("sample" = "sample_id"). Una combinación interna devuelve todas las filas que se cruzan entre dos conjuntos y, por lo general, es lo que queremos cuando combinamos resultados. Pero si hay entradas únicas en cualquier conjunto, no serán devueltas por inner_join. Dado que generamos la salida de la misma manera, no habrá entradas únicas y, debido a esto, inner_join, left_join, right_joiny full_join todos devolverán el mismo resultado. Por defecto, las columnas con el mismo nombre tendrán un .x y .y sufijo añadido a ellos. Puede cambiar este comportamiento especificando su propio vector de sufijo.

inner_join(
  x = x_output,
  y = y_output,
  by = "sample",
  suffix = c(".tool_x", ".tool_y")
) -> xy

head(xy)
# A tibble: 6 × 3
  sample purity.tool_x purity.tool_y
  <chr>          <dbl>         <dbl>
1 a              0.112         0.409
2 b              2.16         -0.323
3 c             -0.648         0.636
4 d              0.149        -1.85 
5 e             -1.90          0.954
6 f             -0.204         1.19 

Ahora tenemos todos los resultados de los 20 archivos de salida convenientemente almacenados en un marco de datos. Sin embargo, debemos ordenar el marco de datos asegurándonos de que:

  1. Cada columna es una variable.
  2. Cada fila es una observación.
  3. Cada celda es un valor único.

Actualmente, la segunda y tercera columnas contienen dos variables: pureza y herramienta. Usaremos pivot_longer para dividir las columnas 2 y 3. Usando cols = !sample es un atajo para decir que queremos pivotar todas las columnas excepto la sample columna, es decir, las columnas 2 y 3. El .value es un nombre especial que le dice a la función que parte del nombre de la columna anterior especifica el nombre de la columna nueva. los names_sep controla cómo se divide la columna y queremos dividir usando el período que separa la pureza y el nombre de la herramienta. Tenga en cuenta que tenemos que escapar del punto (.) usando un escape doble para escapar del escape porque R no reconoce ..

pivot_longer(
  data = xy,
  cols =  !sample,
  names_to = c(".value", "tool"),
  names_sep = "\."
) -> xyl

head(xyl)
# A tibble: 6 × 3
  sample tool   purity
  <chr>  <chr>   <dbl>
1 a      tool_x  0.112
2 a      tool_y  0.409
3 b      tool_x  2.16 
4 b      tool_y -0.323
5 c      tool_x -0.648
6 c      tool_y  0.636

Para finalizar, podemos graficar los resultados (aleatorios) para comparar las herramientas.

ggplot(xyl, aes(sample, purity, fill = tool)) +
  geom_bar(stat = "identity", position = "dodge") +
  scale_fill_manual(values = c("#E69F00", "#56B4E9")) +
  theme_bw()

Mapear unir y pivotar en R

Imprimir amigable, PDF y correo electrónico

Fuente del artículo

Deja un comentario