6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【C#】縦持ちのデータを集計して横持ちにする【LINQ】

Posted at

SQLと同じことができるのなら、LINQでデータ分析だってできるはず!

いわゆるピボットテーブルですが、集計後の形が思ったようにならない!
もっとLinqで完結してコントロールできるのでは?
以下、LinqPadで検証します。

データ構造

public class Employee
{
    public int Group { set; get; }
    public string Name { set; get; }
}

仮データ

var employees = new List<Employee>()
{
    new Employee {Group = 1, Name = "A" },
    new Employee {Group = 2, Name = "B" },
    new Employee {Group = 1, Name = "C" },
    new Employee {Group = 3, Name = "D" },
};

とりあえず Linq Pivot で検索して出てくる形

var q = employees
		.GroupBy(c => c.Group)
		.Select(g => new {
			Group = g.Key,
			i1 = g.Where(c => c.Group == 1).Count(),
			i2 = g.Where(c => c.Group == 2).Count(),
			i3 = g.Where(c => c.Group == 3).Count()
    });
    
q.Dump();

結果

img1.PNG

横持ちに。あとはMAXで一通りにすればいい。。。が、ぐぐっても出てこないので、試行錯誤しました。

GroupByするキーがない

ないなら追加すれば

var q = employees
		.GroupBy(c => c.Group)
		.Select(g => new {
			//Group = g.Key,
			i0 = 1,
			i1 = g.Where(c => c.Group == 1).Count(),
			i2 = g.Where(c => c.Group == 2).Count(),
			i3 = g.Where(c => c.Group == 3).Count()
		})
		.GroupBy(t => t.i0)
		.Select(s => new {
			m1 = s.Max(t => t.i1),
			m2 = s.Max(t => t.i2),
			m3 = s.Max(t => t.i3)
		});

q.Dump();

結果

img2.PNG

ダミーのキー(i0 = 1)をつくり、このキーで集計(GroupBy(t => t.i0))することで一通りに。

ちなみにデータが0件だったらどうなるのかを調べると

var employees = new List<Employee>()
{
    new Employee {Group = 1, Name = "A" },
    new Employee {Group = 1, Name = "B" },
    new Employee {Group = 1, Name = "C" },
    new Employee {Group = 3, Name = "D" },
};

(Group = 2 が0件)

結果

img3.PNG

0件として列が入ります。
Where句を差しておけば、出力の形式が崩れないことがわかりました。

以下全文

void Main()
{
    var employees = new List<Employee>()
    {
        new Employee {Group = 1, Name = "A" },
        new Employee {Group = 2, Name = "B" },
		new Employee {Group = 1, Name = "C" },
        new Employee {Group = 3, Name = "D" },
    };
	
	var q = employees
			.GroupBy(c => c.Group)
			.Select(g => new {
				//Group = g.Key,
				i0 = 1,
				i1 = g.Where(c => c.Group == 1).Count(),
				i2 = g.Where(c => c.Group == 2).Count(),
				i3 = g.Where(c => c.Group == 3).Count()
			})
			.GroupBy(t => t.i0)
			.Select(s => new {
				m1 = s.Max(t => t.i1),
				m2 = s.Max(t => t.i2),
				m3 = s.Max(t => t.i3)
			});

	q.Dump();
}

// Define other methods and classes here
public class Employee
{
    public int Group { set; get; }
    public string Name { set; get; }
}
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?