如何在数据表的styleEqual()中指定缺失或不适用?

时间:2019-11-13 02:04:16

标签: r datatable na dt

我有一个R数据表对象,其中的空/空白单元格对应于数据帧(相关矩阵)中的NA。我想更改包含1,-1或空白的单元格的背景颜色。

此代码创建一个表并使用styleEqual()标记带有1或-1的单元格,但是我找不到丢失/空白/ NA的适当规范。您如何在styleEqual()中识别空白单元格?

df <- data.frame(x = c(1, .3, NA),
                 y = c(.3, 1, -1),
                 z = c(NA, -1, 1))
dt <- DT::datatable(df)
dt <- DT::formatStyle(dt, c(1:ncol(df)), backgroundColor = styleEqual(c(-1, 1, NA), c('gray', 'green', 'red')))
dt

结果数据表:

Resulting datatable

1 个答案:

答案 0 :(得分:1)

您可以在styleEqual处获得更多答案。它从JS函数的类“ JS_EVAL”输出一个字符串,您可以通过直接调用styleEqual

来查看
styleEqual(c(-1, 1, NA), c('gray', 'green', 'red'))

# [1] "value == -1 ? \"gray\" : value == 1 ? \"green\" : value == \"NA\" ? \"red\" : value"
# attr(,"class")
# [1] "JS_EVAL"

从那里您只需要了解javascript如何处理NA值(NaN),就可以创建自己的配色方案,然后只需修改值即可创建自己的字符串

myJScolor = "value == -1 ? \"gray\" : value == 1 ? \"green\" : isNaN(parseFloat(value)) ? \"red\" : value"
class(myJScolor) = "JS_EVAL"
myJScolor
dt2 <- DT::formatStyle(dt, c(1:ncol(df)), backgroundColor = myJScolor )
dt2

一个更通用的解决方案是创建styleEqual的新版本,如下所示:

 df <- data.frame(x = c(1, .3, NA),
                  y = c(.3, 1, -1),
                  z = c(NA, -1, 1))

 newstyleEqual <- function (levels, values, default = NULL) 
 {
   n = length(levels)
   if (n != length(values)) 
     stop("length(levels) must be equal to length(values)")
   if (!is.null(default) && (!is.character(default) || length(default) != 
                             1)) 
     stop("default must be null or a string")
   if (n == 0) 
     return("''")
   levels = DT:::jsValues(levels)
   values = DT:::jsValues(values)
   js = ""
   for (i in seq_len(n)) {
     if(levels[i]=="\"NA\""){ # needed because jsValues converts NA to a string
       js = paste0(js, sprintf("isNaN(parseFloat(value)) ? %s : ",
                               values[i]))

     }else{
       js = paste0(js, sprintf("value == %s ? %s : ", levels[i], 
                                   values[i]))
       }

   }
   default = if (is.null(default)) 
     "value"
   else jsValues(default)
   DT::JS(paste0(js, default))
 }

 dt <- DT::datatable(df)

 dt <- DT::formatStyle(dt, c(1:ncol(df)), backgroundColor = newstyleEqual(c(-1, 1, NA), c('gray', 'green', 'red')))
 dt