web-dev-qa-db-ja.com

1つ以上の他の列の値に基づいて因子を並べ替える

順序付け要素に関する多くの投稿を調べてきましたが、私の問題に一致するものは見つかりませんでした。残念ながら、Rに関する私の知識はまだかなり初歩的なものです。

作業中の考古学的なアーティファクトカタログのサブセットがあります。診断の歴史的成果物の種類とサイトのテスト場所をクロス集計しようとしています。 ddplyまたはtapplyで十分簡単。

私の問題は、アーティファクトタイプ(要因)を平均診断日(数/年)でソートしたいということであり、アルファベット順に取得し続けています。私はそれを順序付けられた要素にする必要があることを知っていますが、他の列の年の値でそれを順序付ける方法を理解できません。

_IDENTIFY                                      MIDDATE
engine-turned fine red stoneware              1769
white salt-glazed stoneware, scratch blue     1760
wrought nail, 'L' head                        1760
yellow lead-glazed buff earthenware           1732
...
_

注文する必要があります:

_IDENTIFY                                      MIDDATE
yellow lead-glazed buff earthenware           1732
white salt-glazed stoneware, scratch blue     1760
wrought nail, 'L' head                        1760
engine-turned fine red stoneware              1769
...
_

ファクター(IDENTIFY)は、日付(MIDDATE)で並べ替える必要があります。と思った

_Catalog$IDENTIFY<-factor(Catalog$IDENTIFY,levels=Catalog$MIDDATE,ordered=TRUE)
_

ただし、警告が表示されます。

_In `levels<-`(`*tmp*`, value = if (nl == nL) as.character(labels) 
else paste0(labels,: duplicated levels will not be allowed 
in factors anymore
_

IDENTIFYには〜130の因子レベルがあり、多くはMIDDATEの値が同じであるため、MIDDATEおよび別の列TYPENAMEでIDENTIFYを注文する必要があります。

もう少し詳細:

私はデータフレームCatalogを持っています。これは以下のように分類されます(つまりstr(Catalog)):

_> str(Catalog)
'data.frame':   2211 obs. of  15 variables:
 $ TRENCH  : Factor w/ 7 levels "DRT 1","DRT 2",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ U_TYPE  : Factor w/ 3 levels "EU","INC","STP": 1 1 1 1 1 1 1 1 1 1 ...
 $ U_LBL   : Factor w/ 165 levels "001","005","007",..: 72 72 72 72 72 72 ...
 $ L_STRAT : Factor w/ 217 levels "#2-7/25","[3]",..: 4 4 4 4 4 4 89 89 89 89 ...
 $ START   : num  0 0 0 0 0 0 39.4 39.4 39.4 39.4 ...
 $ END     : num  39.4 39.4 39.4 39.4 39.4 39.4 43.2 43.2 43.2 43.2 ...
 $ Qty     : int  1 1 3 5 1 1 6 8 1 1 ...
 $ MATNAME : Factor w/ 6 levels "Ceramics","Chipped Stone",..: 1 1 1 5 5 6 ...
 $ TYPENAME: Factor w/ 9 levels "Architectural Hardware",..: 9 9 9 1 1 3 9 ...
 $ CATNAME : Factor w/ 32 levels "Biface","Bottle Glass",..: 24 29 29 6 24 ...
 $ IDENTIFY: Factor w/ 112 levels "amethyst bottle glass",..: 17 91 96 71 103 ...
 $ BEGDATE : int  1820 1820 1830 1835 1700 NA 1670 1762 1800 1720 ...
 $ ENDDATE : int  1900 1970 1860 1875 1820 NA 1795 1820 1820 1780 ...
 $ OCC_LBL : Ord.factor w/ 5 levels "Late 19th Century"<..: 2 1 2 2 4 5 4 3 ...
 $ MIDDATE : num  1860 1895 1845 1855 1760 ...
_

IDENTIFYを順序付き因子にし、MIDDATE-> TYPENAME-> IDENTIFYでアルファを並べ替える必要があります。

私が本当に得ていないのは、複数の列からの注文を組み合わせて並べ替える方法です。

私はdbでこれを行うだけですが、実行しているものの多くは、あらゆる種類のクロス集計内の加重平均です(たとえば、場所ごとのアーティファクトクラスの地面の下の加重平均深さ)...

... Accessで実行できますが、面倒で予測不能です。 Rで管理する方がはるかに簡単でクリーンですが、結果のテーブルを手動で再ソートする必要はありません。

私が作成しようとしているのは、これらの線に沿った多くのことです:

_>xtab.Catalog<-tapply(Catalog$Qty,list(Catalog$IDENTIFY,Catalog$TRENCH),sum)

IDENTIFY                        DRT1    DRT2    DRT3    DRT4    DRT5    DRT6
Staffordshire stoneware         4       NA      NA      NA      NA      NA  
undecorated delftware           6       4       NA      NA      NA      NA  
unidentified wrought nail       15      9       3       1       3       NA  
white salt-glazed stoneware     6       1       1       NA      2       1   
white salt-glazed scratch blue  1       NA      NA      NA      NA      NA  
white stoneware, slip-dipped    NA      NA      NA      NA      NA      NA  
wrought nail, 'L' head          2       NA      NA      NA      NA      NA  
wrought nail, 'rose' head       62      21      4       NA      1       1   
wrought nail, 'T' head          2       NA      1       NA      NA      1   
yellow lead-glazed              12      NA      NA      NA      1       3   
...
_

...しかし、アルファベット順ではなく、論理的な(つまり、時系列/タイプ)順序で並べ替える必要があります。

30
Scard

再現可能なサンプルとソリューションを次に示します。

set.seed(0)
a = sample(1:20,replace=F)
b = sample(1:20,replace=F)
f = as.factor(letters[1:20])

> a
 [1] 18  6  7 10 15  4 13 14  8 20  1  2  9  5  3 16 12 19 11 17
> b
 [1] 16 18  4 12  3  5  6  1 15 10 19 17  9 11  2  8 20  7 13 14
> f
 [1] a b c d e f g h i j k l m n o p q r s t
Levels: a b c d e f g h i j k l m n o p q r s t

次に、新しい要素について:

fn = factor(f, levels=unique(f[order(a,b,f)]), ordered=TRUE)

> fn
 [1] a b c d e f g h i j k l m n o p q r s t
20 Levels: k < l < o < f < n < b < c < i < m < d < s < q < g < h < e < ... < j

「a」、次の「b」、最後に「f」自体でソートされます(この例では、「a」には繰り返し値がありません)。

40

次のdplyrベースのアプローチ(h/t daattali )をお勧めします。これは、必要な数の列に拡張できます。

library(dplyr)
Catalog <- Catalog %>%
  arrange(MIDDATE, TYPENAME) %>%               # sort your dataframe
  mutate(IDENTIFY = factor(IDENTIFY, unique(IDENTIFY))) # reset your factor-column based on that order
23
zach