2011-11-12 1 views
0

私は統計レポートを作成しています。私たちは大量のデータを扱っているので、私たちは断片を取得しています。例えば、DateTime/Dataオブジェクトを出力し、開始日から終了日までの月の間隔で追跡しています。統計データの欠損値を取得するにはどうすればよいですか?

データはそこにデータが入っている月だけを出します。例えば、2010年12月、2011年2月、2011年8月です。私はそれをどのように構築するのかを知る必要があります。 、2011年3月などがあります。

誰かが私に大量のオーバーヘッドなしにこれをどのように構築するかというアイデアを教えてもらえますか?最初にループを作成し、必要な間隔(分、月、年など)を取得してリストに入れ、DateTime/Dataオブジェクトをチェックして、0より大きい値があればチェックします。また、これはチャート上にポイントを作成するためのものです。

+0

あなたがデータを取得しているどこから?データベース?ウェブサービス?いくつかの他のデータソース? – PiRX

+0

データがストアドプロシージャからデータベースに送信されています。 – Darren

答えて

1

リンクリストにデータをロードして、欠落しているデータポイントを挿入します。

using System; 
using System.Collections.Generic; 

namespace Whatever 
{ 
    public struct DataPoint 
    { 
    private DateTime time; 
    private int value; 

    public DataPoint(DateTime time, int value) 
    { 
     this.time = time; 
     this.value = value; 
    } 

    public DateTime Time 
    { 
     get { return this.time; } 
    } 

    public int Value 
    { 
     get { return this.value; } 
    } 

    public override string ToString() 
    { 
     return string.Format("{0:D2}/{1}: {2}", this.time.Month, this.time.Year, this.value); 
    } 
    } 

    public static class Program 
    { 
    public static void Main() 
    { 
     // List of the datapoints, e.g. loaded from a database 
     var dataPoints = new List<DataPoint>(); 
     dataPoints.Add(new DataPoint(new DateTime(2010, 11, 1), 10)); 
     dataPoints.Add(new DataPoint(new DateTime(2011, 2, 1), 20)); 
     dataPoints.Add(new DataPoint(new DateTime(2011, 3, 1), 30)); 
     dataPoints.Add(new DataPoint(new DateTime(2011, 6, 1), 40)); 
     dataPoints.Add(new DataPoint(new DateTime(2011, 9, 1), 50)); 
     dataPoints.Add(new DataPoint(new DateTime(2011, 12, 1), 60)); 
     dataPoints.Add(new DataPoint(new DateTime(2012, 2, 1), 70)); 

     // Endpoints of the measurement interval 
     var begin = new DateTime(2010, 9, 1); 
     var end = new DateTime(2012, 4, 1); 

     // Check each month and insert missing datapoints 
     var time = begin; 
     var i = 0; 
     while (time <= end) 
     { 
     if (i < dataPoints.Count) 
     { 
      if (time < dataPoints[i].Time) 
      { 
      var dataPoint = new DataPoint(time, 0); 
      dataPoints.Insert(i, dataPoint); 
      } 
     } 
     else 
     { 
      var dataPoint = new DataPoint(time, 0); 
      dataPoints.Add(dataPoint); 
     } 
     ++i; 
     time = time.AddMonths(1); 
     } 

     // Print list 
     foreach (var dataPoint in dataPoints) 
     Console.WriteLine(dataPoint); 
    } 
    } 
} 

EDIT: だけ、これらのデータをプロットする必要がある場合は、不足しているデータポイントを挿入する必要はありません。私は単に既存の点の間を補間する、つまり、それらを接続するということです。既存の点を塗りつぶした円で表すと、これらの接続線上にある空の円で欠けている点を示すことができます(そのようなグラフコントロールは、補間によって与えられたプロット点にそれらを保存せずに書き込むことができます)。

+0

こんにちは、グラフは折れ線グラフで、ラベルは何ヶ月かですが、欠落しているのは、何もデータがないという月の0秒です。ありがとうございます – Darren

+0

PiRXのソリューションは、データベース側に欠けているデータポイントを挿入する方法を提供します。私のソリューションは、クライアント側に欠けているデータポイントを挿入します。グラフと補間についての私のコメントは、あなたがグラフコントロールの開発者である状況を指します。 – kol

+0

私は、大規模なデータセットであるため、あなたのソリューションはより良く機能します。また、間隔を数日に変更したいのであれば、それをどのように表しますか?測定値は秒、分、日、月、および年になります。もう一度あなたの助けをありがとうございます。 – Darren

1

可能であれば、このプロシージャのストアド・プロシージャおよび/またはSQLコールを変更し、部分結合(LEFT/RIGHT JOIN)およびCOALESCE/ISNULL関数を使用して不足しているデータを挿入することをお勧めします。このような

何か:

DECLARE @range AS TABLE (datePoint DATETIME); 
DECLARE @data AS TABLE (datePoint DATETIME, value INT); 

-- setup date range 
DECLARE @currentDatePoint AS DATETIME; 
SET @currentDatePoint = '01/01/2011' 
WHILE @currentDatePoint < '01/01/2012' 
BEGIN 
    INSERT INTO @range VALUES (@currentDatePoint); 
    SET @currentDatePoint = DATEADD(MONTH, 1, @currentDatePoint); 
END 

-- setup test data 
SET @currentDatePoint = '01/01/2011' 
WHILE @currentDatePoint < '01/01/2012' 
BEGIN 
    INSERT INTO @data VALUES (@currentDatePoint, DATEPART(MONTH, @currentDatePoint)); 
    SET @currentDatePoint = DATEADD(MONTH, 2, @currentDatePoint); 
END 
--end setup 

-- actual select 
SELECT 
    r.datePoint, 
    ISNULL(d.value, 0) 
FROM 
    @range r 
LEFT JOIN 
    @data d ON r.datePoint = d.datePoint 
関連する問題