【问题标题】:R compute RGB code propotional to value in dataframeR计算RGB代码与数据帧中的值成比例
【发布时间】:2020-07-21 11:48:29
【问题描述】:

我有一个简单的数据框,其中我有 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

但我仍然无法将 -5 / 5 的最小值和值修复为 255

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 

【问题讨论】:

  • stackoverflow.com/q/13353213/3358272 建议使用colorRampPalette。由于您似乎想要 bins 种颜色,也许您可​​以使用 cut 首先对您的数据值进行分箱,然后选择合适的颜色。
  • 谢谢,但实际上我需要数据框列中的 RGB 值。谢谢
  • 您在列中的 rgb 值是......不是直接有用的。为什么不使用提供直接适用于所有绘图函数的值的东西,而不必对它进行字符串拆分/解析/分解/删除呢?
  • 因为我会把输出数据帧写在一个文件中,并使用一个需要RGB值的程序

标签: r collapse


【解决方案1】:

试试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

【讨论】:

  • 谢谢,但我希望从红色变为黑色,然后从黑色变为绿色。在 0 我期望 rgb = 0,0,0
  • 没关系,我找到了。我只需要在函数中添加黑色。谢谢
  • 您的要求中还有其他未说出口的限制吗? (设置colors=c("#ff0000", "#000000", "#00ff00"))
  • pmax 和 pmin 工作查找我的值是否大于和小于 -5 / 5;但如果我有 -4 ,它会将其缩放到 -5 并且我将得到 255,0,0 而不是 204,0,0
  • 您的回答非常有帮助,但我仍然坚持这一点。如果我的值大于-5,它将缩放到-5。谢谢你
猜你喜欢
  • 2018-02-12
  • 2022-09-29
  • 1970-01-01
  • 2015-02-11
  • 2015-01-04
  • 2016-04-14
  • 2021-12-24
  • 2021-06-21
  • 1970-01-01
相关资源
最近更新 更多