使用 Tidyverse 的简单管道中的 assign() 行为不一致
Inconsistent assign() behavior in simple piping with Tidyverse
通过简单地改变连接步骤中的参数顺序,我可以得到下面的代码 运行。我刚刚安装了截至 post (1.3.1) 的最新版本的 Tidyverse,我使用的是 R 版本 4.1.1 (2021-08-10),“Kick Things”。请结束我的疯狂:
更新:
- 如果你 运行 没有连接语句的管道,分配工作正常(奇数)
- 我有一个旧版本的 tidyverse(我愚蠢地没有记录),代码会 运行。现在它不适用于最新版本的 tidyverse。不要让事情太复杂,但我是在另一台机器上用 R 版本 R 版本 3.6.3 (2020-02-29) 做的。
library(dplyr)
#Doesn't run
if(exists("test")) rm("test")
iris%>%
assign(x = "test",value = .,envir = .GlobalEnv)%>%
left_join(x = test,y =. ,by="Species")
#Runs
if(exists("test")) rm("test")
iris%>%
assign(x = "test",value = .,envir = .GlobalEnv)%>%
left_join(x = .,y =test ,by="Species")
这里的管道让事情变得有点混乱,但如果我们编写与嵌套函数相同的代码,我们会得到相同的效果:
#Doesn't run
if(exists("test")) rm("test")
left_join(x = test, y = assign("test", iris, envir = .GlobalEnv), by = "Species")
#Runs
if(exists("test")) rm("test")
left_join(x = assign("test", iris, envir = .GlobalEnv), y = test, by = "Species")
当你看到它是这样写的时,第一个版本没有 运行 的原因现在就明白了:你在 non-existent 对象上调用 left_join
;由于 left_join
是 S3 泛型,它仅评估 x
以确定方法分派,并将所有其他参数作为未评估的承诺传递给 left_join.data.frame
。由于y
没有被计算,test
没有被写入,所以我们得到一个test not found
错误。
在第二个版本中,y
参数直到在 left_join.data.frame
中被要求时才会被计算,而在它被计算时,test
已经被写入。
所以这种奇怪的行为是懒惰评估的结果。
通过简单地改变连接步骤中的参数顺序,我可以得到下面的代码 运行。我刚刚安装了截至 post (1.3.1) 的最新版本的 Tidyverse,我使用的是 R 版本 4.1.1 (2021-08-10),“Kick Things”。请结束我的疯狂:
更新:
- 如果你 运行 没有连接语句的管道,分配工作正常(奇数)
- 我有一个旧版本的 tidyverse(我愚蠢地没有记录),代码会 运行。现在它不适用于最新版本的 tidyverse。不要让事情太复杂,但我是在另一台机器上用 R 版本 R 版本 3.6.3 (2020-02-29) 做的。
library(dplyr)
#Doesn't run
if(exists("test")) rm("test")
iris%>%
assign(x = "test",value = .,envir = .GlobalEnv)%>%
left_join(x = test,y =. ,by="Species")
#Runs
if(exists("test")) rm("test")
iris%>%
assign(x = "test",value = .,envir = .GlobalEnv)%>%
left_join(x = .,y =test ,by="Species")
这里的管道让事情变得有点混乱,但如果我们编写与嵌套函数相同的代码,我们会得到相同的效果:
#Doesn't run
if(exists("test")) rm("test")
left_join(x = test, y = assign("test", iris, envir = .GlobalEnv), by = "Species")
#Runs
if(exists("test")) rm("test")
left_join(x = assign("test", iris, envir = .GlobalEnv), y = test, by = "Species")
当你看到它是这样写的时,第一个版本没有 运行 的原因现在就明白了:你在 non-existent 对象上调用 left_join
;由于 left_join
是 S3 泛型,它仅评估 x
以确定方法分派,并将所有其他参数作为未评估的承诺传递给 left_join.data.frame
。由于y
没有被计算,test
没有被写入,所以我们得到一个test not found
错误。
在第二个版本中,y
参数直到在 left_join.data.frame
中被要求时才会被计算,而在它被计算时,test
已经被写入。
所以这种奇怪的行为是懒惰评估的结果。