1

I have a data frame which looks like below. I want to save two png files out of this data frame, named based on sample column, 1.png and 2.png both being 2x3 pixel large using the rgb values on respective columns.

As far as I can tell, I need to prepare a 3d array for each channel and then use writePNG function for each array to save as PNG file, but I got stuck after nesting rgb values for each sample.

Any help would be appreciated (help in tidyverse and purrr way will be appreciated more ;)

Data frame:

| sample| pixel| red| green| blue|
|------:|-----:|---:|-----:|----:|
|      1|     1| 255|     0|    0|
|      1|     2| 255|    32|    0|
|      1|     3| 255|    64|    0|
|      1|     4| 255|    96|    0|
|      1|     5| 255|   128|    0|
|      1|     6| 255|   159|    0|
|      2|     1| 255|   191|    0|
|      2|     2| 255|   223|    0|
|      2|     3| 255|   255|    0|
|      2|     4| 255|   255|   42|
|      2|     5| 255|   255|  128|
|      2|     6| 255|   255|  213|

Here's the code to generate this data frame:

test_df <- data_frame(sample=rep(1:2,each=6), pixel=rep(1:6,2)) %>% 
  bind_cols(as_data_frame(t(col2rgb(heat.colors(12))))) 
Alper Yilmaz
  • 319
  • 2
  • 11
  • Can you show the code you used to nest rgb values? – Aurèle Apr 25 '18 at 16:53
  • you already answered but I just noticed the comment and still wanted to answer. I used the following command to nest the values: `test_df %>% group_by(sample) %>% nest()` – Alper Yilmaz Apr 25 '18 at 21:40

1 Answers1

2

For instance:

library(purrr)

test_df %>% 
  split(.$sample) %>% 
  setNames(paste0(names(.), ".png")) %>% 
  map(~ array(c(.x$red, .x$green, .x$blue), c(2, 3, 3)) / 255) %>%
  iwalk(png::writePNG)

Or in a more "step-by-step" fashion:

test_df %>% 
  split(.$sample) %>% 
  setNames(paste0(names(.), ".png")) %>% 
  map(`[`, 3:5) %>% 
  map(as.matrix) %>% 
  map(`/`, 255) %>% 
  map(array, c(2, 3, 3)) %>% 
  iwalk(png::writePNG)

Or without the tidyverse:

z <- split(test_df, test_df$sample)
mapply(function(x, y) {
  png::writePNG(array(as.matrix(x[3:5]), c(2, 3, 3)) / 255, paste0(y, ".png"))
}, z, names(z))  
Aurèle
  • 12,545
  • 1
  • 31
  • 49