私はこのようなデータフレームを持っています:
n = c(2, 2, 3, 3, 4, 4)
n <- as.factor(n)
s = c("a", "b", "c", "d", "e", "f")
df = data.frame(n, s)
df
n s
1 2 a
2 2 b
3 3 c
4 3 d
5 4 e
6 4 f
そして、因子の各レベルの最初の要素にアクセスしたいと思います(この例では、a, c, e
を含むベクトルがあります)。
1つのレベルの最初の要素に到達することが可能です。
df$s[df$n == 2][1]
ただし、すべてのレベルで機能するわけではありません。
df$s[df$n == levels(n)]
[1] a f
どうしますか?
さらに、データフレームを変更して、発生するたびに各レベルの最初の要素がどれであるかを確認したいと思います。私の例では、新しい列は次のようになります。
n s rep firstelement
1 2 a a a
2 2 b c a
3 3 c e c
4 3 d a c
5 4 e c e
6 4 f e e
関数ave
は、次の場合に役立ちます。
df$firstelement = ave(df$s, df$n, FUN = function(x) x[1])
df
n s firstelement
1 2 a a
2 2 b a
3 3 c c
4 3 d c
5 4 e e
6 4 f e
編集。私の答えの最初の部分は、元の質問、つまりbefore "そしてさらに進むために」(これは編集でOPによって追加されました)。
別の可能性として、duplicated
を使用します。 _?duplicated
_から: "duplicated()
は、ベクトルまたはデータフレームのどの要素が、より小さな添え字を持つ要素の複製であるかを判別します。"
ここでは、論理否定(NOT)である_!
_を使用して、「n」の重複要素not、つまり各レベルの最初の要素を選択します。 'n'の。
_df[!duplicated(df$n), ]
# n s
# 1 2 a
# 3 3 c
# 5 4 e
_
更新これまで「さらに進む」編集は表示されませんでした。私の最初の提案は、@ thelatemailと@sparrowによってすでに提案されているように、間違いなくave
を使用することです。しかし、Rツールボックスを掘り下げて別の方法を示すために、ここにdplyr
の方法があります。
データをn
でグループ化し、mutate
関数を使用して、値「sの最初の要素」(_s[1]
_)を持つ新しい変数「first」を作成します。
_library(dplyr)
df %.%
group_by(n) %.%
mutate(
first = s[1])
# n s first
# 1 2 a a
# 2 2 b a
# 3 3 c c
# 4 3 d c
# 5 4 e e
# 6 4 f e
_
または、dplyr
便利な関数を使用して、_[1]
_の代わりにfirst
を使用します。
_df %.%
group_by(n) %.%
mutate(
first = first(s))
_
元の質問に対するdplyr
の解決策は、summarise
を使用することです。
_df %.%
group_by(n) %.%
summarise(
first = first(s))
# n first
# 1 2 a
# 2 3 c
# 3 4 e
_
match
を使用したアプローチは次のとおりです。
df$s[match(levels(n), df$n)]
編集:多分これは少し混乱しているように見えます...
最初の要素をリストする列を取得するには、match
を2回使用できます(ただし、x
とtable
の引数を入れ替えます)。
df$firstelement <- df$s[match(levels(n), df$n)[match(df$n, levels(n))]]
df$firstelement
# [1] a a c c e e
# Levels: a b c d e f
これを詳しく見てみましょう:
## this returns the first matching elements
match(levels(n), df$n)
# [1] 1 3 5
## when we swap the x and table argument in match we get the level index
## for each df$n (the duplicated indices are important)
match(df$n, levels(n))
# [1] 1 1 2 2 3 3
## results in
c(1, 3, 5)[c(1, 1, 2, 2, 3, 3)]
# [1] 1 1 3 3 5 5
df$s[c(1, 1, 3, 3, 5, 5)]
# [1] a a c c e e
# Levels: a b c d e f
この場合、私はplyrパッケージを好みます。これにより、データをさらに自由に操作できます。
library(plyr)
ddply(df,.(n),function(subdf){return(subdf[1,])})
n s
1 2 a
2 3 c
3 4 e
Data.tableを使用することもできます
library(data.table)
dt = as.data.table(df)
dt[, list(firstelement = s[1]), by=n]
それはあなたを得るでしょう:
n firstelement
1: 2 a
2: 3 c
3: 4 e
by=n
ビットはすべてをn
の各値でグループ化するため、s[1]
はこれらの各グループの最初の要素を取得します。
これを追加の列として取得するには、次のようにします。
dt[, newcol := s[1], by=n]
dt
# n s newcol
#1: 2 a a
#2: 2 b a
#3: 3 c c
#4: 3 d c
#5: 4 e e
#6: 4 f e
したがって、これは各グループの最初の行からs
の値を取得し、それを新しい列に割り当てるだけです。
df$s[sapply(levels(n), function(particular.level) { which(df$n == particular.level)[1]})]
あなたの問題は、2つのベクトルを比較していることだと思います。df$ nはベクトルで、levels(n)はベクトルです。 vector == df $ nはlevels(n)の倍数であるため、vectorはたまたま機能します。
回答ストリームにこのクラシックがまだ表示されていないことに驚いています。
> do.call(rbind, lapply(split(df, df$n), function(x) x[1,]))
## n s
## 2 2 a
## 3 3 c
## 4 4 e