class RailsDataExplorer::DataType::Quantitative

This is an abstract class. Use sub_classes

Responsibilities:

* Provide available charts and statistics for quantitative data type.
* Provide methods for quantitative data type.

Collaborators:

* DataSet

Public Instance Methods

all_available_chart_types() click to toggle source
# File lib/rails_data_explorer/data_type/quantitative.rb, line 16
def all_available_chart_types
  [
    # {
    #   chart_class: Chart::BoxPlot,
    #   chart_roles: [:y],
    #   dimensions_count_min: 1,
    #   dimensions_count_max: 1
    # },
    {
      chart_class: Chart::HistogramQuantitative,
      chart_roles: [:x],
      dimensions_count_min: 1,
      dimensions_count_max: 1
    },
    {
      chart_class: Chart::BoxPlotGroup,
      chart_roles: [:x],
      dimensions_count_min: 2,
      dimensions_count_max: 2,
    },
    {
      chart_class: Chart::Scatterplot,
      chart_roles: [:x, :y, :size],
      dimensions_count_min: 2
    },
    {
      chart_class: Chart::DescriptiveStatisticsTable,
      chart_roles: [:any],
      dimensions_count_min: 1,
      dimensions_count_max: 1
    },
    {
      chart_class: Chart::ParallelCoordinates,
      chart_roles: [:dimension],
      dimensions_count_min: 3,
    },
  ].freeze
end
axis_scale(data_series, modification, d3_or_vega) click to toggle source
# File lib/rails_data_explorer/data_type/quantitative.rb, line 134
def axis_scale(data_series, modification, d3_or_vega)
  # Log scales can't handle 0 values
  if data_series.min_val(modification) > 0.0 && data_series.has_large_dynamic_range?(modification)
    { d3: 'd3.scale.log', vega: 'log' }[d3_or_vega]
  else
    { d3: 'd3.scale.linear', vega: 'linear' }[d3_or_vega]
  end
end
axis_tick_format(values) click to toggle source
# File lib/rails_data_explorer/data_type/quantitative.rb, line 130
def axis_tick_format(values)
  raise "Implement me in sub_class"
end
descriptive_statistics(values) click to toggle source
# File lib/rails_data_explorer/data_type/quantitative.rb, line 55
def descriptive_statistics(values)
  non_nil_values = values.find_all { |e| !(e.nil? || Float::NAN == e) }
  stats = ::DescriptiveStatistics::Stats.new(non_nil_values)
  ruby_formatters = {
    integer: Proc.new { |v|
      v.nil? ? 'Null' : number_with_delimiter(v.round)
    },
    decimal: Proc.new { |v|
      case
      when v.nil?
        'Null'
      when v.is_a?(Float) && v.nan?
        'NaN'
      else
        number_with_precision(
          v,
          precision: 3,
          significant: true,
          strip_insignificant_zeros: true,
          delimiter: ','
        )
      end
    },
    pass_through: Proc.new { |v| (v.nil? || Float::NAN == v) ? 'NaN' : v },
  }
  [
    { label: 'Min', value: stats.min, ruby_formatter: ruby_formatters[:decimal], table_row: 1 },
    { label: '1%ile', value: stats.value_from_percentile(1), ruby_formatter: ruby_formatters[:decimal], table_row: 1 },
    { label: '5%ile', value: stats.value_from_percentile(5), ruby_formatter: ruby_formatters[:decimal], table_row: 1 },
    { label: '10%ile', value: stats.value_from_percentile(10), ruby_formatter: ruby_formatters[:decimal], table_row: 1 },
    { label: '25%ile', value: stats.value_from_percentile(25), ruby_formatter: ruby_formatters[:decimal], table_row: 1 },
    { label: 'Median', value: stats.median, ruby_formatter: ruby_formatters[:decimal], table_row: 1 },
    { label: '75%ile', value: stats.value_from_percentile(75), ruby_formatter: ruby_formatters[:decimal], table_row: 1 },
    { label: '90%ile', value: stats.value_from_percentile(90), ruby_formatter: ruby_formatters[:decimal], table_row: 1 },
    { label: '95%ile', value: stats.value_from_percentile(95), ruby_formatter: ruby_formatters[:decimal], table_row: 1 },
    { label: '99%ile', value: stats.value_from_percentile(99), ruby_formatter: ruby_formatters[:decimal], table_row: 1 },
    { label: 'Max', value: stats.max, ruby_formatter: ruby_formatters[:decimal], table_row: 1 },

    { label: 'Range', value: stats.range, ruby_formatter: ruby_formatters[:decimal], table_row: 2 },
    { label: 'Mean', value: stats.mean, ruby_formatter: ruby_formatters[:decimal], table_row: 2 },
    { label: 'Mode', value: stats.mode, ruby_formatter: ruby_formatters[:decimal], table_row: 2 },
    { label: 'Count', value: values.length, ruby_formatter: ruby_formatters[:integer], table_row: 2 },
    { label: 'Sum', value: non_nil_values.inject(0) { |m,e| m += e }, ruby_formatter: ruby_formatters[:decimal], table_row: 2 },
    { label: 'Variance', value: stats.variance, ruby_formatter: ruby_formatters[:decimal], table_row: 2 },
    { label: 'Std. dev.', value: stats.standard_deviation, ruby_formatter: ruby_formatters[:decimal], table_row: 2 },
    { label: 'Rel. std. dev.', value: stats.relative_standard_deviation, ruby_formatter: ruby_formatters[:decimal], table_row: 2 },
    { label: 'Skewness', value: stats.skewness, ruby_formatter: ruby_formatters[:decimal], table_row: 2 },
    { label: 'Kurtosis', value: stats.kurtosis, ruby_formatter: ruby_formatters[:decimal], table_row: 2 },
    { label: '', value: '', ruby_formatter: ruby_formatters[:pass_through], table_row: 2 },
  ]
end
descriptive_statistics_table(values) click to toggle source

Returns an object that describes a statistics table.

# File lib/rails_data_explorer/data_type/quantitative.rb, line 108
def descriptive_statistics_table(values)
  desc_stats = descriptive_statistics(values)
  table = Utils::RdeTable.new([])
  [1,2].each do |table_row|
    table.rows << Utils::RdeTableRow.new(
      :tr,
      desc_stats.find_all { |e| table_row == e[:table_row] }.map { |stat|
        Utils::RdeTableCell.new(:th, stat[:label], ruby_formatter: Proc.new { |e| e }, css_class: 'rde-cell-label')
      },
      css_class: 'rde-column_header'
    )
    table.rows << Utils::RdeTableRow.new(
      :tr,
      desc_stats.find_all { |e| table_row == e[:table_row] }.map { |stat|
        Utils::RdeTableCell.new(:td, stat[:value], ruby_formatter: stat[:ruby_formatter], css_class: 'rde-cell-value')
      },
      css_class: 'rde-data_row'
    )
  end
  table
end