各グループ内で変数dplyr
の最小値を持つ行のみが返されるように、x
を使用してグループ化されたフィルターを作成します。
私の問題は、予想通り、最小値を持つ複数の最小値allの行が返されることです。しかし、私の場合、複数の最小値が存在する場合、最初の行のみが必要ですです。
以下に例を示します。
df <- data.frame(
A=c("A", "A", "A", "B", "B", "B", "C", "C", "C"),
x=c(1, 1, 2, 2, 3, 4, 5, 5, 5),
y=rnorm(9)
)
library(dplyr)
df.g <- group_by(df, A)
filter(df.g, x == min(x))
予想どおり、すべての最小値が返されます。
Source: local data frame [6 x 3]
Groups: A
A x y
1 A 1 -1.04584335
2 A 1 0.97949399
3 B 2 0.79600971
4 C 5 -0.08655151
5 C 5 0.16649962
6 C 5 -0.05948012
Ddplyを使用すると、この方法でタスクにアプローチできます。
library(plyr)
ddply(df, .(A), function(z) {
z[z$x == min(z$x), ][1, ]
})
...動作します:
A x y
1 A 1 -1.04584335
2 B 2 0.79600971
3 C 5 -0.08655151
Q:dplyrでこれにアプローチする方法はありますか?(速度の理由から)
完全を期すために:@hadleyと@Arunのコメントから導き出された最終的なdplyr
ソリューションを以下に示します。
library(dplyr)
df.g <- group_by(df, A)
filter(df.g, rank(x, ties.method="first")==1)
Dplyr> = 0.3では、which.min
と組み合わせてslice
関数を使用できます。これは、このタスクの私のお気に入りのアプローチです。
df %>% group_by(A) %>% slice(which.min(x))
#Source: local data frame [3 x 3]
#Groups: A
#
# A x y
#1 A 1 0.2979772
#2 B 2 -1.1265265
#3 C 5 -1.1952004
サンプルデータの場合、2つのfilter
を連続して使用することもできます。
group_by(df, A) %>%
filter(x == min(x)) %>%
filter(1:n() == 1)
価値があるものについては、data.table
解決策、興味があるかもしれない人へ:
# approach with setting keys
dt <- as.data.table(df)
setkey(dt, A,x)
dt[J(unique(A)), mult="first"]
# without using keys
dt <- as.data.table(df)
dt[dt[, .I[which.min(x)], by=A]$V1]
これは、row_number
とgroup_by
を組み合わせて使用することで実現できます。 row_number
は、値だけでなく、ベクトル内の相対的な順序でもランクを割り当てることにより、同順位を処理します。 x
の最小値を持つ各グループの最初の行を取得するには:
df.g <- group_by(df, A)
filter(df.g, row_number(x) == 1)
詳細については、dplyr ウィンドウ関数のビネット を参照してください。
私はそのシンプルさからsqldfが好きです。
sqldf("select A,min(X),y from 'df.g' group by A")
出力:
A min(X) y
1 A 1 -1.4836989
2 B 2 0.3755771
3 C 5 0.9284441
ここに来て、複数の方法でこれを行う方法を探しました。これにより、最後の10の結びつきを壊し、私は信じています
df.g %>%
top_n(-10,row_number(x))
別の方法:
set.seed(1)
x <- data.frame(a = rep(1:2, each = 10), b = rnorm(20))
x <- dplyr::arrange(x, a, b)
dplyr::filter(x, !duplicated(a))
結果:
a b
1 1 -0.8356286
2 2 -2.2146999
また、各グループの行を最大値で取得するように簡単に適合させることもできます。