You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用devtools::check()时R包@examples报错的解决需求

解决R包make_dicho()函数devtools检查示例报错问题

问题出在哪

  1. 示例代码有语法错误:你用的----------------------------------------------------------------------------不是合法的R注释,devtools检查时会把它当成代码执行,直接触发语法错误,这是最直接的原因。
  2. dplyr环境下变量名获取失效:函数里的deparse(substitute(x))在mutate()或across()里拿不到正确的原始列名——比如在across里会得到.col,在新生成的因子列里得到临时变量名,导致属性里的描述文本异常。
  3. 普通因子输入的标签丢失:当输入是普通因子时,labelled::var_label(x)会返回NULL,手动运行没事,但devtools的严格检查可能会触发警告或错误。

怎么改

1. 先修复示例的语法错误

把那些分割线改成合法注释,前面加#:

# ----------------------------------------------------------------------------

不然R会把这些横线当成无效代码,直接报错。

2. 重写make_dicho()函数,适配dplyr环境

调整变量名获取方式,处理边缘情况:

make_dicho <- function(x, flip_levels = FALSE) {
  # 用rlang工具在dplyr环境里正确获取变量名
  x_expr <- rlang::ensym(x)
  x_lab <- rlang::as_label(x_expr)
  
  # 处理普通因子无标签的情况,避免NULL值
  variable_label <- labelled::var_label(x) %||% ""
  
  # 转换为因子(输入已是因子则无变化)
  x <- haven::as_factor(x)
  
  # 处理水平文本:移除第一个单词并转为标题格式
  x <- dplyr::if_else(
    stringr::str_detect(x, "\\s"),
    stringr::str_replace(x, "\\w+\\s", ""),
    x
  ) |>
    stringr::str_to_title()
  
  # 提前检查水平数量,防止索引越界报错
  x_levels <- unique(x)
  if (length(x_levels) != 2) {
    stop("处理后变量必须包含且仅包含两个水平,请检查输入数据")
  }
  
  # 处理水平翻转逻辑
  if (flip_levels) {
    lab <- x_levels[2]
    x <- forcats::fct_relevel(x, lab)
  } else {
    lab <- x_levels[1]
    x <- forcats::as_factor(x)
  }
  
  # 添加自定义属性
  structure(
    x,
    transformation = glue::glue(
      "Converting '{x_lab}' to a dichotomous factor{if(flip_levels) paste0(' and reordering levels so that ', shQuote(lab), ' is reference') else paste0(' with ', shQuote(lab), ' as reference')}"
    ),
    label = variable_label
  )
}
  • 用rlang::ensym()和rlang::as_label()替代原来的deparse(substitute(x)),在dplyr的mutate/across环境中也能拿到正确的列名。
  • 用%||%处理无标签的情况,需要在包中导入rlang的这个函数,或者自己定义:%||% <- function(a, b) if (is.null(a)) b else a。
  • 新增水平数量检查,防止数据异常导致索引错误。
  • 优化属性文本生成逻辑,更简洁清晰。

3. 调整across示例,无需\dontrun{}

把across里的直接传函数改成匿名函数,确保变量名正确获取:

# function also works inside dplyr::across()
# Create new columns using `across()`
dicho_df <- df %>%
  dplyr::mutate(
    # 不翻转水平的用法
    dplyr::across(
      x:z,
      ~make_dicho(.),
      .names = "dicho_{col}"
    ),
    # 翻转水平的用法
    dplyr::across(
      x:z,
      ~make_dicho(., flip_levels = TRUE),
      .names = "dicho_flipped_{col}"
    )
  )

用~make_dicho(.)的方式传参,结合.names参数,函数内部能正确识别原始列名。

4. 确保包依赖完整

在包的DESCRIPTION文件中添加必要的依赖:

Imports:
  dplyr,
  forcats,
  glue,
  haven,
  labelled,
  rlang,
  stringr,
  tibble

同时在函数的文档注释中添加@importFrom导入所需函数:

#' @importFrom rlang ensym as_label %||%
#' @importFrom dplyr if_else
#' @importFrom forcats fct_relevel as_factor
#' @importFrom glue glue
#' @importFrom haven as_factor
#' @importFrom labelled var_label
#' @importFrom stringr str_detect str_replace str_to_title

验证

修改完成后重新运行devtools::check(),示例代码应能正常执行,无报错;手动运行示例也能保持原有功能。

内容的提问来源于stack exchange,提问作者jdenn0514

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:24:55