【问题标题】:R programming Function (Returning a subset of Real Mean Squared)R 编程函数(返回实数均方的子集)
【发布时间】:2018-06-06 11:13:43
【问题描述】:

我是 R 新手,正在编写一些很酷的函数,同时我并行学习统计数据。我正在尝试制作一个函数,该函数将采用数字向量,执行“均方根”运算,然后让输出返回基本相同的向量,并删除可能的异常值。

例如,如果向量是 c(2,4,9,10,100),则生成的 RMS 约为 37。

因此,我希望输出返回相同的向量,并从数据集中删除可能的异常值(在本例中为 100)。所以结果将是 2, 4, 9, 10

我将代码放在下面,但输出不起作用。我尝试了两种不同的方式。一切都在说 RMS final 有效。但低于它没有。

我怎样才能修改这个函数,让它做我想做的事?此外,作为奖励,这可能会要求很多,但根据我下面的编码,对于新手制作函数的任何提示,我也会感激不尽。非常感谢!

RMS_x <- c(2,4,9,10,100)

#Root Mean Squared Function - Takes a numeric vector
RMS <- function(RMS_x){
    RMS_MEAN <- mean(RMS_x)
    RMS_DIFF <- (RMS_x-RMS_MEAN)
    RMS_DIFF_SQ <- RMS_DIFF^2
    RMS_FINAL <- sqrt(sum(RMS_DIFF_SQ)/length(RMS_x))

    for(i in length(RMS_x)){
            if(abs(RMS_x[i]) > RMS_FINAL){
                  output <- RMS_x[i]}
                  else {NULL} }
    return(output)  
}




#Root Mean Squared Function - Takes a numeric vector
RMS <- function(RMS_x){
  RMS_MEAN <- mean(RMS_x)
  RMS_DIFF <- (RMS_x-RMS_MEAN)
  RMS_DIFF_SQ <- RMS_DIFF^2
  RMS_FINAL <- sqrt(sum(RMS_DIFF_SQ)/length(RMS_x))

    #output <- ifelse(abs(RMS_x) > RMS_FINAL,RMS_x, NULL)
  return(RMS_FINAL)  
}

【问题讨论】:

    标签: r vector statistics numeric rms


    【解决方案1】:

    由于您更具体地询问 R 和 R 函数,我将重点回答这个问题。我会指出一些错误,然后提供一些替代解决方案。

    您的第一个函数没有产生您想要的输出,原因有两个:

    1. 逻辑指示函数返回单个值而不是向量。如果您尝试在 for 循环中加载向量(没有异常值的向量),请确保在函数外部初始化向量:output &lt;- vector()(请注意,在下面的解决方案中,但这不是必需的)。此外,它返回的值只是向量 RMS_x 中大于 RMS 的值,而不是找到异常值,如果这是你想要的,仅供参考。

    2. 你的 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)  
    
    }
    

    附:写得很快——以后可能会重新测试和编辑。希望现在这会有所帮助。

    【讨论】:

      【解决方案2】:

      尝试遵循 RMS 函数的第一行。

      RMS <- function(RMS_x) {
         bp <- boxplot(RMS, plot = FALSE)
         RMS_x <- RMS_x[!(RMS_x %in% bp$out)]
         ...
      

      现在,RMS_x 没有异常值。

      箱线图函数有一种确定异常值的方法。在这里,我正在使用它来删除它们。

      【讨论】:

      • 我想把它作为学习 R 的练习,而不是真正完成任何特别的事情。所以我真的不想使用箱线图。我只是想学习如何让它按照我想象的方式工作。但我非常感谢你的努力。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-05
      • 2022-12-07
      • 2019-12-06
      • 2012-07-28
      • 2022-11-02
      相关资源
      最近更新 更多