【问题标题】:Same R function works as function/object in Global Env, does not work when loaded from R package相同的 R 函数在全局环境中用作函数/对象,从 R 包加载时不起作用
【发布时间】:2016-12-08 16:54:15
【问题描述】:

这可能是一个很难回答的问题,因为如果不向 Gmail API 提供访问令牌,我就无法轻松提供可重现的 SNAFU,但我希望我遇到的问题从我的描述中可以清楚地看出.我们拭目以待……

我编写了一个函数,该函数获取 Google Scholar Alert 的 gmail 消息 ID,并将其解析为一个数据框,其中包含文章标题、作者、出版物、日期等列。我的难题是相同的代码在我以交互方式加载它(即,将函数加载到会话 RAM 中,当我将函数作为 R 包的一部分加载时(a la 'devtools:: load_all("/mypackage/")')。值得注意的是,我的包中的另一个主要功能无论哪种方式都可以正常工作,但是当我通过 devtools::load_all("my_misbehave_package/") 加载包后尝试从包版本中使用它时,这个功能会出错。

以下是函数的 .R 文件内容,该函数在作为包的一部分加载时不会出现 - 我在此提前承认这是一些丑陋的代码混乱,如果这样可以节省我的手指在你的答案中摇摆不定。这感觉就像经典的“作为因素的字符串”SNAFU 的软件包版本,但你告诉我。问题似乎在函数评估的早期就出现了,我得到的错误如下:

UseMethod("read_xml") 中的错误: 'read_xml' 没有适用的方法应用于“NULL”类的对象

这是我这个函数的完整代码:

library(stringr)
library(rvest)
library(plyr)
library(dplyr)
library(lubridate)
library(gmailr)

GScholar_alert_msg_to_df <- function(message_id){
     one_message <- message(message_id)
     msg_html <- body(one_message)
     title <- read_html(msg_html) %>% html_nodes("h3") %>% html_text()
     link <- read_html(msg_html) %>% html_nodes("h3 a") %>% html_attr("href")
     msg_chunks <- msg_html %>% str_split("<a href") %>% unlist
     msg_chunks <- msg_chunks[2:(length(msg_chunks)-2)]
     excerpt <- msg_chunks %>% str_replace_all(fixed("<b>"), "") %>%
          str_replace_all(fixed("</b>"), "") %>%
          str_replace_all(fixed("<br>"), "") %>%
          str_extract("<(font size=2 color=#222222|font size=\"-1\")>(.*?)</font>") %>%
          unlist %>% str_replace_all("<(font size=2 color=#222222||font size=\"-1\")>", "") %>%
          str_replace_all("</font>", "")
     author_pub_field <- msg_chunks %>% str_replace_all(fixed("<b>"), "") %>%
     str_replace_all(fixed("</b>"), "") %>%
     str_extract("<font size=(2|\"-1\") color=#(006621|009933|008000)>(.*?)</font>") %>%
     unlist %>%
     str_replace_all("<font size=(2|\"-1\") color=#(006621|009933|008000)>", "") %>%
     str_replace_all("</font>", "")
     one_message_df <- data.frame(title, excerpt, link, author_pub_field, stringsAsFactors = FALSE)
     one_message_df$date <- date(one_message) # needs reformatting
     one_message_df$date %>% str_replace("[[:alpha:]]{3}, ", "") %>%
          str_extract("^.{11}") %>% dmy -> one_message_df$date
     one_message_df$author_only <- str_detect(one_message_df$author_pub_field, " - ")
     one_message_df$author <- one_message_df$author_pub_field %>%
          str_extract("^(.*?) - ") %>% str_replace(" - ", "")
     one_message_df$author <- ifelse(one_message_df$author_only == 1, one_message_df$author, one_message_df$author_pub_field)
     one_message_df$publication <- one_message_df$author_pub_field %>%
          str_extract(" - (.*?)$") %>% str_replace(" - ", "") %>%
          str_replace(", [0-9]{4}$", "") %>% str_replace("^[0-9]{4}$", NA)
     one_message_df$publication <- str_replace(one_message_df$publication, "^[0-9]{4}$", NA)
     one_message_df$author_MIAs <- str_detect(one_message_df$author, "&hellip;")
     one_message_df$author %>% str_replace("&hellip;", " \\.\\.\\.") ->      one_message_df$author
     one_message_df$pub_name_clipped <- one_message_df$publication %>% str_detect("&hellip;")
     one_message_df$publication %>% str_replace("&hellip;", " \\.\\.\\.") -> one_message_df$publication
     return(one_message_df)

是的,它很难看,但我再次保证它在以交互方式输入代码时有效。至于行为不端的包版本,根据 RStudio 回溯,错误似乎发生在顶部,我认为我在 gmailr 包中使用的 body() 或 message() 函数。 (是的,我已经通过终端尝试了代码,但没有得到更愉快的结论。)帮助我,哦,任何人,你是我唯一的希望。

【问题讨论】:

  • 你是如何创建你的包的? NAMESPACE 文件中有什么?您是否将所有这些包都列为“导入”?
  • @MrFlick 我使用下拉菜单中的“新项目...”选项从 RStudio 中启动了包。我什至没有打开 NAMESPACE 文件,所以它只有一个通用的正则表达式行。我在包的 .R 文件之一的顶部有该包列表,因此当我加载包时它们会加载。
  • 您不应该在包的代码中包含 library() 语句。您应该以不同的方式设置 NAMESPACE。也许结帐writing R packages。你也不能减少这个例子以使其最小化可重现吗?究竟是哪一行导致了错误(删除任何与错误没有直接关系的行)?
  • 我知道打包代码中的 library() 语句是一个禁忌,但直到现在还没有遇到过问题,所以如果它是我自己使用的包,我没有看到它的危害。我会正确地做到这一点并报告它是否解决了问题。 // 我看不出如何为此提供可重现的代码,因为它依赖于拥有 client_id.json 文件来访问 Gmail API。

标签: r scope package environment-variables packages


【解决方案1】:

感谢@MrFlick 指出走出困境的方法。我能够通过将该包列表移动到说明文件的“依赖”字段来解决问题,而且我还必须使用“::”运算符来显式调用“正文”和“日期”函数来自 gmailr 包。这两个名称也属于非标准函数,它们是“基本”命名空间的一部分,并且不能通过在包环境中加载 gmailr 来掩盖它们。根据 Hadley 的说法,当我编写自己的包时,每次使用另一个包中的函数时,我都应该使用 '::'。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    • 2012-10-20
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 2018-05-04
    • 2022-11-02
    相关资源
    最近更新 更多