如何将格式表格格式应用于多列?

时间:2019-04-18 03:37:39

标签: r formatting r-markdown

我有两个data.frames(每个最初是一个较大的父3-d数组的一个维度)。一个保存数值。另一个具有指示第一个数组中每个值的置信区间是否与参考置信区间重叠的T / F值。置信区间对于数组中的每个值都是不同的,因此在格式化表格时,我不能引用常量,而只能引用T / F值数组。

我想显示第一个数组的表,并根据第二个数组显示每个单元格的背景色。为了使formattable可以看到具有T / F值的列,我创建了一个数据框,该数据框绑定了两个三维尺寸的列。在实际数据中,有〜20列数值。这是一个简化的示例:

 orig.data <- array(dim = c(3, 4, 2))
 dimnames(orig.data) <- list (c("site1", "site2", "site3"), c("model1", "model2", "model3",
   "model4"), c("mean.val", "is.in.CI"))
 orig.data[,,1] <- round(runif(12, 2, 10), 2)
 orig.data[,,2] <- as.logical(round(runif(12, 0, 1)))
 ft.data <- data.frame(orig.data[,,2], stringsAsFactors = F)
 colnames(ft.data) <- paste0("match.", colnames(ft.data))
 ft.data <- cbind(data.frame(orig.data[,,1], stringsAsFactors = F), 
    ft.data)

我可以通过按名称调用每一列来创建所需的表格式。有两个特殊注意事项。首先,对于前四列,背景色的选择取决于第二列。第二,我要隐藏的最后四列。有没有办法使用Apply或类似的简洁动态语法来做到这一点?

这是我要合并的长版。

 yes.color <- "lightgreen"
 no.color <- "pink"
 formattable::formattable(ft.data, list(
     `model1` = formatter("span", style = ~ style(display = "block",
        "border-radius" = "4px", "padding-right" = "4px",
        "background-color" =  ifelse(`match.model1`, yes.color, no.color))),
     `model2` = formatter("span", style = ~ style(display = "block",
        "border-radius" = "4px", "padding-right" = "4px",
        "background-color" =  ifelse(`match.model2`, yes.color, no.color))),
     `model3` = formatter("span", style = ~ style(display = "block",
        "border-radius" = "4px", "padding-right" = "4px",
        "background-color" =  ifelse(`match.model3`, yes.color, no.color))),
     `model4` = formatter("span", style = ~ style(display = "block",
        "border-radius" = "4px", "padding-right" = "4px",
        "background-color" =  ifelse(`match.model4`, yes.color, no.color))),
     match.model1 = F,
     match.model2 = F,
     match.model3 = F,
     match.model4 = F))

该问题与我的第二个问题类似,但未得到解答:Loop, hide columns and r formattable

以下是自动隐藏T / F列的尝试失败。我对将两栏参考资料自动化没有任何想法。

 formattable(ft.data[, 1:4]) 

如果我省略了带有T / F名称的列,那么格式化程序将不知道它们的存在。

  area(col = 5:8) = F)) # no effect

在formattable命令之外,创建一个字符串:

 formatter.string <- paste( unlist(paste0("match.", c(“model1”, “model2”, “model3”, “model4”), " = #F,\n\t")), collapse='')

然后在格式表列表中添加

  eval(parse(formatter.string)))) # no effect  OR
  lapply(5:8, function(m.col){m.col = F}) # also no effect

1 个答案:

答案 0 :(得分:1)

这是我使用一些eval / parse魔术所能想到的最好的方法:

format <- sapply(names(ft.data)[1:4],function(x)
{
  eval( #evaluate the following expression
    parse(text=  #parse the following string to an expression
        sub("_SUB_", #find "_SUB_"
            paste0("`match.",x,"`"), #replace with name of column
            "formatter(\"span\", style = ~ style(display = \"block\", #in the string containing the formatter call
                                      \"border-radius\" = \"4px\", \"padding-right\" = \"4px\",
                                      \"background-color\" =  ifelse(_SUB_, yes.color, no.color)))")))
},simplify=F,USE.NAMES = T)

#hiding part. Same concept as above
hide <- sapply(names(ft.data[5:8]), function(x) eval(parse(text=sub("_SUB_",x,"_SUB_ = F"))),
               simplify=F,USE.NAMES=T)

formattable::formattable(ft.data,c(format,hide))