R语言:未显式调用flextable内部函数却报错,如何排查调用方式?
问题描述
执行脚本时遇到如下报错:
Error in get_rows_id(x[[part]], i) :
invalid row selection: out of range selection
在脚本中搜索get_rows_id未找到定义,通过以下命令确认它是flextable包的内部未导出函数:
list.files(system.file(package = 'flextable'), recursive = T, full.names = T)
脚本中使用flextable的代码段里没有browser语句,想请教:除了flextable:::get_rows_id这种直接调用方式外,未导出函数还有哪些被调用或隐藏在脚本其他函数中的方式?
附使用flextable的代码段:
df %>% # opts flextable(cheight = cell_height) %>% add_footer_lines(top = F, values = source_caption(report_quarter)) %>% style(pr_p = def_par, pr_t = def_text, pr_c = def_cell, part = "all") %>% style(pr_c = def_header_bg, pr_t = def_text_header, part = "header") %>% style(j = 1, pr_p = update(text.align = "left", def_par), part = "body") %>% style(pr_p = update(text.align = "left", def_par), pr_c = update(vertical.align = "bottom", border.bottom = fp_border(width = 0), def_cell), pr_t = update(color = cbre_pal[2], def_text), part = "footer") %>% style(i = which(submarket_order %in% totals), j = 1, pr_t = update(bold = T, def_text)) %>% ## Row borders border(border.top = body_border, border.bottom = body_border, part = "body") %>% width(width = cell_width) %>% width(j = 1, 1.55) %>% height(height = .28, part = "header") %>% # changed from .65 void(1, part = "header")
解答
未导出函数的调用/触发场景
- 包内公开函数内部调用:这是最普遍的情况,flextable的公开API(比如你用到的
style、border、void等)在执行逻辑中会依赖内部未导出函数完成细节操作,get_rows_id就是被这些上层函数间接调用的,不需要你显式写flextable:::get_rows_id。 - 动态代码执行:如果脚本里用了
do.call配合字符串形式的函数名,或者eval(parse(...))这类动态执行代码的方式,也可能触发未导出函数的调用,但这种写法在常规数据分析脚本里很少见。 - S3方法隐式调用:flextable的对象有自定义的S3方法,这些方法内部可能会调用未导出函数,当你调用
print、update这类泛型函数时,会间接触发对应S3方法里的内部函数调用。
针对你的报错的排查方向
报错提示“行选择超出范围”,结合你的代码,大概率是这两处逻辑出了问题:
style(i = which(submarket_order %in% totals), ...):which(submarket_order %in% totals)返回的行索引,超出了当前flextable主体部分的行数。可能的原因包括:submarket_order的长度和df的行数不匹配;totals中的元素在submarket_order里找不到,导致返回空索引integer(0);或者返回的索引数值大于df的实际行数。void(1, part = "header"):执行到这一步时,表头的行数可能已经被之前的操作(比如flextable初始化参数、style调整)改变,此时指定删除第1行,但表头已经没有足够的行数(比如表头被之前的操作清空,或者原本就只有0行)。
建议先做这两步检查:
- 单独运行
which(submarket_order %in% totals),查看返回的索引是否合理,是否存在超出nrow(df)的数值或空值。 - 在
void(1, part = "header")前添加print(.),查看当前flextable对象的表头行数,确认是否存在第1行。
内容的提问来源于stack exchange,提问作者wigglesthe3rd
相关产品推荐
相关产品推荐

