如何解决R管道,mget和环境
我将其发布,希望有人可以在这里解释其行为。也许这可以为其他人节省一些时间来跟踪如何解决类似的错误。
答案可能在this vignette by Hadley Wickham and Lionel Henry中的此处。然而,像我这样的人需要花几周的时间才能把点子联系起来。
我正在从远程数据库运行许多查询,然后将它们组合到单个data.table中。我在每个查询结果的名称前添加“ part_”前缀,并将ls()
和mget()
与data.table的rbindlist()
结合使用。
这有效:
results_all <- rbindlist(mget(ls(pattern = "part_",)))
我可能是从list data.tables in memory and combine by row (rbind)那里学到的,这对确定如何做是很有帮助的。
出于可读性考虑,我通常更喜欢使用magrittr管道(或与data.table链接),尤其是在这样的项目中,因为我使用dplyr来查询数据库。但是此代码会导致错误:
results_all <- ls(pattern = "part_",) %>%
mget() %>%
rbindlist()
错误读取Error: value for ‘part_a’ not found
,其中part_a是ls()
返回的字符向量中的第一个对象名称。
搜索该错误消息时,我遇到了讨论in this data.table Github issue。仔细阅读后,我尝试在mget()中设置“ inherits = TRUE”,如下所示:
results_all <- ls(pattern = "part_",) %>%
mget(inherits = TRUE) %>%
rbindlist()
那行得通。因此,将ls()
的结果传递到mget()
时会发生错误。并且考虑到将ls()嵌套在mget()中的工作原理,我的猜测是这与管道和“环境的封闭框架”有关。
在撰写本文时,我遇到了Unexpected error message while joining data.table with rbindlist() using mget()。从讨论中,我发现这也行得通。
results_all <- ls(pattern = "part_",) %>%
mget(envir = .GlobalEnv) %>%
rbindlist()
再次,我希望有人能解释那些希望了解有关R中环境如何工作的人们的情况。
根据对可重复答案的请求,应使用这三个data.tables(data.frames或tibble的行为相同)运行上面的代码。
part_a <- data.table(col1 = 1:10,col2 = sample(letters,10))
part_b <- data.table(col1 = 11:20,10))
part_c <- data.table(col1 = 21:30,10))
解决方法
解释器从不将管道操作符的rhs
参数(在您的示例中为表达式mget()
)视为函数调用。管道运算符是一个infix函数,它对第二个参数(rhs
)执行非标准评估。管道函数使用RHS表达式作为一种“模板”来组成并执行新的函数调用。
此新函数调用的调用环境是%>%
的函数环境,而不是lhs
函数的调用环境或全局环境。 .GlobalEnv
和lhs
函数的调用环境在您的示例中恰好是同一环境,并且该环境是%>%
函数环境的父级,这就是{{1 }}或将环境设置为inherits = TRUE
都可以。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。