web-dev-qa-db-ja.com

データフレームを降順と昇順で並べ替える方法は?

次のようなデータフレームがあります。

    P1  P2  P3  T1  T2  T3  I1  I2
1   2   3   5   52  43  61  6   "b"
2   6   4   3   72  NA  59  1   "a"
3   1   5   6   55  48  60  6   "f"
4   2   4   4   65  64  58  2   "b"

I1で降順で並べ替え、I1で同じ値を持つ行をI2で昇順で並べ替え、行を1 3 4 2。ただし、order関数は、1つのdecreasing引数のみをとるように思われます。この引数は、すべての順序ベクトルに対して一度にTRUEまたはFALSEです。ソートを正しくするにはどうすればよいですか?

48
rumtscho

このコードを使用して、目的の出力を生成しました。これはあなたが望んでいたことですか?

rum <- read.table(textConnection("P1  P2  P3  T1  T2  T3  I1  I2
2   3   5   52  43  61  6   b
6   4   3   72  NA  59  1   a
1   5   6   55  48  60  6   f
2   4   4   65  64  58  2   b"), header = TRUE)
rum$I2 <- as.character(rum$I2)
rum[order(rum$I1, rev(rum$I2), decreasing = TRUE), ]

  P1 P2 P3 T1 T2 T3 I1 I2
1  2  3  5 52 43 61  6  b
3  1  5  6 55 48 60  6  f
4  2  4  4 65 64 58  2  b
2  6  4  3 72 NA 59  1  a
44
Roman Luštrik

私はrankを使用します:

rum <- read.table(textConnection("P1  P2  P3  T1  T2  T3  I1  I2
2   3   5   52  43  61  6   b
6   4   3   72  NA  59  1   a
1   5   6   55  48  60  6   f
2   4   4   65  64  58  2   b
1   5   6   55  48  60  6   c"), header = TRUE)

> rum[order(rum$I1, -rank(rum$I2), decreasing = TRUE), ]
  P1 P2 P3 T1 T2 T3 I1 I2
1  2  3  5 52 43 61  6  b
5  1  5  6 55 48 60  6  c
3  1  5  6 55 48 60  6  f
4  2  4  4 65 64 58  2  b
2  6  4  3 72 NA 59  1  a
28
Michele

RomanLuštrikの答えは間違っていると思う。たまたまこの入力で動作します。たとえば、非常によく似た入力(I2列に「c」を含む元の行3に似た追加行がある)での出力を考えてみましょう。

rum <- read.table(textConnection("P1  P2  P3  T1  T2  T3  I1  I2
2   3   5   52  43  61  6   b
6   4   3   72  NA  59  1   a
1   5   6   55  48  60  6   f
2   4   4   65  64  58  2   b
1   5   6   55  48  60  6   c"), header = TRUE)

rum$I2 <- as.character(rum$I2)
rum[order(rum$I1, rev(rum$I2), decreasing = TRUE), ]

  P1 P2 P3 T1 T2 T3 I1 I2
3  1  5  6 55 48 60  6  f
1  2  3  5 52 43 61  6  b
5  1  5  6 55 48 60  6  c
4  2  4  4 65 64 58  2  b
2  6  4  3 72 NA 59  1  a

これは望ましい結果ではありません。I2の最初の3つの値はf b c の代わりに b c f。これは、2次ソートが昇順のI2であるために予想されます。

I2の逆の順序を取得するには、大きな値を小さくし、逆の場合も同様です。数値の場合は-1で乗算しますが、文字の場合は少し注意が必要です。文字/文字列の一般的な解決策は、係数を調べ、レベルを逆にして(大きな値を小さくし、小さな値を大きくする)、係数を文字に戻すことです。

rum <- read.table(textConnection("P1  P2  P3  T1  T2  T3  I1  I2
2   3   5   52  43  61  6   b
6   4   3   72  NA  59  1   a
1   5   6   55  48  60  6   f
2   4   4   65  64  58  2   b
1   5   6   55  48  60  6   c"), header = TRUE)

f=factor(rum$I2)
levels(f) = rev(levels(f))
rum[order(rum$I1, as.character(f), decreasing = TRUE), ]

  P1 P2 P3 T1 T2 T3 I1 I2
1  2  3  5 52 43 61  6  b
5  1  5  6 55 48 60  6  c
3  1  5  6 55 48 60  6  f
4  2  4  4 65 64 58  2  b
2  6  4  3 72 NA 59  1  a
23
dudusan

Dfを2つのフィールドAとBを持つデータフレームとします

ケース1:フィールドAとBが数値の場合

df[order(df[,1],df[,2]),] - sorts fields A and B in ascending order
df[order(df[,1],-df[,2]),] - sorts fields A in ascending and B in descending order
Aに優先順位が与えられます。

ケース2:フィールドAまたはBが非数値の場合、ファクターまたは文字

この場合、Bが文字であり、逆の順序で並べ替えたい場合
df[order(df[,1],-as.numeric(as.factor(df[,2]))),] -> this sorts field A(numerical) in ascending and field B(character) in descending.
Aに優先順位が与えられます。

The idea is that you can apply -sign in order function ony on numericals. So for sorting character strings in descending order you have to coerce them to numericals.

4
ayush1723

デフォルトのソートは安定しているため、2回ソートします。最初はマイナーキー、次にメジャーキーの順です。

rum1 <- rum[order(rum$I2, decreasing = FALSE),]
rum2 <- rum1[order(rum1$I1, decreasing = TRUE),]
3
Rick

ランクのないシンプルなもの:

rum[order(rum$I1, -rum$I2, decreasing = TRUE), ]
2
Somnath Kadam
    library(dplyr)
    library(tidyr)
    #supposing you want to arrange column 'c' in descending order and 'd' in ascending order. name of data frame is df
    ## first doing descending
    df<-arrange(df,desc(c))
    ## then the ascending order of col 'd;
    df <-arrange(df,d)
2
Pranay Aryal
rum[order(rum$T1, -rum$T2 ), ]
1
Dmitri B

@dudusanの例では、I1の順序を逆にして、昇順で並べ替えることもできます。

> rum <- read.table(textConnection("P1  P2  P3  T1  T2  T3  I1  I2
+   2   3   5   52  43  61  6   b
+   6   4   3   72  NA  59  1   a
+   1   5   6   55  48  60  6   f
+   2   4   4   65  64  58  2   b
+   1   5   6   55  48  60  6   c"), header = TRUE)
> f=factor(rum$I1)   
> levels(f) <- sort(levels(f), decreasing = TRUE)
> rum[order(as.character(f), rum$I2), ]
  P1 P2 P3 T1 T2 T3 I1 I2
1  2  3  5 52 43 61  6  b
5  1  5  6 55 48 60  6  c
3  1  5  6 55 48 60  6  f
4  2  4  4 65 64 58  2  b
2  6  4  3 72 NA 59  1  a
> 

これは少し短く見えるようで、I2の順序を2回逆にしないでください。

0

正しい方法は次のとおりです。

rum[order(rum$T1, rum$T2, decreasing=c(T,F)), ]
0
dinh