Ruby百分比计算来匹配Excel公式(需要重构)

我已经用Ruby写了两个简单的计算,它们与Microsoft Excel计算给定数据集的上下四分位数的方式相匹配 – 这与普遍接受的方法(意外)不一样。

我的问题是 – 为了最大限度地干燥,这些方法可以被重构多less,怎样最好?

 #与Microsoft Excel(Freund + Perles方法)相同的基础上返回上四分位值
   def excel_upper_quartile(array)
      返回nil,如果array.empty?
       sorted_array = array.sort
       u =(0.25 *(3 * sorted_array.length + 1))
      如果(uu.truncate).is_a?(Integer)
         return sorted_array [(uu.truncate)-1]
      其他
         sample = sorted_array [u.truncate.abs-1]
         sample1 = sorted_array [(u.truncate.abs)]
         return sample +((sample1-sample)*(uu.truncate))
      结束
  结束


   #在Microsoft Excel(Freund + Perles方法)的基础上返回一个较低的四分位值,
   def excel_lower_quartile(array)
      返回nil,如果array.empty?
       sorted_array = array.sort
       u =(0.25 *(sorted_array.length + 3))
      如果(uu.truncate).is_a?(Integer)
         return sorted_array [(uu.truncate)-1]
      其他
         sample = sorted_array [u.truncate.abs-1]
         sample1 = sorted_array [(u.truncate.abs)]
         return sample +((sample1-sample)*(uu.truncate))
      结束
  结束

我将首先概括一点,并提供一个方法来处理这两个实例。

 def excel_quartile(array, quartile) # Returns nil if array is empty and covers the case of array.length == 1 return array.first if array.length <= 1 sorted = array.sort # The 4th quartile is always the last element in the sorted list. return sorted.last if quartile == 4 # Source: http://mathworld.wolfram.com/Quartile.html quartile_position = 0.25 * (quartile*sorted.length + 4 - quartile) quartile_int = quartile_position.to_i lower = sorted[quartile_int - 1] upper = sorted[quartile_int] lower + (upper - lower) * (quartile_position - quartile_int) end 

那么你可以做一些方便的方法:

 def excel_lower_quartile(array) excel_quartile(array, 1) end def excel_upper_quartile(array) excel_quartile(array, 3) end 

注意: excel_quartile方法与quartile in { 1, 2, 3, 4}期望相匹配。 别的,我保证失败。

更新:

我所用的公式并没有在我引用的网站上明确给出,而是用于计算四分位数的弗氏和珀耳斯方法的抽象。

进一步更新:

在原始代码中有一个错误,尽pipe你不应该遇到这个错误: u - u.trunc总是在[ u - u.trunc区间内,因此唯一一个类似于整数的时候是u - u.trunc = 0 。 然而,当u是一个Float时, (u - u.trunc)仍然是一个Float的实例,所以你的代码不会发生在失算的索引上。 顺便说一句,如果u – u.trunc是一个整数,你的方法将返回数组的最后一个元素。

有些人可能不同意重构,但这是我如何处理它:

 def excel_quartile(extreme,array) return nil if array.empty? sorted_array = array.sort u = case extreme when :upper then 3 * sorted_array.length + 1 when :lower then sorted_array.length + 3 else raise "ArgumentError" end u *= 0.25 if (uu.truncate).is_a?(Integer) return sorted_array[(uu.truncate)-1] else sample = sorted_array[u.truncate.abs-1] sample1 = sorted_array[(u.truncate.abs)] return sample+((sample1-sample)*(uu.truncate)) end end def excel_upper_quartile(array) excel_quartile(:upper, array) end def excel_lower_quartile(array) excel_quartile(:lower, array) end