使用tableGrob实现单元格文本换行时遇‘invalid grob name’错误求助
R语言tableGrob文本换行报错解决方法
我有一个仅包含“评审反馈”列的数据框df,两行数据分别对应“评审人1”和“评审人2”。尝试实现单元格内评审反馈文本的换行操作时,持续触发错误:in gPathFromVector(names) : invalid grob name。相关代码如下:
library(grid) library(gridExtra) text_cell <- function(text, width = unit(1, "cm")) { g <- textGrob(text, rot = 0, hjust = 0, vjust = 0.5) g$width <- width g } d4 <- data.frame(Reviewer_Feedback = c("This is a long text from reviewer 1 that needs to be wrapped", "This is a long text from reviewer 2 that needs to be wrapped")) colnames(d4) <- "Reviewer Feedback" rownames(d4) <- c("Reviewer 1", "Reviewer 2") table_grobs <- tableGrob(d4, rows = NULL, theme = ttheme_default(core = list(fg_params = list(hjust = 0)))) # Set width of the column to 10 cm table_grobs[["widths"]][1] <- unit(10, "cm") # Wrap text in the cells. This is where I receive the error. for (i in 1:nrow(d4)) { cell_grob <- table_grobs[gPath(i, 1)] cell_grob <- text_cell(cell_grob$label, width = table_grobs[["widths"]][1]) table_grobs[gPath(i, 1)] <- cell_grob } grid.draw(table_grobs)
错误原因
你用gPath(i, 1)直接索引table_grobs的方式不对,tableGrob的内部结构里,核心单元格的grob存储在table_grobs$core$grob中,不能直接通过行号列号的gPath访问,这才导致了"invalid grob name"错误。
修复方案
下面提供两种简单可行的文本换行实现方式:
方式1:利用tableGrob自带的自动换行
不用手动替换单元格grob,创建时配置参数即可让文本自动适配列宽换行:
library(grid) library(gridExtra) # 构建数据框 d4 <- data.frame(Reviewer_Feedback = c("This is a long text from reviewer 1 that needs to be wrapped", "This is a long text from reviewer 2 that needs to be wrapped")) colnames(d4) <- "评审反馈" rownames(d4) <- c("评审人1", "评审人2") # 创建tableGrob,设置左对齐和内边距 table_grobs <- tableGrob(d4, rows = rownames(d4), theme = ttheme_default( core = list( fg_params = list(hjust = 0, x = unit(0.02, "npc")), padding = unit(c(2, 2), "mm") ) )) # 设置列宽为10cm table_grobs$widths[1] <- unit(10, "cm") # 自动调整行高以适配换行后的文本 table_grobs$heights <- unit.c( unit(1, "line"), lapply(1:nrow(d4), function(i) { grobHeight(textGrob(d4[i,1], hjust=0, width=table_grobs$widths[1])) + unit(4, "mm") }) ) # 绘制表格 grid.draw(table_grobs)
方式2:用gridtext包实现更灵活的换行
如果需要支持富文本格式,推荐使用gridtext包的richtext_grob:
library(grid) library(gridExtra) library(gridtext) # 定义生成换行文本grob的函数 text_cell <- function(text, width) { richtext_grob(text, width = width, hjust = 0, vjust = 0.5, padding = unit(c(2, 2), "mm"), gp = gpar(fontsize = 12)) } # 构建数据框 d4 <- data.frame(Reviewer_Feedback = c("This is a long text from reviewer 1 that needs to be wrapped", "This is a long text from reviewer 2 that needs to be wrapped")) colnames(d4) <- "评审反馈" rownames(d4) <- c("评审人1", "评审人2") # 创建基础表格(先填充空文本占位) table_grobs <- tableGrob(d4, rows = rownames(d4), theme = ttheme_default(core = list(fg_params = list(label = "")))) # 设置列宽 col_width <- unit(10, "cm") table_grobs$widths[1] <- col_width # 替换每个单元格的grob for (i in seq_len(nrow(d4))) { table_grobs$core$grob[[i]] <- text_cell(d4[i,1], col_width) } # 调整行高 table_grobs$heights <- unit.c( unit(1, "line"), sapply(1:nrow(d4), function(i) grobHeight(table_grobs$core$grob[[i]])) ) # 绘制表格 grid.draw(table_grobs)
内容的提问来源于stack exchange,提问作者vashfive
相关产品推荐
相关产品推荐

