R 在函数中使用eval()时应该调用哪个环境?
我有一系列的函数,我正在尝试使用它们,我正在努力找出为什么这个任务不起作用。以下是我正在使用的函数:R 在函数中使用eval()时应该调用哪个环境?,r,scope,eval,R,Scope,Eval,我有一系列的函数,我正在尝试使用它们,我正在努力找出为什么这个任务不起作用。以下是我正在使用的函数: new_timeline <- function() { timeline = structure(list(), class="timeline") timeline$title <- list("text" = list("headline" = NULL, "text" = NULL), "start_date" =
new_timeline <- function() {
timeline = structure(list(), class="timeline")
timeline$title <- list("text" = list("headline" = NULL, "text" = NULL),
"start_date" = list("year" = NULL, "month" = NULL, "day" = NULL),
"end_date" = list("year" = NULL, "month" = NULL, "day" = NULL))
return(timeline)
}
.add_date <- function(self, date, time_type) {
valid_date <- stringr::str_detect(date, "^[0-9]{4}(-[0-9]{1,2}){0,2}$")
if (!valid_date) {
stringr::str_interp("Your ${time_type} date does not appear to be formatted correctly. It must be of the form 'yyyy-mm-dd'. Only the year is required.") %>% stop()
}
date_elements <- date %>% as.character() %>% stringr::str_split(" ") %>% unlist()
date <- date_elements[1] %>% stringr::str_split("-") %>% unlist()
stringr::str_interp("self$title$${time_type}_date$year <- date[1]") %>% parse(text = .) %>% eval()
if (!is.na(date[2])) stringr::str_interp("self$title$${time_type}_date$month <- date[2]") %>% parse(text = .) %>% eval()
if (!is.na(date[3])) stringr::str_interp("self$title$${time_type}_date$day <- date[3]") %>% parse(text = .) %>% eval()
return(self)
}
edit_title <- function(self, headline = NULL, text = NULL, start_date = NULL, end_date = NULL) {
if (class(self) != "timeline") stop("The object passed must be a timeline object.")
if (is.null(headline) && is.null(self$title$text$headline)) stop("Headline cannot be empty when adding a new title.")
if (!is.null(headline)) self$title$text$headline <- headline
if (!is.null(text)) self$title$text$text <- text
if (!is.null(start_date)) self <- .add_date(self, date = start_date, time_type = "start")
if (!is.null(end_date)) self <- .add_date(self, date = end_date, time_type = "end")
return(self)
}
new_时间线%unlist()
stringr::str_interp(“self$title$${time\u type}}\u date$year如评论中所述,我认为您可能不需要所有的代码解析,只需在[[
用于您的作业。无论如何,当您使用管道操作符时,会发生一系列函数换行,因此确定要返回多少帧是一件痛苦的事情。以下是修改.add\u date
函数的几种解决方案
您已经找到了一个,使用%
解析(text=)%%>%eval(envir=sys.frame(goback))
##解决方案2:使用函数中定义的环境
如果在运行示例时(!is.na(date[2])stringr::str_interp(“self$title$${time\u type}}\u date$month),则我得到无法找到函数“edit\u timeline”
@Pascal Good call;这是我的一个输入错误。它已经被更正。哦,伙计,环境与管道操作符变得非常复杂。你有没有可能简化这个示例?快速通读之后,大多数代码看起来都不相关。这是一种奇怪的方式,很难了解发生了什么。我不知道首先,我要理解你为什么要使用str\u interp
。你可以使用self$title[[paste0(time\u type),“\u date”]]$month这样一个简单的解决方案。我不知道为什么我不想使用[[
…我非常感谢您对环境和框架的解释,并演示了如何调试这些内容,但我最终还是使用了您的简化来修复我的代码。感谢您的帮助!很高兴听到您这样说!这就是正确的方法
library(magrittr)
#devtools::install_github("hadley/stringr")
library(stringr)
tl <- new_timeline()
tl <- tl %>% edit_title(headline = "My Timeline", text = "Example", start_date = "2015-10-18")
.add_date <- function(self, date, time_type) {
valid_date <- stringr::str_detect(date, "^[0-9]{4}(-[0-9]{1,2}){0,2}$")
if (!valid_date) {
stringr::str_interp("Your ${time_type} date does not appear to be formatted correctly. It must be of the form 'yyyy-mm-dd'. Only the year is required.") %>% stop()
}
## Examining environemnts
e <- environment() # current env
efirst <- sys.nframe() # frame number
print(paste("Currently in frame", efirst))
envs <- stringr::str_interp("${date}") %>% parse(text=.) %>% {.; sys.frames()} # list of frames
elast <- stringr::str_interp("${date}") %>% parse(text=.) %>% {.; sys.nframe()} # number of last
print(paste("Went", elast, "frames deep."))
## Go back this many frames in eval
goback <- efirst-elast
date_elements <- date %>% as.character() %>% stringr::str_split(" ") %>% unlist()
date <- date_elements[1] %>% stringr::str_split("-") %>% unlist()
## Solution 1: use sys.frame
stringr::str_interp("self$title$${time_type}_date$year <- date[1]") %>%
parse(text = .) %>% eval(envir=sys.frame(goback))
## Solution 2: use environment defined in function
if (!is.na(date[2])) stringr::str_interp("self$title$${time_type}_date$month <- date[2]") %>%
parse(text = .) %>% eval(envir=e)
return(self)
}