在purrr::map中调用自定义函数时指定数据框未找到的问题求助
问题原因与解决方案
问题根源
这是R的作用域规则导致的:
filter_fn()是在全局环境中定义的函数,它执行时会优先在自己的**定义环境(全局环境)**里查找iris1对象;- 你在
map的匿名函数内部创建的iris1,只存在于匿名函数的局部环境中,全局环境并没有这个对象,所以filter_fn()自然找不到它。
解决方案
推荐采用函数传参的写法(最规范、易维护):
library(tidyverse) # 修改filter_fn,让它接收数据参数 filter_fn <- function(data){ data %>% filter(Sepal.Length < 4) } map(.x = list("setosa","virginica"), .f = function(species){ iris1 <- filter(iris, Species %in% species) # 把iris1作为参数传入filter_fn iris2 <- filter_fn(iris1) return(iris2) })
如果一定要保持filter_fn无参数的写法(不推荐,依赖环境会降低代码可读性),可以临时修改它的执行环境:
library(tidyverse) filter_fn <- function(){ iris1 %>% filter(Sepal.Length < 4) } map(.x = list("setosa","virginica"), .f = function(species){ iris1 <- filter(iris, Species %in% species) # 将filter_fn的执行环境切换到当前匿名函数的局部环境 environment(filter_fn) <- environment() iris2 <- filter_fn() return(iris2) })
额外说明
尽量让函数成为纯函数:只依赖明确传入的参数,不依赖外部环境变量。这种写法的代码更清晰,调试和复用性更强,也能避免大部分作用域相关的问题。
内容的提问来源于stack exchange,提问作者Basil
相关产品推荐
相关产品推荐

