由于您更具体地询问 R 和 R 函数,我将重点回答这个问题。我会指出一些错误,然后提供一些替代解决方案。
您的第一个函数没有产生您想要的输出,原因有两个:
逻辑指示函数返回单个值而不是向量。如果您尝试在 for 循环中加载向量(没有异常值的向量),请确保在函数外部初始化向量:output <- vector()(请注意,在下面的解决方案中,但这不是必需的)。此外,它返回的值只是向量 RMS_x 中大于 RMS 的值,而不是找到异常值,如果这是你想要的,仅供参考。
你的 for 循环参数中有一个错误和/或拼写错误,这很轻微,但它会将你的 for 循环变成非循环——这显然与你的意图完全相反。 for循环需要一个向量来循环,参数应该是:for(i in 1:length(RMS_x))
在您的代码中,循环直接跳转到 i = 5,因为那是向量的长度 (length(RMS_x) = 5)。鉴于 RMS_x 向量中的值已经按升序排列,您的代码恰好给出了“正确”的答案,但这只是因为您最初加载向量的方式。这可能是您的问题中的一个错字,并且仅相差 2 个代码字符,但它完全改变了函数的查找内容。
解决方案:
要获得您想要完成的任务,您需要编写两个函数:1.) 定义数据集中的异常值;2.) 第二个函数,去除异常值并计算 RMS。然后从那里使函数独立或嵌套它们以传递变量(这种方式也符合您的奖金请求,因为它是编写函数的多种方式)。
异常值识别功能:
outlrs <- function(vec){
Q1 <- summary(vec)["1st Qu."]
Q3 <- summary(vec)["3rd Qu."]
# defining outliers can get complicated depending on your sample data but
# your data set is super simple so we'll keep it that way
IQR <- Q3 - Q1
lower_bound <- Q1 - 1.5*(IQR)
upper_bound <- Q3 + 1.5*(IQR)
bounds <- c(lower_bound, upper_bound)
return(bounds)
assign("non_outlier_range", bounds, envir = globalEnv())
# the assign() function will create an actual object in your environment
# called non_outlier_range that you can access directly - return()
# just mean the result will be spit out into the console or into a variable
# you load it into
}
现在转到第二个函数,这里有几个选项:
第一种方式:将 bounds 参数输入到 RMS_func()
RMS_func <- function(dat, bounds){
dat <- dat[!(dat < min(bounds)) & !(dat > max(bounds))]
dat_MEAN <- mean(dat)
dat_DIFF <- (dat-dat_MEAN)
dat_DIFF_SQ <- dat_DIFF^2
dat_FINAL <- sqrt(sum(dat_DIFF_SQ)/length(dat))
return(dat_FINAL)
}
# Call function from approach 1 - note that here the assign() in the
# definition of outlrs() would be required to refer to non_outlier_range:
RMS_func(dat = RMS_x, bounds = non_outlier_range)
第二种方式:在第二个函数中调用 outlrs()
RMS_func <- function(dat){
bounds <- outlrs(vec = dat)
dat <- dat[!(dat < min(bounds)) & !(dat > max(bounds))]
dat_MEAN <- mean(dat)
dat_DIFF <- (dat-dat_MEAN)
dat_DIFF_SQ <- dat_DIFF^2
dat_FINAL <- sqrt(sum(dat_DIFF_SQ)/length(dat))
return(dat_FINAL)
}
# Call RMS_func - here the assign() in outlrs() would not be needed is not
# needed because the output will exist within the functions temp environment
# and be passed to RMS_func
RMS_func(dat = RMS_x)
第三种方式:在 RMS_Func 中嵌套 outlrs() 定义 - 在这种情况下,您只需要一个嵌套函数即可完成任务
RMS_Func <- function(dat){
outlrs <- function(vec){
Q1 <- summary(dat)["1st Qu."]
Q3 <- summary(dat)["3rd Qu."]
#Q1 <- quantile(vec)["25%"]
#Q3 <- summary(vec)["75%"]
IQR <- Q3 - Q1
lower_bound <- Q1 - 1.5*(IQR)
upper_bound <- Q3 + 1.5*(IQR)
bounds <- c(lower_bound, upper_bound)
return(bounds)
}
bounds <- outlrs(vec = dat)
dat <- dat[!(dat < min(bounds)) & !(dat > max(bounds))]
dat_MEAN <- mean(dat)
dat_DIFF <- (dat-dat_MEAN)
dat_DIFF_SQ <- dat_DIFF^2
dat_FINAL <- sqrt(sum(dat_DIFF_SQ)/length(dat))
return(dat_FINAL)
}
附:写得很快——以后可能会重新测试和编辑。希望现在这会有所帮助。