どのように並べ替えdataframe複数のカラム(s)
質問
たい並べ替えます。フレームを複数の列あります。例えば、データです。フレーム以下のように並列 z
(降順)によるカラム b
(昇順):
dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"),
levels = c("Low", "Med", "Hi"), ordered = TRUE),
x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
z = c(1, 1, 1, 2))
dd
b x y z
1 Hi A 8 1
2 Med D 3 1
3 Hi A 9 1
4 Low C 9 2
解決
あなたは order()
: - >関数は、直接アドオンするツール頼らずexample(order)
コードの先頭からのトリックの権利を使用しています。このシンプルな答えを見ます
R> dd[with(dd, order(-z, b)), ]
b x y z
4 Low C 9 2
2 Med D 3 1
1 Hi A 8 1
3 Hi A 9 1
のいくつかの2+年後に編集します。のそれはちょうど列インデックスでこれを行う方法を頼まれました。答えは単にorder()
関数に所望のソートカラム(複数可)を通過することである。
R> dd[order(-dd[,4], dd[,1]), ]
b x y z
4 Low C 9 2
2 Med D 3 1
1 Hi A 8 1
3 Hi A 9 1
R>
ではなく(簡単に/より直接アクセスするとwith()
)列の名前を使用するよります。
他のヒント
お客様の選択
order
からbase
arrange
からdplyr
setorder
やsetorderv
からdata.table
arrange
からplyr
sort
からtaRifx
orderBy
からdoBy
sortData
からDeducer
ほとんどの時間をお使いください dplyr
または data.table
ソリューション、限りない依存するのではなく、その場合利用 base::order
.
私は最近追加並べ替えができます。データです。フレームをCRANパッケージ、クラスと一致しているので、ここで説明されてい:ベストな方法を汎用的方法の整合性のための並べ替えができます。データです。フレーム?
そのためのデータです。フレームdd並べ替えができて
dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"),
levels = c("Low", "Med", "Hi"), ordered = TRUE),
x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
z = c(1, 1, 1, 2))
library(taRifx)
sort(dd, f= ~ -z + b )
の場合は、原著作者がこの機能は、ご連絡ください.シカゴ公共domaininessはこちら: http://chat.stackoverflow.com/transcript/message/1094290#1094290
にお使いいただけます arrange()
機能から plyr
としてのハドレー循環が指摘されている上記のスレッド:
library(plyr)
arrange(dd,desc(z),b)
ベンチマーク:ご注意積載さらに各パッケージの新しいRセッションから多くの紛争の絶えない領域でもある。特に負荷のdoByパッケージの原因 sort
戻すには以下のオブジェクトについては覆面からのx位置17)':b,x,y,z"、および荷重のDeducerパッケージで上書き sort.data.frame
からのケビン-ライトのtaRifxパッケージです。
#Load each time
dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"),
levels = c("Low", "Med", "Hi"), ordered = TRUE),
x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
z = c(1, 1, 1, 2))
library(microbenchmark)
# Reload R between benchmarks
microbenchmark(dd[with(dd, order(-z, b)), ] ,
dd[order(-dd$z, dd$b),],
times=1000
)
中央値時:
dd[with(dd, order(-z, b)), ]
778
dd[order(-dd$z, dd$b),]
788
library(taRifx)
microbenchmark(sort(dd, f= ~-z+b ),times=1000)
期間の中央値: 1,567
library(plyr)
microbenchmark(arrange(dd,desc(z),b),times=1000)
期間の中央値: 862
library(doBy)
microbenchmark(orderBy(~-z+b, data=dd),times=1000)
期間の中央値: 1,694
ご注意doByにも少しの時間への負荷のソフトウェアによるものです。
library(Deducer)
microbenchmark(sortData(dd,c("z","b"),increasing= c(FALSE,TRUE)),times=1000)
もできなDeducer負荷時のものです。ニーズの送料、代引手数料は無料です。
esort <- function(x, sortvar, ...) {
attach(x)
x <- x[with(x,order(sortvar,...)),]
return(x)
detach(x)
}
microbenchmark(esort(dd, -z, b),times=1000)
が表示されていない対応によりmicrobenchmarkにより付け/取り外し.
m <- microbenchmark(
arrange(dd,desc(z),b),
sort(dd, f= ~-z+b ),
dd[with(dd, order(-z, b)), ] ,
dd[order(-dd$z, dd$b),],
times=1000
)
uq <- function(x) { fivenum(x)[4]}
lq <- function(x) { fivenum(x)[2]}
y_min <- 0 # min(by(m$time,m$expr,lq))
y_max <- max(by(m$time,m$expr,uq)) * 1.05
p <- ggplot(m,aes(x=expr,y=time)) + coord_cartesian(ylim = c( y_min , y_max ))
p + stat_summary(fun.y=median,fun.ymin = lq, fun.ymax = uq, aes(fill=expr))
(ラインから下の四分位を四分位点の中央値)
これらの結果は、計量単純前速度、私を出さなければいけないことになるnodる arrange
の plyr
パッケージ.シンプルな構文なのでほとんどしていくスピーディーベースのRコマンドを巻き込みmachinations.一般的に輝かしいハドレー Wickhamます。私だけの追求であることがまとめられることにより、標準のR名称が別物になると呼ばれるよ sort(object)
, がかかったハドレートのカスタムにいかがでしょうにつきましては、質問リンクです。
ディルクの答えは素晴らしいです。また、インデックスdata.frame
sとdata.table
sのために使用される構文の重要な違いを強調します:
## The data.frame way
dd[with(dd, order(-z, b)), ]
## The data.table way: (7 fewer characters, but that's not the important bit)
dd[order(-z, b)]
の二つの呼び出しの間の差は小さいが、それは重要な結果をもたらすことができます。本番コードを記述および/またはあなたの研究では正確と懸念している場合は特に、それは、変数名の不必要な繰り返しを避けるのがベストです。 data.table
あなたがこれを行うことができます。
ここでは、変数名の繰り返しがトラブルにあなたを得る可能性があります方法の例です。
のはディルクの答えからコンテキストを変更し、これがオブジェクト名の多くがあり、彼らは長くて意味のある大きなプロジェクトの一部であるとしましょう。代わりにdd
のそれはquarterlyreport
と呼ばれています。それはなります:
quarterlyreport[with(quarterlyreport,order(-z,b)),]
[OK]を、罰金。それと間違って何もありません。次のあなたの上司は、レポートの最後の四半期の報告書を含めることが求められます。あなたは何とか様々な場所でオブジェクトlastquarterlyreport
を追加すると、あなたのコードを通過しますが、これで終わる(地球上でどのように?):
quarterlyreport[with(lastquarterlyreport,order(-z,b)),]
それはあなたが何を意味するのかではなく、あなたはそれが速く、それは同様のコードのページにたたずむいなかったので、あなたはそれを発見しませんでした。 Rは、それはあなたが何を意味するのかと考えているので、コードが倒れない(警告やエラーなし)しません。あなたのレポートはそれをスポット読み込ん誰でも願うだろう、多分そうではありません。あなたがプログラミング言語で作業する場合、多くは、このような状況ではおなじみの、すべてであってもよいです。それはあなたが言うよ「タイプミス」でした。私はあなたの上司に言うでしょう「タイプミス」を修正します。
data.table
に、我々はこのような小さな詳細を懸念しています。だから私たちは二度の変数名を入力して避けるために、単純な何かをやりました。非常にシンプルなもの。 i
は自動的に、すでにdd
の枠内で評価されます。あなたはまったくwith()
は必要ありません。
の代わりに
dd[with(dd, order(-z, b)), ]
それだけです。
dd[order(-z, b)]
、代わりの
quarterlyreport[with(lastquarterlyreport,order(-z,b)),]
それだけです。
quarterlyreport[order(-z,b)]
これは非常に小さな違いだが、それだけで一日あなたの首を救うかもしれません。この質問に別の答えを計量する場合、決定で、あなたの基準の一つとして、変数名の繰り返しを数えることを検討してください。いくつかの答えは、他の人が何を持っていない、かなりの数の繰り返しを持っています。
があり優れた答えの多くはここにありますが、 dplyr のは、私が迅速かつ容易に思い出すことができる唯一の構文を示します(ので、今)非常に頻繁に使用します。
library(dplyr)
# sort mtcars by mpg, ascending... use desc(mpg) for descending
arrange(mtcars, mpg)
# sort mtcars first by mpg, then by cyl, then by wt)
arrange(mtcars , mpg, cyl, wt)
OPの問題の場合:
arrange(dd, desc(z), b)
b x y z
1 Low C 9 2
2 Med D 3 1
3 Hi A 8 1
4 Hi A 9 1
Rパッケージ data.table
の両方を提供 高速 や メモリ効率的な ご注文の データです。テーブル と簡単な構文の一部をマットで浮き彫りにされたのは、なかなか良 彼の答え).が非常に多くの改善や新機能 setorder()
てきました。から v1.9.5+
, setorder()
することができます データです。フレーム.
を作成しまひとつのデータセットに十分に大きいとベンチマークを異なる方法からその他の回答およびそのリストの特徴 データです。テーブル.
データ:
require(plyr)
require(doBy)
require(data.table)
require(dplyr)
require(taRifx)
set.seed(45L)
dat = data.frame(b = as.factor(sample(c("Hi", "Med", "Low"), 1e8, TRUE)),
x = sample(c("A", "D", "C"), 1e8, TRUE),
y = sample(100, 1e8, TRUE),
z = sample(5, 1e8, TRUE),
stringsAsFactors = FALSE)
ベンチマーク:
のタイミング報告されているから走る system.time(...)
これらの機能を以下に示します。のタイミングは表示をはじめ、最も遅いる最速).
orderBy( ~ -z + b, data = dat) ## doBy
plyr::arrange(dat, desc(z), b) ## plyr
arrange(dat, desc(z), b) ## dplyr
sort(dat, f = ~ -z + b) ## taRifx
dat[with(dat, order(-z, b)), ] ## base R
# convert to data.table, by reference
setDT(dat)
dat[order(-z, b)] ## data.table, base R like syntax
setorder(dat, -z, b) ## data.table, using setorder()
## setorder() now also works with data.frames
# R-session memory usage (BEFORE) = ~2GB (size of 'dat')
# ------------------------------------------------------------
# Package function Time (s) Peak memory Memory used
# ------------------------------------------------------------
# doBy orderBy 409.7 6.7 GB 4.7 GB
# taRifx sort 400.8 6.7 GB 4.7 GB
# plyr arrange 318.8 5.6 GB 3.6 GB
# base R order 299.0 5.6 GB 3.6 GB
# dplyr arrange 62.7 4.2 GB 2.2 GB
# ------------------------------------------------------------
# data.table order 6.2 4.2 GB 2.2 GB
# data.table setorder 4.5 2.4 GB 0.4 GB
# ------------------------------------------------------------
data.table
'sDT[order(...)]
書式にした ~10x よりも早く最速の方法dplyr
が消費と同額の記憶としてdplyr
.data.table
'ssetorder()
た ~14x よりも早く最速の方法dplyr
)、 約0.4GBのメモリを.dat
現在の注文を必要として更新される参照)。
データです。テーブルの特徴
速度:
データです。テーブル'sご注文は非常に高速で実施 基数秩序.
の構文
DT[order(...)]
最適化されるため、内部的に使用 データです。テーブル'sの高速順序付けします。きを用いておこないようにしてもお馴染みのベースR構文がプロセスを加速さ(以下いたしました。
メモリ:
の時々の時代を必要としないの データです。フレーム または データです。テーブル 後順序を変更.しているのは、通常の割り当ての後に同じオブジェクトは、例えば:
DF <- DF[order(...)]
の課題であることが必要で少なくとも倍(2x)のメモリのオブジェクトです。する メモリ効率的な, データです。テーブル そのためにも提供機能
setorder()
.setorder()
reorders データです。テーブルby reference
(場所)を作らずに追加する。ついてアフターサービスについてのメモリと同じサイズのカラムです。
その他の特徴:
にも対応
integer
,logical
,numeric
,character
もbit64::integer64
種類です。ご注意
factor
,Date
,POSIXct
す。授業はすべてのinteger
/numeric
種類の下に追加で属性がサポートされます。ベースRを使用できません
-
文字のベクトルを並べ替える列は減っている。代わりにして使用-xtfrm(.)
.ただし、 データです。テーブル, しかし、例えば、
dat[order(-x)]
またはsetorder(dat, -x)
.
<のhref = "https://web.archive.org/web/20131108055534/http://rwiki.sciviews.org/doku.php?id=tips%3adata-frames%3asort" のrel =と」 noreferrer ">ケビン・ライトするによってこの(非常に有用)関数は、Rのウィキのヒントセクションに掲載、これは容易に達成される。
sort(dd,by = ~ -z + b)
# b x y z
# 4 Low C 9 2
# 2 Med D 3 1
# 1 Hi A 8 1
# 3 Hi A 9 1
か、パッケージdoByを使用することができます。
library(doBy)
dd <- orderBy(~-z+b, data=dd)
は、あなたがdata.frame
のA
を持っていて、降順x
という列を使用して、それをソートしたいとします。コールソートdata.frame
のnewdata
newdata <- A[order(-A$x),]
あなたは昇順をしたい場合は、何も"-"
を交換してください。あなたが好きなものを持つことができます。
newdata <- A[order(-A$x, A$y, -A$z),]
ここでx
とz
はdata.frame
のA
にいくつかの列です。これはdata.frame
降順、昇順A
とx
の降順でソートy
z
を意味します。
また、パッケージを使用してDeducer
library(Deducer)
dd<- sortData(dd,c("z","b"),increasing= c(FALSE,TRUE))
、sqldfはコッドが意図したとおりに、ORDER BYを処理します。
ディルクの答えは良いですが、あなたが持続するソートが必要な場合は、そのデータフレームの名前に戻し並べ替えを適用することをお勧めします。サンプルコードを使用して
dd <- dd[with(dd, order(-z, b)), ]
について order
以下の例を次に戸惑ったところでも長時間:
set.seed(1234)
ID = 1:10
Age = round(rnorm(10, 50, 1))
diag = c("Depression", "Bipolar")
Diagnosis = sample(diag, 10, replace=TRUE)
data = data.frame(ID, Age, Diagnosis)
databyAge = data[order(Age),]
databyAge
理由はただそれだけこの例では、作品が order
ある分別の vector Age
, ではなく、列の名前 Age
の data frame data
.
見を、同一のデータフレームを使用 read.table
イストが微妙に異なるカラム名となく利用"に記載のベクトル:
my.data <- read.table(text = '
id age diagnosis
1 49 Depression
2 50 Depression
3 51 Depression
4 48 Depression
5 50 Depression
6 51 Bipolar
7 49 Bipolar
8 49 Bipolar
9 49 Bipolar
10 49 Depression
', header = TRUE)
上記のライン構造 order
な作品がありませんのベクトルの名前 age
:
databyage = my.data[order(age),]
以下の線の作品が order
種類のカラム age
に my.data
.
databyage = my.data[order(my.data$age),]
これってすごいことだなと思いましたが掲載されどのように惑わったこの例でいます。このポストは適当でないと判断されたスレッドできます取り外してください。
編集:月13日2014年
以下に、一般の選別データフレーム毎にカラムを指定せずにカラム名になってしまいます以下のコード表示方法を示しう左から右または右へ左折。これらを組み合わせると、列は数値配列となる。っていないのにして文字列に追加されます。
この do.call
コードを前の古いポストを別のサイトが幅広く、困難を示すことが知られています。いかに移転している。現在のスレッドが最初のヒットをご注文の data.frame
に R
.うだと思った拡大版と原作 do.call
コードでも役にたつかもしれません。
set.seed(1234)
v1 <- c(0,0,0,0, 0,0,0,0, 1,1,1,1, 1,1,1,1)
v2 <- c(0,0,0,0, 1,1,1,1, 0,0,0,0, 1,1,1,1)
v3 <- c(0,0,1,1, 0,0,1,1, 0,0,1,1, 0,0,1,1)
v4 <- c(0,1,0,1, 0,1,0,1, 0,1,0,1, 0,1,0,1)
df.1 <- data.frame(v1, v2, v3, v4)
df.1
rdf.1 <- df.1[sample(nrow(df.1), nrow(df.1), replace = FALSE),]
rdf.1
order.rdf.1 <- rdf.1[do.call(order, as.list(rdf.1)),]
order.rdf.1
order.rdf.2 <- rdf.1[do.call(order, rev(as.list(rdf.1))),]
order.rdf.2
rdf.3 <- data.frame(rdf.1$v2, rdf.1$v4, rdf.1$v3, rdf.1$v1)
rdf.3
order.rdf.3 <- rdf.1[do.call(order, as.list(rdf.3)),]
order.rdf.3
プログラムでソートする方法についてはOPで追加されたコメントに対応してます:
dplyr
とdata.table
を使用して
library(dplyr)
library(data.table)
dplyr
ジャストarrange_
用標準評価版であるarrange
を使用します。
df1 <- tbl_df(iris)
#using strings or formula
arrange_(df1, c('Petal.Length', 'Petal.Width'))
arrange_(df1, ~Petal.Length, ~Petal.Width)
Source: local data frame [150 x 5]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
(dbl) (dbl) (dbl) (dbl) (fctr)
1 4.6 3.6 1.0 0.2 setosa
2 4.3 3.0 1.1 0.1 setosa
3 5.8 4.0 1.2 0.2 setosa
4 5.0 3.2 1.2 0.2 setosa
5 4.7 3.2 1.3 0.2 setosa
6 5.4 3.9 1.3 0.4 setosa
7 5.5 3.5 1.3 0.2 setosa
8 4.4 3.0 1.3 0.2 setosa
9 5.0 3.5 1.3 0.3 setosa
10 4.5 2.3 1.3 0.3 setosa
.. ... ... ... ... ...
#Or using a variable
sortBy <- c('Petal.Length', 'Petal.Width')
arrange_(df1, .dots = sortBy)
Source: local data frame [150 x 5]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
(dbl) (dbl) (dbl) (dbl) (fctr)
1 4.6 3.6 1.0 0.2 setosa
2 4.3 3.0 1.1 0.1 setosa
3 5.8 4.0 1.2 0.2 setosa
4 5.0 3.2 1.2 0.2 setosa
5 4.7 3.2 1.3 0.2 setosa
6 5.5 3.5 1.3 0.2 setosa
7 4.4 3.0 1.3 0.2 setosa
8 4.4 3.2 1.3 0.2 setosa
9 5.0 3.5 1.3 0.3 setosa
10 4.5 2.3 1.3 0.3 setosa
.. ... ... ... ... ...
#Doing the same operation except sorting Petal.Length in descending order
sortByDesc <- c('desc(Petal.Length)', 'Petal.Width')
arrange_(df1, .dots = sortByDesc)
ここで詳細: https://cran.r-project.org/web /packages/dplyr/vignettes/nse.htmlする
また中での発現を評価するための環境を捉えたような式を使用することをお勧めします。
data.table
dt1 <- data.table(iris) #not really required, as you can work directly on your data.frame
sortBy <- c('Petal.Length', 'Petal.Width')
sortType <- c(-1, 1)
setorderv(dt1, sortBy, sortType)
dt1
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1: 7.7 2.6 6.9 2.3 virginica
2: 7.7 2.8 6.7 2.0 virginica
3: 7.7 3.8 6.7 2.2 virginica
4: 7.6 3.0 6.6 2.1 virginica
5: 7.9 3.8 6.4 2.0 virginica
---
146: 5.4 3.9 1.3 0.4 setosa
147: 5.8 4.0 1.2 0.2 setosa
148: 5.0 3.2 1.2 0.2 setosa
149: 4.3 3.0 1.1 0.1 setosa
150: 4.6 3.6 1.0 0.2 setosa
アレンジ()dplyerで私の好きなオプションです。パイプ演算子を使用し、少なくともからの重要な最も重要な側面に行く
dd1 <- dd %>%
arrange(z) %>%
arrange(desc(x))
完全性のために:あなたはまたsortByCol()
パッケージからBBmisc
機能を使用することができます:
library(BBmisc)
sortByCol(dd, c("z", "b"), asc = c(FALSE, TRUE))
b x y z
4 Low C 9 2
2 Med D 3 1
1 Hi A 8 1
3 Hi A 9 1
性能比較:
library(microbenchmark)
microbenchmark(sortByCol(dd, c("z", "b"), asc = c(FALSE, TRUE)), times = 100000)
median 202.878
library(plyr)
microbenchmark(arrange(dd,desc(z),b),times=100000)
median 148.758
microbenchmark(dd[with(dd, order(-z, b)), ], times = 100000)
median 115.872
ただ、ずっと昔の機械的なカード選別機、最下位のキーは、次の最も重要な、などによる最初の並べ替えのようなノーライブラリに必要な、キーの任意の数と、昇順と降順のいずれかのキーの組み合わせで動作します。
dd <- dd[order(dd$b, decreasing = FALSE),]
今、私たちは、最も重要なキーを行う準備ができました。ソートは安定であり、最も重要なキーで任意の絆はすでに解決されています。
dd <- dd[order(dd$z, decreasing = TRUE),]
これは最速ではないかもしれないが、それは確かに簡単で信頼性のある
別の方法として、rgr
パッケージを使用します:
> library(rgr)
> gx.sort.df(dd, ~ -z+b)
b x y z
4 Low C 9 2
2 Med D 3 1
1 Hi A 8 1
3 Hi A 9 1
ただ、完全を期すために、多くのエラーへの道を切り開いて、列の順序が変更される可能性があるため、列番号でソートについて...確かに(それはしばしば望ましくないと主張することが可能と言われていないので、 )が、いくつかの特定の状況で(例えば、あなたが行って迅速な作業を必要とし、受注を変更する列のそのようなリスクが存在しない場合)には、多数の列を扱う場合は特に、行うには、最も賢明なことかもしれません。
その場合、do.call()
が救助に来ます:
ind <- do.call(what = "order", args = iris[,c(5,1,2,3)])
iris[ind, ]
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 14 4.3 3.0 1.1 0.1 setosa
## 9 4.4 2.9 1.4 0.2 setosa
## 39 4.4 3.0 1.3 0.2 setosa
## 43 4.4 3.2 1.3 0.2 setosa
## 42 4.5 2.3 1.3 0.3 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 48 4.6 3.2 1.4 0.2 setosa
## 7 4.6 3.4 1.4 0.3 setosa
## (...)