更新(最初に読む)
行インデックスのみに本当に関心がある場合は、おそらくいくつかの簡単な使用法split
とが役立つrange
でしょう。以下は、データセット内の行名に順番に番号が付けられていることを前提としていますが、おそらく適応も可能です。
irisFirstLast <- sapply(split(iris, iris$Species),
function(x) range(as.numeric(rownames(x))))
irisFirstLast ## Just the indices
# setosa versicolor virginica
# [1,] 1 51 101
# [2,] 50 100 150
iris[irisFirstLast[1, ], ] ## `1` would represent "first"
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 5.1 3.5 1.4 0.2 setosa
# 51 7.0 3.2 4.7 1.4 versicolor
# 101 6.3 3.3 6.0 2.5 virginica
iris[irisFirstLast, ] ## nothing would represent both first and last
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1 5.1 3.5 1.4 0.2 setosa
# 50 5.0 3.3 1.4 0.2 setosa
# 51 7.0 3.2 4.7 1.4 versicolor
# 100 5.7 2.8 4.1 1.3 versicolor
# 101 6.3 3.3 6.0 2.5 virginica
# 150 5.9 3.0 5.1 1.8 virginica
d <- datasets::Puromycin
dFirstLast <- sapply(split(d, d$state),
function(x) range(as.numeric(rownames(x))))
dFirstLast
# treated untreated
# [1,] 1 13
# [2,] 12 23
d[dFirstLast[2, ], ] ## `2` would represent `last`
# conc rate state
# 12 1.1 200 treated
# 23 1.1 160 untreated
名前付き行を操作する場合、一般的なアプローチは同じですが、範囲を自分で指定する必要があります。一般的なパターンは次のとおりです。
datasetFirstLast <- sapply(split(dataset, dataset$groupingvariable),
function(x) c(rownames(x)[1],
rownames(x)[length(rownames(x))]))
最初の答え(編集)
他の目的で行番号を必要とするのではなく、行を抽出することに関心がある場合は、を調べることもできますdata.table
。ここではいくつかの例を示します。
library(data.table)
DT <- data.table(iris, key="Species")
DT[J(unique(Species)), mult = "first"]
# Species Sepal.Length Sepal.Width Petal.Length Petal.Width
# 1: setosa 5.1 3.5 1.4 0.2
# 2: versicolor 7.0 3.2 4.7 1.4
# 3: virginica 6.3 3.3 6.0 2.5
DT[J(unique(Species)), mult = "last"]
# Species Sepal.Length Sepal.Width Petal.Length Petal.Width
# 1: setosa 5.0 3.3 1.4 0.2
# 2: versicolor 5.7 2.8 4.1 1.3
# 3: virginica 5.9 3.0 5.1 1.8
DT[, .SD[c(1,.N)], by=Species]
# Species Sepal.Length Sepal.Width Petal.Length Petal.Width
# 1: setosa 5.1 3.5 1.4 0.2
# 2: setosa 5.0 3.3 1.4 0.2
# 3: versicolor 7.0 3.2 4.7 1.4
# 4: versicolor 5.7 2.8 4.1 1.3
# 5: virginica 6.3 3.3 6.0 2.5
# 6: virginica 5.9 3.0 5.1 1.8
この最後のアプローチは非常に便利です。たとえば、各グループの最初の3行と最後の3行が必要な場合は、次を使用できます。DT[, .SD[c(1:3, (.N-2):.N)], by=Species]
(参考のために:.N
グループごとのケースの数を表します。
その他の便利なアプローチは次のとおりです。
DT[, tail(.SD, 2), by = Species] ## last two rows of each group
DT[, head(.SD, 4), by = Species] ## first four rows of each group