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

如何在R中提取脚本内函数定义的行号、标题等信息?

问题描述

我有一段保存为function.R的R代码,内容如下:

#' This function is cool
#' 
#' blablabla.....
#' @export
#' @param hello a parameter of my function
f_cool <- function(hello) {
  # some code
  # some other code
}

请问是否有办法以列表形式按行号提取函数定义的大纲信息?例如调用类似map_fn_definition("function.R")的函数后,能返回如下结果:

#> $f_cool
#> $f_cool$line_start 
#> 6
#> $f_cool$line_end 
#> 9
#> $f_cool$title
#> "This function is cool"

我了解roxygen2可能实现该功能,但该工具的文档侧重生成包的.Rd文件,因此特向您寻求解决方案。

解决方案

可以通过解析文件文本内容,结合正则匹配与语法逻辑判断实现需求,以下是自定义的map_fn_definition函数:

map_fn_definition <- function(file_path) {
  # 读取文件所有行
  lines <- readLines(file_path)
  line_count <- length(lines)
  
  # 匹配函数定义行(格式:函数名 <- function(...))
  fn_def_pattern <- "^\\s*([a-zA-Z0-9._]+)\\s*<-\\s*function\\s*\\("
  fn_def_matches <- regexec(fn_def_pattern, lines)
  fn_positions <- which(sapply(fn_def_matches, function(x) x[1] != -1))
  
  result <- list()
  
  for (pos in fn_positions) {
    # 提取函数名
    fn_name <- regmatches(lines[pos], fn_def_matches[[pos]])[2]
    
    # 定位函数结束行:统计大括号数量,处理嵌套情况
    brace_count <- 0
    end_line <- line_count
    for (i in pos:line_count) {
      current_line <- lines[i]
      brace_count <- brace_count + stringr::str_count(current_line, "\\{") - stringr::str_count(current_line, "\\}")
      if (brace_count == 0 && i > pos) {
        end_line <- i
        break
      }
    }
    
    # 提取roxygen标题:向上查找第一个有效注释行
    title <- NA_character_
    for (i in (pos-1):1) {
      current_line <- lines[i]
      if (grepl("^#'\\s+", current_line)) {
        title <- gsub("^#'\\s+", "", current_line)
        break
      } else if (trimws(current_line) != "") {
        # 遇到非roxygen注释内容,停止查找
        break
      }
    }
    
    # 存入结果列表
    result[[fn_name]] <- list(
      line_start = pos,
      line_end = end_line,
      title = title
    )
  }
  
  return(result)
}

函数逻辑说明

  1. 定位函数起始行:通过正则匹配找到所有符合函数名 <- function(...)格式的行;
  2. 确定函数结束行:遍历行号统计大括号的开闭数量,确保找到函数定义对应的闭合大括号(支持嵌套大括号场景);
  3. 提取roxygen标题:从函数起始行向上遍历,找到第一个以#' 开头的非空注释行,作为函数标题;
  4. 返回结果:将每个函数的起始行号、结束行号、标题信息整理为列表返回。

使用示例

调用函数前需先安装并加载stringr包:

install.packages("stringr")
library(stringr)

执行map_fn_definition("function.R"),会返回符合需求的结果:

#> $f_cool
#> $f_cool$line_start
#> [1] 6
#> 
#> $f_cool$line_end
#> [1] 9
#> 
#> $f_cool$title
#> [1] "This function is cool"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 06:55:31