title: Sort a factor based on value in one or more other columns
body: <p>I've looked through a number of posts about ordering factors, but haven't quite found a match for my problem. Unfortunately, my knowledge of R is still pretty rudimentary.</p>
  
  <p>I have a subset of an archaeological artifact catalog that I'm working with. I'm trying to cross-tabulate diagnostic historical artifact types and site testing locations. Easy enough with ddply or tapply.</p>
  
  <p>My problem is that I want to sort the artifact types (a factor) by their mean diagnostic date (number/year), and I keep getting them alphabetically. I know I need to make it an ordered factor, but can't figure out how to order it by the year value in the other column.</p>
  
  <pre><code>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
  ...
  </code></pre>
  
  <p>Which needs to be ordered:</p>
  
  <pre><code>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
  ...
  </code></pre>
  
  <p>The factor (IDENTIFY) needs to be ordered by the Date (MIDDATE). I thought I had it with</p>
  
  <pre><code>Catalog$IDENTIFY&lt;-factor(Catalog$IDENTIFY,levels=Catalog$MIDDATE,ordered=TRUE)
  </code></pre>
  
  <p>But get the warning:</p>
  
  <pre><code>In `levels&lt;-`(`*tmp*`, value = if (nl == nL) as.character(labels) 
  else paste0(labels,: duplicated levels will not be allowed 
  in factors anymore
  </code></pre>
  
  <p>IDENTIFY has ~130 factor levels and many have the same value for MIDDATE, so I need to order IDENTIFY by MIDDATE and another column TYPENAME.</p>
  
  <p>A little more detail:</p>
  
  <p>I have a dataframe <code>Catalog</code>, which breaks down (i.e. <code>str(Catalog)</code>) as:</p>
  
  <pre><code>&gt; 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"&lt;..: 2 1 2 2 4 5 4 3 ...
   $ MIDDATE : num  1860 1895 1845 1855 1760 ...
  </code></pre>
  
  <p>I need to make <code>IDENTIFY</code> an ordered factor, and reorder by <code>MIDDATE</code> -> <code>TYPENAME</code> -> alpha by <code>IDENTIFY</code>.</p>
  
  <p>What I'm not really getting is how to reorder by combined orders from multiple columns.</p>
  
  <p>I would just do this in the db, but a lot of what I'm running are weighted means within all sorts of cross-tabulations (e.g. weighted mean depths below ground surface for artifact classes by location)...</p>
  
  <p>...doable in Access, but messy, and unpredictable. Far easier and cleaner to manage in R, but I'd rather not to have to manually re-sort the resulting tables.</p>
  
  <p>What I'm trying to produce is a number of things along these lines:</p>
  
  <pre><code>&gt;xtab.Catalog&lt;-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   
  ...
  </code></pre>
  
  <p>...but I need them to sort in the logical (i.e. chronological/type) order instead of alphabetical.</p>