如何在输入非数值时终止R代码执行?函数报错求助
问题:添加数值检查逻辑后ci_boot函数报错“object 'pd' not found”
原本运行正常的ci_boot函数,在加入非数值输入时终止代码的判断逻辑后,调用时出现错误提示:Error in ci_boot(dat = x, by = wk, var = pd) : object 'pd' not found。相关代码如下:
#DATA library(tidyverse) x <- structure(list(wk = c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3), month = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), xd = c(0.0370098838217444, 0.0391215970961887, 0.0409865246890313, NA, NA, NA, NA, 0.015188, 0.007513, 0.012716, 0.013962, 0.014259, 0.023553, 0.032122, 0.03953, 0.028946, 0.030769, 0.030815, 0.029187, 0.022604), td = c(0.02701157274146, 0.0284158620689655, 0.0296560389182058, NA, NA, NA, NA, 0.0125, 0.007396, 0.010856, 0.011685, 0.011882, 0.018063, 0.023761, 0.028687, 0.021649, 0.022861, 0.022892, 0.021809, 0.017432), pd = c(317.308439683869, 0, 126.719553152898, NA, NA, NA, NA, 2671.6, 3540.6976744186, 1270.35740604274, 1067.69362430466, 688.099646524154, 317.444499806234, 420.941879550524, 280.475476696762, 250.681324772507, 159.048160622895, 258.125109208457, 450.868907331836, 0), year = c(2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007)), class = "data.frame", row.names = c(NA, -20L)) x$test <- rep("hi",nrow(x)) # 测试文本输入的情况 # 原正常运行的函数 ci_boot <- function(dat, by, var, conf.int = 0.90,...) { dat %>% group_by({{by}}) %>% dplyr::summarise(mean=list(smean.cl.boot({{var}}, conf.int=conf.int))) %>% unnest_wider(mean) } ci_boot(dat = x, by = wk, var = pd) # 添加检查后报错的函数 ci_boot <- function(dat, by, var, conf.int = 0.90,...) { if(!is.numeric(var)) {stop("'var' must be numeric")} # 尝试过给var加{{}}但无效 dat %>% group_by({{by}}) %>% dplyr::summarise(mean=list(smean.cl.boot({{var}}, conf.int=conf.int))) %>% unnest_wider(mean) } ci_boot(dat = x, by = wk, var = pd)
错误原因
你直接使用is.numeric(var)时,检查的是符号var本身,而非数据框dat中对应的列。函数调用时传入的pd是一个未在全局环境定义的符号,R无法找到这个对象,因此抛出“object 'pd' not found”的错误。
要正确判断输入列的类型,需要先从数据框中提取出指定列,再进行数值型检查。
修正后的代码
ci_boot <- function(dat, by, var, conf.int = 0.90,...) { # 从数据框中提取指定列,再检查是否为数值型 if(!is.numeric(pull(dat, {{var}}))) { stop("'var' must be numeric") } dat %>% group_by({{by}}) %>% dplyr::summarise(mean=list(smean.cl.boot({{var}}, conf.int=conf.int))) %>% unnest_wider(mean) } # 测试数值列(正常执行) ci_boot(dat = x, by = wk, var = pd) # 测试文本列(触发错误提示) ci_boot(dat = x, by = wk, var = test)
这里用pull(dat, {{var}})从数据框中提取用户指定的列,再用is.numeric判断类型,既实现了数值检查的逻辑,又避免了符号找不到的问题。
内容的提问来源于stack exchange,提问作者Salvador
相关产品推荐
相关产品推荐

