R:使用给定的颜色查找表将矩阵转换为彩色光栅的最快方法

R:使用给定的颜色查找表将矩阵转换为彩色光栅的最快方法,r,graphics,colors,rcpp,raster,R,Graphics,Colors,Rcpp,Raster,我正在寻找R(或Rcpp)中最快的方法,将给定的双精度矩阵(值介于0和1之间)转换为具有十六进制颜色代码的图像光栅 目前我正在做的是 library(RColorBrewer) cols=colorRampPalette(RColorBrewer::brewer.pal(11, "RdYlBu"))(1080) colfun=colorRamp(RColorBrewer::brewer.pal(11, "RdYlBu")) mat=matrix(seq(1:1080)/1080,ncol=192

我正在寻找R(或Rcpp)中最快的方法,将给定的双精度矩阵(值介于0和1之间)转换为具有十六进制颜色代码的图像光栅

目前我正在做的是

library(RColorBrewer)
cols=colorRampPalette(RColorBrewer::brewer.pal(11, "RdYlBu"))(1080)
colfun=colorRamp(RColorBrewer::brewer.pal(11, "RdYlBu"))
mat=matrix(seq(1:1080)/1080,ncol=1920,nrow=1080,byrow=FALSE)
system.time(rastmat <- as.raster(apply(mat, 2, function (col) rgb(colfun(col),max=255)))) # 2.55s

使用调色板的离散化和预先计算颜色,我可以更快地完成任务10倍。考虑到您的代码在我的计算机上运行时间为0.5秒(而不是您评论中的2.55秒),我将在~0.05秒内执行您的任务

ncol = 100
colfun = colorRamp(RColorBrewer::brewer.pal(11, "RdYlBu"))
col = rgb(colfun(seq(0,1, length.out = ncol)), max = 255)

val2hexa = function(mat, col)
{
  idx = findInterval(mat, seq(0, 1, length.out = length(col)))
  colors = col[idx]
  rastmat = as.raster(matrix(colors, ncol = ncol(mat), nrow = nrow(mat), byrow = FALSE))
  return(rastmat)
}

rastmat <- val2hexa(mat, col)
编辑

你可以像那样获得几毫秒

val2hexa = function(mat, col)
{
  idx = findInterval(mat, seq(0, 1, length.out = length(col)))
  colors = col[idx]
  dim(colors) <- dim(mat)
  rastmat = as.raster(colors)
  return(rastmat)
}
val2hexa=函数(mat,col)
{
idx=findInterval(mat,seq(0,1,length.out=length(col)))
颜色=列[idx]

暗淡(颜色)您可以使用
foreach()
mclapply()
来并行化您的
apply
函数。这实际上取决于操作系统和可用的内核数量。您的R版本和CPU是什么?您的代码在我的计算机上运行0.6秒(R3.4,Intel core i7,Linux)使用英特尔core i7和R 3.4.0,但却赢得了8.1。因此,McLappy()将不是一个选项-我认为使用OpenMP的Rcpp和多线程将是最有效的,尽管下面的解决方案已经有了合理的性能…非常感谢-有10000种颜色(这是我所需要的)我得到了一个0.07秒的计时,所以这应该足够好了!我仍然会等待一段时间来接受你的答案,以防其他人可能会想出更快的解决方案,例如使用哈希表,或一些Rcpp+OpenMP解决方案……使用100000种颜色,我的机器上的计时会下降到0.16秒,不过……
findInterval
使用快速内部C代码。然后我使用向量中的索引访问颜色。你不能期望通过哈希表更快地访问颜色。而且你不能并行化这个已经很快的任务。此外,代码中比较慢的是
as.raster(矩阵(…)
Ha是的,我看到了-so.raster()如果需要更快的性能,应该考虑一下…谢谢Thx让我知道!哈刚刚注意到as.raster()并不是真的需要,因为它已经是一个十六进制色码矩阵了,所以它所做的只是转置,所以我们可以只做mat=matrix(seq(1:1080)/1080,nrow=1920,ncol=1080,byrow=TRUE)在函数中,rastmat=matrix(颜色,ncol=nrow(mat),nrow=ncol(mat),byrow=TRUE);class(rastmat)=“光栅”
microbenchmark::microbenchmark(
  orig = as.raster(apply(mat, 2, function (col) rgb(colfun(col),max=255))),
  new = val2hexa(mat, col), 
  times = 25)

Unit: milliseconds
 expr       min       lq      mean    median        uq      max neval
 orig 456.36900 466.7336 516.96512 489.52481 560.94217 618.1538    25
  new  49.10714  56.0333  65.29669  57.32988  60.16575 155.7042    25
val2hexa = function(mat, col)
{
  idx = findInterval(mat, seq(0, 1, length.out = length(col)))
  colors = col[idx]
  dim(colors) <- dim(mat)
  rastmat = as.raster(colors)
  return(rastmat)
}