R函数逐行运行正常但调用时报‘f未找到’的原因及解决
问题原因
核心是作用域(环境)不匹配:
subset()默认会在调用它的上层环境中查找数据框外的变量(比如f)- 当通过
map(E, subset, A %in% f)调用时,subset的执行环境是purrr::map的内部环境,而非你的test函数内部环境,因此找不到f - 逐行执行时
subset在当前交互环境(全局)查找,全局有f时函数能运行,均印证了这一点
解决方法
以下是3种可行方案,按推荐度排序:
方案1:用dplyr::filter替代subset(推荐)
dplyr的filter基于tidy eval机制,能自动识别函数内部的变量,无需额外处理:
library(tidyverse) library(ggthemes) library(ggrepel) library(readxl) test=function(a){ f=as.character(c(a,a)) b="g" D=data.frame(A=c("a","b","c"),B=c(1:3)) E=list(D,D) print(f) # 用filter替代subset,并用get(b)获取赋值后的变量 assign(b, map(E, filter, A %in% f)) get(b) } # 测试调用 a="a";test(a)
方案2:给subset显式指定环境
通过subset的envir参数,强制它在test函数的环境中查找f:
test=function(a){ f=as.character(c(a,a)) b="g" D=data.frame(A=c("a","b","c"),B=c(1:3)) E=list(D,D) print(f) assign(b, map(E, subset, A %in% f, envir = environment())) get(b) }
方案3:用匿名函数包裹subset
将subset放在匿名函数内,绑定f的作用域到test函数内部:
test=function(a){ f=as.character(c(a,a)) b="g" D=data.frame(A=c("a","b","c"),B=c(1:3)) E=list(D,D) print(f) assign(b, map(E, function(x) subset(x, A %in% f))) get(b) }
额外提示
函数最后直接写g会报错,因为g是通过assign创建在函数内部环境的,需用get(b)获取。更规范的写法是避免assign,直接返回map的结果,在外部赋值:
test=function(a){ f=as.character(c(a,a)) D=data.frame(A=c("a","b","c"),B=c(1:3)) E=list(D,D) print(f) map(E, filter, A %in% f) } # 外部赋值 a="a"; g <- test(a)
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

