1. ホーム
  2. r

[解決済み] グループごとの変数の最小値に対応する行を抽出する。

2023-02-08 16:22:32

質問

(1) データを1つの変数でグループ化したい ( State ) でグループ化し、 (2) 各グループ内で別の変数の最小値の行を見つける ( Employees )を見つけ、(3)その行全体を抽出する。

(1)と(2)は簡単な一発勝負で、(3)もそのはずなのですが、うまくいかない気がします。

ここにサンプルデータがあります。

> data
  State Company Employees
1    AK       A        82
2    AK       B       104
3    AK       C        37
4    AK       D        24
5    RI       E        19
6    RI       F       118
7    RI       G        88
8    RI       H        42

data <- structure(list(State = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 
        2L), .Label = c("AK", "RI"), class = "factor"), Company = structure(1:8, .Label = c("A", 
        "B", "C", "D", "E", "F", "G", "H"), class = "factor"), Employees = c(82L, 
        104L, 37L, 24L, 19L, 118L, 88L, 42L)), .Names = c("State", "Company", 
        "Employees"), class = "data.frame", row.names = c(NA, -8L))

計算する min をグループ別に計算するのは簡単です。 aggregate :

> aggregate(Employees ~ State, data, function(x) min(x))
  State Employees
1    AK        24
2    RI        19

...または data.table :

> library(data.table)
> DT <- data.table(data)
> DT[ , list(Employees = min(Employees)), by = State]
   State Employees
1:    AK        24
2:    RI        19

しかし、これらの行に対応する行全体を抽出するにはどうすればよいでしょうか。 min の値、つまり Company を含むのですか?

どのように解決するのですか?

少しエレガントです。

library(data.table)
DT[ , .SD[which.min(Employees)], by = State]

   State Company Employees
1:    AK       D        24
2:    RI       E        19


を使用するよりも若干エレガントではありません。 .SD を使用するよりも若干劣りますが、(多くのグループを持つデータでは)少し速くなります。

DT[DT[ , .I[which.min(Employees)], by = State]$V1]

また、単に式を置き換えて which.min(Employees)Employees == min(Employees) を使用すると、データセットに複数の同じ最小値があり、それらのすべてをサブセットしたい場合に便利です。

参照 data.tableを使用したグループによる最大値に対応する行のサブセット .