基于行对的R灵活条件格式
R flextable conditional formatting based on pairs of rows
我正在尝试更改 flextable
中某些单元格的 bg
颜色,具体取决于标记为 Act
的行中的值(实际)是否超过相应的行(即相同的 KPI
)标记为 Plan
。超过的值应为绿色背景,而低于 Plan
的值应为红色背景。
(在一个完美的世界中,无论单元格大于还是小于,我都可以更改背景颜色,具体取决于我配置的列表说要走哪个方向,但接下来会出现。)
df <- structure(list(KPI = c("Quality", "Quality", "On Time", "On Time",
"Attrition", "Attrition", "Growth 1", "Growth 1", "Growth 2",
"Growth 2", "WCT", "WCT", "ROI", "ROI"), Type = c("Plan", "Act",
"Plan", "Act", "Plan", "Act", "Plan", "Act", "Plan", "Act", "Plan",
"Act", "Plan", "Act"), JAN = c(1, 1, NA, NA, 0.05, 0.09, NA,
NA, NA, NA, 4, -1.8, NA, NA), FEB = c(1, 0.98, NA, NA, 0.05,
0.08, NA, NA, NA, NA, -0.2, -1.3, NA, NA), MAR = c(1, 1, 0.79,
0.81, 0.05, 0.08, 0.1, 0.08, 116, 199, -0.7, -0.2, NA, NA), APR = c(1,
1, NA, NA, 0.05, 0.08, NA, NA, NA, NA, -0.2, -0.3, NA, NA), MAY = c(1,
1, NA, NA, 0.05, 0.09, NA, NA, NA, NA, -0.2, -0.6, NA, NA), JUN = c(1,
1, 0.79, 0.8, 0.05, 0.08, 0.12, 0.03, -33, 22, 0.1, 1.1, NA,
NA), JUL = c(1, 1, NA, NA, 0.05, 0.09, NA, NA, NA, NA, 0.3, 0.2,
NA, NA), AUG = c(1, 1, NA, NA, 0.05, 0.09, NA, NA, NA, NA, 0.3,
0.8, NA, NA), SEP = c(1, 1, 0.79, 0.78, 0.05, 0.09, 0.2, 0.14,
173, 303, 1.5, 2.1, NA, NA), OCT = c(1, NA, NA, NA, 0.05, NA,
NA, NA, NA, NA, 2.3, NA, NA, NA), NOV = c(1, NA, NA, NA, 0.05,
NA, NA, NA, NA, NA, 2, NA, NA, NA), DEC = c(1, NA, NA, NA, 0.05,
NA, NA, NA, NA, NA, 0.2, NA, NA, NA)), row.names = c(NA, -14L
), class = c("tbl_df", "tbl", "data.frame"))
library(regulartable)
library(magrittr)
df %>% regulartable() %>% bg(i = ~ Type %in% "Act", j = 3:14, bg="#cceecc")
它生成的图像如下。我目前被困住了,因为我不知道如何添加第二个条件,即 (value > lag(value))
位置上的任何内容。有谁知道,或者我需要先 spread
和 gather
吗?任何帮助将不胜感激。
df %>% regulartable() %>% bg(i = ~ Type %in% "Act" && (value > lag(value)), j = 3:14, bg="#cceecc")
我确定有更优雅的方法可以解决这个问题,如果有的话,我希望有人能发布它。但与此同时,我找到了权宜之计。首先将 df 拆分为计划值和实际值,然后使用这些差异为每个单元格确定合适的颜色:
library(gdata)
df %>% group_split(Type) -> plan.act
ifelse(plan.act[[1]][,3:14]-plan.act[[2]][,3:14]>=0, "#cceecc", "#eecccc") -> colorgrid
这会为每个单元格创建一个 red/green 颜色列表:
> colorgrid
JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
[1,] "#cceecc" "#eecccc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" NA NA NA
[2,] NA NA "#cceecc" NA NA "#cceecc" NA NA "#eecccc" NA NA NA
[3,] "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" NA NA NA
[4,] NA NA "#eecccc" NA NA "#eecccc" NA NA "#eecccc" NA NA NA
[5,] NA NA "#cceecc" NA NA "#cceecc" NA NA "#cceecc" NA NA NA
[6,] "#eecccc" "#eecccc" "#cceecc" "#eecccc" "#eecccc" "#cceecc" "#eecccc" "#cceecc" "#cceecc" NA NA NA
[7,] NA NA NA NA NA NA NA NA NA NA NA NA
现在为 Plan 组的颜色创建另一个 df,然后绘制 table:
blankgrid <- colorgrid
blankgrid[!is.na(blankgrid)] <- NA_character_
df %>% regulartable() %>% bg(j = 3:14, bg=interleave(blankgrid,colorgrid))
然后您可以添加更多 flextable 优点,使 table 更漂亮:
df %>% regulartable() %>% bg(j = 3:14, bg=interleave(blankgrid,colorgrid)) %>%
merge_v(j=1) %>% border_inner_v(border = fp_border(color="gray", width=1))
我正在尝试更改 flextable
中某些单元格的 bg
颜色,具体取决于标记为 Act
的行中的值(实际)是否超过相应的行(即相同的 KPI
)标记为 Plan
。超过的值应为绿色背景,而低于 Plan
的值应为红色背景。
(在一个完美的世界中,无论单元格大于还是小于,我都可以更改背景颜色,具体取决于我配置的列表说要走哪个方向,但接下来会出现。)
df <- structure(list(KPI = c("Quality", "Quality", "On Time", "On Time",
"Attrition", "Attrition", "Growth 1", "Growth 1", "Growth 2",
"Growth 2", "WCT", "WCT", "ROI", "ROI"), Type = c("Plan", "Act",
"Plan", "Act", "Plan", "Act", "Plan", "Act", "Plan", "Act", "Plan",
"Act", "Plan", "Act"), JAN = c(1, 1, NA, NA, 0.05, 0.09, NA,
NA, NA, NA, 4, -1.8, NA, NA), FEB = c(1, 0.98, NA, NA, 0.05,
0.08, NA, NA, NA, NA, -0.2, -1.3, NA, NA), MAR = c(1, 1, 0.79,
0.81, 0.05, 0.08, 0.1, 0.08, 116, 199, -0.7, -0.2, NA, NA), APR = c(1,
1, NA, NA, 0.05, 0.08, NA, NA, NA, NA, -0.2, -0.3, NA, NA), MAY = c(1,
1, NA, NA, 0.05, 0.09, NA, NA, NA, NA, -0.2, -0.6, NA, NA), JUN = c(1,
1, 0.79, 0.8, 0.05, 0.08, 0.12, 0.03, -33, 22, 0.1, 1.1, NA,
NA), JUL = c(1, 1, NA, NA, 0.05, 0.09, NA, NA, NA, NA, 0.3, 0.2,
NA, NA), AUG = c(1, 1, NA, NA, 0.05, 0.09, NA, NA, NA, NA, 0.3,
0.8, NA, NA), SEP = c(1, 1, 0.79, 0.78, 0.05, 0.09, 0.2, 0.14,
173, 303, 1.5, 2.1, NA, NA), OCT = c(1, NA, NA, NA, 0.05, NA,
NA, NA, NA, NA, 2.3, NA, NA, NA), NOV = c(1, NA, NA, NA, 0.05,
NA, NA, NA, NA, NA, 2, NA, NA, NA), DEC = c(1, NA, NA, NA, 0.05,
NA, NA, NA, NA, NA, 0.2, NA, NA, NA)), row.names = c(NA, -14L
), class = c("tbl_df", "tbl", "data.frame"))
library(regulartable)
library(magrittr)
df %>% regulartable() %>% bg(i = ~ Type %in% "Act", j = 3:14, bg="#cceecc")
它生成的图像如下。我目前被困住了,因为我不知道如何添加第二个条件,即 (value > lag(value))
位置上的任何内容。有谁知道,或者我需要先 spread
和 gather
吗?任何帮助将不胜感激。
df %>% regulartable() %>% bg(i = ~ Type %in% "Act" && (value > lag(value)), j = 3:14, bg="#cceecc")
我确定有更优雅的方法可以解决这个问题,如果有的话,我希望有人能发布它。但与此同时,我找到了权宜之计。首先将 df 拆分为计划值和实际值,然后使用这些差异为每个单元格确定合适的颜色:
library(gdata)
df %>% group_split(Type) -> plan.act
ifelse(plan.act[[1]][,3:14]-plan.act[[2]][,3:14]>=0, "#cceecc", "#eecccc") -> colorgrid
这会为每个单元格创建一个 red/green 颜色列表:
> colorgrid
JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
[1,] "#cceecc" "#eecccc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" NA NA NA
[2,] NA NA "#cceecc" NA NA "#cceecc" NA NA "#eecccc" NA NA NA
[3,] "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" "#cceecc" NA NA NA
[4,] NA NA "#eecccc" NA NA "#eecccc" NA NA "#eecccc" NA NA NA
[5,] NA NA "#cceecc" NA NA "#cceecc" NA NA "#cceecc" NA NA NA
[6,] "#eecccc" "#eecccc" "#cceecc" "#eecccc" "#eecccc" "#cceecc" "#eecccc" "#cceecc" "#cceecc" NA NA NA
[7,] NA NA NA NA NA NA NA NA NA NA NA NA
现在为 Plan 组的颜色创建另一个 df,然后绘制 table:
blankgrid <- colorgrid
blankgrid[!is.na(blankgrid)] <- NA_character_
df %>% regulartable() %>% bg(j = 3:14, bg=interleave(blankgrid,colorgrid))
然后您可以添加更多 flextable 优点,使 table 更漂亮:
df %>% regulartable() %>% bg(j = 3:14, bg=interleave(blankgrid,colorgrid)) %>%
merge_v(j=1) %>% border_inner_v(border = fp_border(color="gray", width=1))