R的可管道分配功能——不分配任何东西
Pipeable assign function for R -- does not assign anything
我一直在尝试制作一个可管道化的 assign() 函数,以便在循环中与 paste0() 结合使用。
但是我无法让它实际分配任何东西,例如
assignp <- function(value, x) {
assign(x, value)
}
assignp(13, "thirteen")
print(thirteen)
returns:
Error in print(thirteen) : object 'thirteen' not found
没有错误信息,只是没有给指定的变量名赋值。
谁能告诉我我做错了什么?
默认情况下 assign
在其当前范围内赋值,即在本例中的函数内。在 assign
.
中指定 envir = parent.frame()
assignp <- function(value, x) {
assign(x, value, envir = parent.frame())
#You can also use .GlobalEnv to assign to global environment directly.
#assign(x, value, envir = .GlobalEnv)
}
assignp(13, "thirteen")
thirteen
#[1] 13
问题中的代码确实分配了它,但分配给了存在于 运行 函数中的环境(有时称为框架),因此当该函数退出时它会丢失。试试这个定义。请注意,重要的是 envir 是解决一般情况的参数。
assignp <- function(value, x, envir = parent.frame()) {
assign(x, value, envir)
}
下面我们讨论使用 %>% 在全局环境中使用它,在函数中使用 %>% 以及在这两种情况下使用 |> 。 magrittr 还定义了一个顺序管道,但没有为它定义一个运算符,我们展示了如何使用它来进一步简化它。我们还表明 assignp 并不是真正需要的,我们可以只使用 assign。
使用 %>%
请注意,如果我们遗漏了 .GlobalEnv,那么 13 将被注入到管道创建的临时环境中,因此在管道的下一段将无法访问它,并且以下将给出错误。
library(magrittr)
if (exists("thirteen")) rm(thirteen)
13 %>% assignp("thirteen", .GlobalEnv) %>% { . + thirteen }
## [1] 26
thirteen
## 13
使用 %>%
从函数调用
通过传递当前环境,在其中定义了 13 个,而不是在管道创建的任何临时环境中。如果我们想将 13 注入到全局环境中,我们可以交替使用 e <- .GlobalEnv。
f <- function(x) {
e <- environment()
x %>%
assignp("thirteen", e) %>%
{ . + thirteen }
}
if (exists("thirteen")) rm(thirteen)
f(13)
## [1] 26
exists("thirteen")
## [1] FALSE
使用 |>
|> 不创建环境,所以这有效。
if (exists("thirteen")) rm(thirteen)
13 |> assignp("thirteen") |> (\(x) x + thirteen)()
## [1] 26
thirteen
## 13
g <- function(x) x |> assignp("thirteen") |> (\(x) x + thirteen)()
if (exists("thirteen")) rm(thirteen)
g(13)
## [1] 26
exists("thirteen")
## [1] FALSE
仅使用赋值
实际上我们根本不需要assignp。这些都有效:
if (exists("thirteen")) rm(thirteen)
13 %>% assign("thirteen", ., .GlobalEnv) %>% { . + thirteen }
f2 <- function(x) {
e <- environment()
x %>%
assign("thirteen", ., e) %>%
{ . + thirteen }
}
if (exists("thirteen")) rm(thirteen)
f2(13)
g2 <- function(x) x |> assign(x = "thirteen") |> (\(x) x + thirteen)()
if (exists("thirteen")) rm(thirteen)
g2(13)
magrittr 顺序管道
magrittr 定义了一个顺序管道,但目前没有它的运算符;但是,我们可以很容易地定义一个。
`%s>%` <- pipe_eager_lexical
f3 <- function(x) x %s>% assign("thirteen", .) %>% { . + thirteen }
if (exists("thirteen")) rm(thirteen)
f3(13)
## [1] 26
更新
扩展并修复了错误。
我一直在尝试制作一个可管道化的 assign() 函数,以便在循环中与 paste0() 结合使用。
但是我无法让它实际分配任何东西,例如
assignp <- function(value, x) {
assign(x, value)
}
assignp(13, "thirteen")
print(thirteen)
returns:
Error in print(thirteen) : object 'thirteen' not found
没有错误信息,只是没有给指定的变量名赋值。
谁能告诉我我做错了什么?
默认情况下 assign
在其当前范围内赋值,即在本例中的函数内。在 assign
.
envir = parent.frame()
assignp <- function(value, x) {
assign(x, value, envir = parent.frame())
#You can also use .GlobalEnv to assign to global environment directly.
#assign(x, value, envir = .GlobalEnv)
}
assignp(13, "thirteen")
thirteen
#[1] 13
问题中的代码确实分配了它,但分配给了存在于 运行 函数中的环境(有时称为框架),因此当该函数退出时它会丢失。试试这个定义。请注意,重要的是 envir 是解决一般情况的参数。
assignp <- function(value, x, envir = parent.frame()) {
assign(x, value, envir)
}
下面我们讨论使用 %>% 在全局环境中使用它,在函数中使用 %>% 以及在这两种情况下使用 |> 。 magrittr 还定义了一个顺序管道,但没有为它定义一个运算符,我们展示了如何使用它来进一步简化它。我们还表明 assignp 并不是真正需要的,我们可以只使用 assign。
使用 %>%
请注意,如果我们遗漏了 .GlobalEnv,那么 13 将被注入到管道创建的临时环境中,因此在管道的下一段将无法访问它,并且以下将给出错误。
library(magrittr)
if (exists("thirteen")) rm(thirteen)
13 %>% assignp("thirteen", .GlobalEnv) %>% { . + thirteen }
## [1] 26
thirteen
## 13
使用 %>%
从函数调用通过传递当前环境,在其中定义了 13 个,而不是在管道创建的任何临时环境中。如果我们想将 13 注入到全局环境中,我们可以交替使用 e <- .GlobalEnv。
f <- function(x) {
e <- environment()
x %>%
assignp("thirteen", e) %>%
{ . + thirteen }
}
if (exists("thirteen")) rm(thirteen)
f(13)
## [1] 26
exists("thirteen")
## [1] FALSE
使用 |>
|> 不创建环境,所以这有效。
if (exists("thirteen")) rm(thirteen)
13 |> assignp("thirteen") |> (\(x) x + thirteen)()
## [1] 26
thirteen
## 13
g <- function(x) x |> assignp("thirteen") |> (\(x) x + thirteen)()
if (exists("thirteen")) rm(thirteen)
g(13)
## [1] 26
exists("thirteen")
## [1] FALSE
仅使用赋值
实际上我们根本不需要assignp。这些都有效:
if (exists("thirteen")) rm(thirteen)
13 %>% assign("thirteen", ., .GlobalEnv) %>% { . + thirteen }
f2 <- function(x) {
e <- environment()
x %>%
assign("thirteen", ., e) %>%
{ . + thirteen }
}
if (exists("thirteen")) rm(thirteen)
f2(13)
g2 <- function(x) x |> assign(x = "thirteen") |> (\(x) x + thirteen)()
if (exists("thirteen")) rm(thirteen)
g2(13)
magrittr 顺序管道
magrittr 定义了一个顺序管道,但目前没有它的运算符;但是,我们可以很容易地定义一个。
`%s>%` <- pipe_eager_lexical
f3 <- function(x) x %s>% assign("thirteen", .) %>% { . + thirteen }
if (exists("thirteen")) rm(thirteen)
f3(13)
## [1] 26
更新
扩展并修复了错误。