web-dev-qa-db-ja.com

特定の順序のベクトルに従ってデータフレーム行を順序付けます

以下の短い例で実装したように、データフレームの行が「ターゲット」ベクトルに従って順序付けられるようにする簡単な方法はありますか?

df <- data.frame(name = letters[1:4], value = c(rep(TRUE, 2), rep(FALSE, 2)))

df
#   name value
# 1    a  TRUE
# 2    b  TRUE
# 3    c FALSE
# 4    d FALSE

target <- c("b", "c", "a", "d")

これはどういうわけか、仕事を成し遂げるには少し複雑すぎるようです。

idx <- sapply(target, function(x) {
    which(df$name == x)
})
df <- df[idx,]
rownames(df) <- NULL

df 
#   name value
# 1    b  TRUE
# 2    c FALSE
# 3    a  TRUE
# 4    d FALSE
130
Rappster

matchを試してください:

df <- data.frame(name=letters[1:4], value=c(rep(TRUE, 2), rep(FALSE, 2)))
target <- c("b", "c", "a", "d")
df[match(target, df$name),]

  name value
2    b  TRUE
3    c FALSE
1    a  TRUE
4    d FALSE

targetdf$nameとまったく同じ要素を含み、重複する値を含まない限り機能します。

?matchから:

match returns a vector of the positions of (first) matches of its first argument 
in its second.

したがって、matchは、targetの要素に一致する行番号を見つけ、dfをこの順序で返します。

194
Edward

この方法は少し異なり、以前の回答よりも柔軟性が少し高くなりました。順序付けられた要素にすることで、arrangeなどでうまく使用できます。 gdataパッケージのreorder.factorを使用しました。

df <- data.frame(name=letters[1:4], value=c(rep(TRUE, 2), rep(FALSE, 2)))
target <- c("b", "c", "a", "d")

require(gdata)
df$name <- reorder.factor(df$name, new.order=target)

次に、現在注文されているという事実を使用します。

require(dplyr)
df %>%
  arrange(name)
    name value
1    b  TRUE
2    c FALSE
3    a  TRUE
4    d FALSE

元の(アルファベット順)の順序に戻したい場合は、as.character()を使用して元の状態に戻します。

18
MattV

データを照合する必要があるときはいつでもdplyr***_joinを使用することを好みます。これの1つの可能な試み

left_join(data.frame(name=target),df,by="name")

***_joinの入力にはtblsまたはdata.frameが必要であることに注意してください

16
Lerong