KableExtra条件字体颜色未正确映射至对应位置问题
问题背景
我在data.table中存储了如下基因列表表格:
t.mini cluster1 cluster15 cluster31 <fctr> <fctr> <fctr> 1: Slc6a6 Cd8a Retnla 2: Sema3g Cd8b1 Cxcl15 3: Cyp26b1 Pdcd1 Scgb3a2 4: H2-Q6 Cd3g Sftpb 5: Klhl5 Sh2d2a Scgb1a1 6: Dnah8 Cxcr6 Sftpa1 7: Tm4sf1 Cd3e Cbr2 8: Cdc42bpb Rgs16 Sftpd 9: Cxcl12 Nkg7 Wfdc2 10: Sptan1 Ms4a4b Cyp2f2
需要用kableExtra输出表格时,把所有Cxcl类基因的字体设为红色,初始编写的代码如下:
lapply(1:3, function(y) { kbl(t.mini) |> kable_classic_2(full_width=F) |> column_spec(column = y, color = fifelse(unlist(t.mini[, lapply(.SD, function(x){grepl(glob2rx("Cx*"), x)})]), "red", "black")) })
运行后效果不符合预期:红色字体映射到了错误的基因,且只有单个基因被标红,异常效果如下:
问题排查与修复
代码存在两个核心问题:
- 匹配与颜色传参逻辑错误:
glob2rx("Cx*")转换后的正则会匹配所有Cx开头的基因(比如Cxcr6也会被命中,不符合只匹配Cxcl类的需求);同时unlist会把三列的匹配结果按列拼接为长向量,传入单列表格样式时,向量顺序和当前列的行顺序完全不匹配,直接导致颜色错位。 - 循环逻辑错误:每次循环都重新调用
kbl()生成全新的表格对象,单独给一列加样式后返回,最终得到的是3个独立的单列表格,而非一个三列都配置好样式的完整表格。
修复后的可运行代码:
library(data.table) library(kableExtra) # 提前为每列生成对应行的颜色向量,直接匹配Cxcl开头的基因 col_color_list <- lapply(t.mini, function(gene_col) { fifelse(grepl("^Cxcl", gene_col), "red", "black") }) # 仅生成一次kable对象,循环为三列依次添加颜色样式 kbl(t.mini) |> kable_classic_2(full_width = F) |> (\(tbl) { for (col_idx in 1:3) { tbl <- column_spec(tbl, column = col_idx, color = col_color_list[[col_idx]]) } tbl })()
补充:如果需要匹配所有Cx开头的基因,只需要把正则匹配规则从
^Cxcl改为^Cx即可,直接写正则比调用glob2rx转义更直观,也能避免转义带来的匹配错误。
内容的提问来源于stack exchange,提问作者akh22
相关产品推荐
相关产品推荐

