【C#】縦持ちのデータを集計して横持ちにする【LINQ】
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();
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();
結果
横持ちに。あとは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();
結果
ダミーのキー(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件)
結果
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; }
}
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; }
}
Author And Source
この問題について(【C#】縦持ちのデータを集計して横持ちにする【LINQ】), 我々は、より多くの情報をここで見つけました https://qiita.com/TakeshiFukasawa/items/bcaca2998f9f81d4904b著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .