R вычисляет RGB-код, пропорциональный значению в кадре данных - PullRequest
0 голосов
/ 09 апреля 2020

У меня есть простой фрейм данных, где у меня есть значение в масштабе log2.

Я пытаюсь добавить в фрейм данных столбец, содержащий код R, G, B, пропорциональный значению в первом столбце. Также, если значение больше или меньше значения, я хочу поставить порог. В этом случае мин -5 макс 5. Я сделал это в awk, но я не нашел решения в R Мой код awk:

awk -v maxlogratio=5 -v FS='\t' -v OFS='\t' '/^chr/{{r=0;g=0;if($9<1){{r=-255*(log($9)/log(2))/maxlogratio;if(r>255){{r=255}}}};if($9>1){{g=255*(log($9)/log(2))/maxlogratio;if(g>255){{g=255}}}};print $0,r","g",0"}}'

Единственное отличие здесь в том, что мое значение не в шкала log2 (вот почему у меня есть log (x) / log (2)

R код:

activity_rgb=data.frame(activity=seq(from=-6,to = 6,by = 1))%>%
mutate(rgb=ifelse(activity<0,c(-255*(activity)/5,0,0),c(0,255*(activity),0)))

Я получил это:

   activity  rgb
1        -6  306
2        -5  255
3        -4  204
4        -3  153
5        -2  102
6        -1   51
7         0 -255
8         1    0
9         2  255
10        3  510
11        4  765
12        5 1020
13        6 1275

Я ожидаю этого :

activity    rgb
  -6    255,0,0 
  -5    255,0,0 
  -4    204,0,0 
  -3    153,0,0
  -2    102,0,0
  -1    51,0,0
   0    0,0,0   
   1    0,51,0  
   2    0,102,0 
   3    0,153,0 
   4    0,204,0 
   5    0,255,0
   6    0,255,0 

Итак, мне нужно вставить значение в столбец rgb, но я не знаю, как это сделать.

Итак, наконец, я сделал что-то, чтобы получить r, g, b

Но я все еще не могу установить минимальное значение 255 для -5 / 5

activity_rgb=data.frame(activity=seq(from=-6,to = 6,by = 1))%>%
mutate(rgb=ifelse(activity<0,paste(-255*(activity)/5,0,0,sep = ","),paste(0,255*(activity)/5,0,sep = ",")))

activity_rgb
   activity     rgb
1        -6 306,0,0
2        -5 255,0,0
3        -4 204,0,0
4        -3 153,0,0
5        -2 102,0,0
6        -1  51,0,0
7         0   0,0,0
8         1  0,51,0
9         2 0,102,0
10        3 0,153,0
11        4 0,204,0
12        5 0,255,0
13        6 0,306,0 

1 Ответ

1 голос
/ 09 апреля 2020

Попробуйте использовать colorRamp:

scale_to_rgb <- function(val, bounds = NA,
                         colors = c("#ff0000", "#000000", "#00ff00"),
                         format = c("rgb", "comma"), ...) {
  if (anyNA(bounds)) bounds <- range(val, na.rm = TRUE)
  format = match.arg(format)

  isna <- is.na(val)
  ispos <- !isna & val >= 0
  isneg <- !isna & !ispos
  cols <- matrix(NA, nrow = length(val), ncol = 3)
  valneg <- pmax(bounds[1], val[isneg]) / bounds[1]
  valpos <- pmin(bounds[2], val[ispos]) / bounds[2]

  cols[isneg,] <- colorRamp(colors[2:1], ...)(valneg)
  cols[ispos,] <- colorRamp(colors[2:3], ...)(valpos)

  if (format == "rgb") {
    cols <- cols / 255
    rgb(cols[,1], cols[,2], cols[,3])
  } else {
    cols <- round(cols, 0)
    paste(cols[,1], cols[,2], cols[,3], sep = ",")
  }
}

Теперь это позволяет передавать аргументы в colorRamp, а именно bias=, space=, interpolate= и alpha=. Не стесняйтесь экспериментировать с ними.

Ваши данные и dplyr сценарий использования:

activity_rgb <- data.frame(activity = seq(from=-6, to = 6, by = 1))

activity_rgb %>%
  mutate(
    rgb = scale_to_rgb(activity, bounds = c(-5, 5)),
    comma = scale_to_rgb(activity, bounds = c(-5, 5), format = "comma")
  )
#    activity     rgb   comma
# 1        -6 #FF0000 255,0,0
# 2        -5 #FF0000 255,0,0
# 3        -4 #CC0000 204,0,0
# 4        -3 #990000 153,0,0
# 5        -2 #660000 102,0,0
# 6        -1 #330000  51,0,0
# 7         0 #000000   0,0,0
# 8         1 #003300  0,51,0
# 9         2 #006600 0,102,0
# 10        3 #009900 0,153,0
# 11        4 #00CC00 0,204,0
# 12        5 #00FF00 0,255,0
# 13        6 #00FF00 0,255,0

Вы упомянули, что будет делать изменение масштаба от -4 до 5 ...

activity_rgb %>%
  mutate(
    rgb = scale_to_rgb(activity, bounds = c(-4, 5)),
    comma = scale_to_rgb(activity, bounds = c(-4, 5), format = "comma")
  )
#    activity     rgb   comma
# 1        -6 #FF0000 255,0,0
# 2        -5 #FF0000 255,0,0
# 3        -4 #FF0000 255,0,0
# 4        -3 #BF0000 191,0,0
# 5        -2 #800000 128,0,0
# 6        -1 #400000  64,0,0
# 7         0 #000000   0,0,0
# 8         1 #003300  0,51,0
# 9         2 #006600 0,102,0
# 10        3 #009900 0,153,0
# 11        4 #00CC00 0,204,0
# 12        5 #00FF00 0,255,0
# 13        6 #00FF00 0,255,0
...