4 Ordered and unordered factors

A factor is a vector object used to specify a discrete classification (grouping) of the components of other vectors of the same length. R provides both ordered and unordered factors. While the “real” application of factors is with model formulae.

4.1 A specific example

Suppose, for example, we have a sample of 30 tax accountants from all the states and territories of Australia and their individiual state of origin is specified by a character vector of state mnemonics as

state <- c("tas", "sa", "qld","nsw","nsw","nt","wa","wa","qld","vic","nsw","vic","qld","qld","sa","tas","sa","nt","wa","vic","qld","nsw","nsw","wa","sa","act","nsw","vic","vic","act")
length(state)
[1] 30
state
 [1] "tas" "sa"  "qld" "nsw" "nsw" "nt"  "wa"  "wa"  "qld" "vic" "nsw" "vic" "qld" "qld"
[15] "sa"  "tas" "sa"  "nt"  "wa"  "vic" "qld" "nsw" "nsw" "wa"  "sa"  "act" "nsw" "vic"
[29] "vic" "act"

A factor is similarly created using the factor() function: The print() function handles factors slightly different from other objects:

statef <- factor(state)
statef
 [1] tas sa  qld nsw nsw nt  wa  wa  qld vic nsw vic qld qld sa  tas sa  nt  wa  vic qld
[22] nsw nsw wa  sa  act nsw vic vic act
Levels: act nsw nt qld sa tas vic wa

To find out the levels of a factor the function levels() can be used.

levels(statef)
[1] "act" "nsw" "nt"  "qld" "sa"  "tas" "vic" "wa" 

4.2 The function tapply and ragged arrays

To continue the previous example, suppose we have the incomes of the same tax accountants in another vector (in suitably largue units of money)

incomes <- c(60,49,40,61,64,60,59,54,62,69,70,42,56,61,61,61,58,51,48,65,49,49,41,48,52,46,59,46,58,43)
length(incomes)
[1] 30
incomes
 [1] 60 49 40 61 64 60 59 54 62 69 70 42 56 61 61 61 58 51 48 65 49 49 41 48 52 46 59 46
[29] 58 43

To calculate the sample mean income for each state we can now use the special function tapply():

incmeans <- tapply(incomes, statef, mean)
incmeans
     act      nsw       nt      qld       sa      tas      vic       wa 
44.50000 57.33333 55.50000 53.60000 55.00000 60.50000 56.00000 52.25000 

This gives a means vector with the components labeled by the levels.

The function tapply() is used to apply a function, here mean(), to each group of components of the first argument, here incomes, defined by the levels of the second component, here statef as if they were separate vector structures. The result is a structure of the same length as the levels attribute of the factor containing the results.

Suppose further we needed to calculate the standard errors of the state income means. To do this we need to write an R function to calculate the standard error for any given vector. Since there is a builtin function var() to calculate the sample variance, such a function is a very simple one linger, specified by the assignment:

stdError <- function(x) sqrt(var(x)/length(x))

The new function is displayed in the environment under Functions. To view the function click it or \(View(stdError)\). Using tapply() again, we can again evaluate incomes, indexing by state factor using our newly created standard error function to derive the standard errors of the respective states (factors).

incster <- tapply(incomes,statef,stdError)
incster
     act      nsw       nt      qld       sa      tas      vic       wa 
1.500000 4.310195 4.500000 4.106093 2.738613 0.500000 5.244044 2.657536 
facssizes <- tapply(incomes, statef, length)
facssizes
act nsw  nt qld  sa tas vic  wa 
  2   6   2   5   4   2   5   4 

The function tapply() can also be used to handle more complicated indexing of a vector by multiple categories. For example, we might wish to split the tax accountants by both state and sex. However in this simple instance (just one factor) what happens can be thought of as follows. The values in the vector are collected into groups corresponding to the distinct entries in the factor. The function is then applied to each of these groups individually. The value is a vector of function results, labeled by the levels attribute of the factor.

The combination of a vector and a labeling factor is an example of what is sometimes called a ragged array, since the subclass sizes are possibly irregular. When the subclass sizes are all the same the indexing may be done implicitly and much more efficiently, as shown in the next section.

4.3 Ordered factors

The levels of factors are stored in alphabetical order, or in the order they were specified to factor if they were specified explicitly.

Sometimes the levels will have a natural ordering that we want to record and want our statistical analysis to make use of. The ordered() function creates such ordered factors but is otherwise identical to factor. For most purposes the only difference between ordered and unordered factors is that the former are printed showing the ordering of the levels, but the contrasts generated for them in fitting linear models are different.

statef
 [1] tas sa  qld nsw nsw nt  wa  wa  qld vic nsw vic qld qld sa  tas sa  nt  wa  vic qld
[22] nsw nsw wa  sa  act nsw vic vic act
Levels: act nsw nt qld sa tas vic wa
levels(statef)
[1] "act" "nsw" "nt"  "qld" "sa"  "tas" "vic" "wa" 
ordered(statef)
 [1] tas sa  qld nsw nsw nt  wa  wa  qld vic nsw vic qld qld sa  tas sa  nt  wa  vic qld
[22] nsw nsw wa  sa  act nsw vic vic act
Levels: act < nsw < nt < qld < sa < tas < vic < wa
LS0tCnRpdGxlOiAiQ2hhcHRlciA0IC0gT3JkZXJlZCBhbmQgdW5vcmRlcmVkIGZhY3RvcnMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMgNCBPcmRlcmVkIGFuZCB1bm9yZGVyZWQgZmFjdG9ycwoKQSAqZmFjdG9yKiBpcyBhIHZlY3RvciBvYmplY3QgdXNlZCB0byBzcGVjaWZ5IGEgZGlzY3JldGUgY2xhc3NpZmljYXRpb24gKGdyb3VwaW5nKSBvZiB0aGUgY29tcG9uZW50cyBvZiBvdGhlciB2ZWN0b3JzIG9mIHRoZSBzYW1lIGxlbmd0aC4gUiBwcm92aWRlcyBib3RoICpvcmRlcmVkKiBhbmQgKnVub3JkZXJlZCogZmFjdG9ycy4gV2hpbGUgdGhlICJyZWFsIiBhcHBsaWNhdGlvbiBvZiBmYWN0b3JzIGlzIHdpdGggbW9kZWwgZm9ybXVsYWUuCgojIyA0LjEgQSBzcGVjaWZpYyBleGFtcGxlICMjCgpTdXBwb3NlLCBmb3IgZXhhbXBsZSwgd2UgaGF2ZSBhIHNhbXBsZSBvZiAzMCB0YXggYWNjb3VudGFudHMgZnJvbSBhbGwgdGhlIHN0YXRlcyBhbmQgdGVycml0b3JpZXMgb2YgQXVzdHJhbGlhIGFuZCB0aGVpciBpbmRpdmlkaXVhbCBzdGF0ZSBvZiBvcmlnaW4gaXMgc3BlY2lmaWVkIGJ5IGEgY2hhcmFjdGVyIHZlY3RvciBvZiBzdGF0ZSBtbmVtb25pY3MgYXMKCmBgYHtyfQpzdGF0ZSA8LSBjKCJ0YXMiLCAic2EiLCAicWxkIiwibnN3IiwibnN3IiwibnQiLCJ3YSIsIndhIiwicWxkIiwidmljIiwibnN3IiwidmljIiwicWxkIiwicWxkIiwic2EiLCJ0YXMiLCJzYSIsIm50Iiwid2EiLCJ2aWMiLCJxbGQiLCJuc3ciLCJuc3ciLCJ3YSIsInNhIiwiYWN0IiwibnN3IiwidmljIiwidmljIiwiYWN0IikKbGVuZ3RoKHN0YXRlKQpzdGF0ZQpgYGAKCkEgKmZhY3RvciogaXMgc2ltaWxhcmx5IGNyZWF0ZWQgdXNpbmcgdGhlIF9fZmFjdG9yKClfXyBmdW5jdGlvbjoKVGhlIF9fcHJpbnQoKV9fIGZ1bmN0aW9uIGhhbmRsZXMgZmFjdG9ycyBzbGlnaHRseSBkaWZmZXJlbnQgZnJvbSBvdGhlciBvYmplY3RzOgoKYGBge3J9CnN0YXRlZiA8LSBmYWN0b3Ioc3RhdGUpCnN0YXRlZgpgYGAKClRvIGZpbmQgb3V0IHRoZSBsZXZlbHMgb2YgYSBmYWN0b3IgdGhlIGZ1bmN0aW9uIF9fbGV2ZWxzKClfXyBjYW4gYmUgdXNlZC4KCmBgYHtyfQpsZXZlbHMoc3RhdGVmKQpgYGAKCiMjIDQuMiBUaGUgZnVuY3Rpb24gKnRhcHBseSogYW5kIHJhZ2dlZCBhcnJheXMgIyMKClRvIGNvbnRpbnVlIHRoZSBwcmV2aW91cyBleGFtcGxlLCBzdXBwb3NlIHdlIGhhdmUgdGhlIGluY29tZXMgb2YgdGhlIHNhbWUgdGF4IGFjY291bnRhbnRzIGluIGFub3RoZXIgdmVjdG9yIChpbiBzdWl0YWJseSBsYXJndWUgdW5pdHMgb2YgbW9uZXkpCgpgYGB7cn0KaW5jb21lcyA8LSBjKDYwLDQ5LDQwLDYxLDY0LDYwLDU5LDU0LDYyLDY5LDcwLDQyLDU2LDYxLDYxLDYxLDU4LDUxLDQ4LDY1LDQ5LDQ5LDQxLDQ4LDUyLDQ2LDU5LDQ2LDU4LDQzKQpsZW5ndGgoaW5jb21lcykKaW5jb21lcwpgYGAKClRvIGNhbGN1bGF0ZSB0aGUgc2FtcGxlIG1lYW4gaW5jb21lIGZvciBlYWNoIHN0YXRlIHdlIGNhbiBub3cgdXNlIHRoZSBzcGVjaWFsIGZ1bmN0aW9uIF9fdGFwcGx5KClfXzoKCmBgYHtyfQppbmNtZWFucyA8LSB0YXBwbHkoaW5jb21lcywgc3RhdGVmLCBtZWFuKQppbmNtZWFucwpgYGAKClRoaXMgZ2l2ZXMgYSBtZWFucyB2ZWN0b3Igd2l0aCB0aGUgY29tcG9uZW50cyBsYWJlbGVkIGJ5IHRoZSBsZXZlbHMuCgpUaGUgZnVuY3Rpb24gX190YXBwbHkoKV9fIGlzIHVzZWQgdG8gYXBwbHkgYSBmdW5jdGlvbiwgaGVyZSBfX21lYW4oKV9fLCB0byBlYWNoIGdyb3VwIG9mIGNvbXBvbmVudHMgb2YgdGhlIGZpcnN0IGFyZ3VtZW50LCBoZXJlIF9faW5jb21lc19fLCBkZWZpbmVkIGJ5IHRoZSBsZXZlbHMgb2YgdGhlIHNlY29uZCBjb21wb25lbnQsIGhlcmUgX19zdGF0ZWZfXyBhcyBpZiB0aGV5IHdlcmUgc2VwYXJhdGUgdmVjdG9yIHN0cnVjdHVyZXMuIFRoZSByZXN1bHQgaXMgYSBzdHJ1Y3R1cmUgb2YgdGhlIHNhbWUgbGVuZ3RoIGFzIHRoZSBsZXZlbHMgYXR0cmlidXRlIG9mIHRoZSBmYWN0b3IgY29udGFpbmluZyB0aGUgcmVzdWx0cy4KClN1cHBvc2UgZnVydGhlciB3ZSBuZWVkZWQgdG8gY2FsY3VsYXRlIHRoZSBzdGFuZGFyZCBlcnJvcnMgb2YgdGhlIHN0YXRlIGluY29tZSBtZWFucy4gVG8gZG8gdGhpcyB3ZSBuZWVkIHRvIHdyaXRlIGFuIFIgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBzdGFuZGFyZCBlcnJvciBmb3IgYW55IGdpdmVuIHZlY3Rvci4gU2luY2UgdGhlcmUgaXMgYSBidWlsdGluIGZ1bmN0aW9uIF9fdmFyKClfXyB0byBjYWxjdWxhdGUgdGhlIHNhbXBsZSB2YXJpYW5jZSwgc3VjaCBhIGZ1bmN0aW9uIGlzIGEgdmVyeSBzaW1wbGUgb25lIGxpbmdlciwgc3BlY2lmaWVkIGJ5IHRoZSBhc3NpZ25tZW50OgoKYGBge3J9CnN0ZEVycm9yIDwtIGZ1bmN0aW9uKHgpIHNxcnQodmFyKHgpL2xlbmd0aCh4KSkKYGBgCgpUaGUgbmV3IGZ1bmN0aW9uIGlzIGRpc3BsYXllZCBpbiB0aGUgZW52aXJvbm1lbnQgdW5kZXIgRnVuY3Rpb25zLiBUbyB2aWV3IHRoZSBmdW5jdGlvbiBjbGljayBpdCBvciAkVmlldyhzdGRFcnJvcikkLiBVc2luZyBfX3RhcHBseSgpX18gYWdhaW4sIHdlIGNhbiBhZ2FpbiBldmFsdWF0ZSBpbmNvbWVzLCBpbmRleGluZyBieSBzdGF0ZSBmYWN0b3IgdXNpbmcgb3VyIG5ld2x5IGNyZWF0ZWQgc3RhbmRhcmQgZXJyb3IgZnVuY3Rpb24gdG8gZGVyaXZlIHRoZSBzdGFuZGFyZCBlcnJvcnMgb2YgdGhlIHJlc3BlY3RpdmUgc3RhdGVzIChmYWN0b3JzKS4KCmBgYHtyfQppbmNzdGVyIDwtIHRhcHBseShpbmNvbWVzLHN0YXRlZixzdGRFcnJvcikKaW5jc3RlcgpgYGAKCmBgYHtyfQpmYWNzc2l6ZXMgPC0gdGFwcGx5KGluY29tZXMsIHN0YXRlZiwgbGVuZ3RoKQpmYWNzc2l6ZXMKYGBgCgo+IFRoZSBmdW5jdGlvbiBfX3RhcHBseSgpX18gY2FuIGFsc28gYmUgdXNlZCB0byBoYW5kbGUgbW9yZSBjb21wbGljYXRlZCBpbmRleGluZyBvZiBhIHZlY3RvciBieSBtdWx0aXBsZSBjYXRlZ29yaWVzLiBGb3IgZXhhbXBsZSwgd2UgbWlnaHQgd2lzaCB0byBzcGxpdCB0aGUgdGF4IGFjY291bnRhbnRzIGJ5IGJvdGggc3RhdGUgYW5kIHNleC4gSG93ZXZlciBpbiB0aGlzIHNpbXBsZSBpbnN0YW5jZSAoanVzdCBvbmUgZmFjdG9yKSB3aGF0IGhhcHBlbnMgY2FuIGJlIHRob3VnaHQgb2YgYXMgZm9sbG93cy4gVGhlIHZhbHVlcyBpbiB0aGUgdmVjdG9yIGFyZSBjb2xsZWN0ZWQgaW50byBncm91cHMgY29ycmVzcG9uZGluZyB0byB0aGUgZGlzdGluY3QgZW50cmllcyBpbiB0aGUgZmFjdG9yLiBUaGUgZnVuY3Rpb24gaXMgdGhlbiBhcHBsaWVkIHRvIGVhY2ggb2YgdGhlc2UgZ3JvdXBzIGluZGl2aWR1YWxseS4gVGhlIHZhbHVlIGlzIGEgdmVjdG9yIG9mIGZ1bmN0aW9uIHJlc3VsdHMsIGxhYmVsZWQgYnkgdGhlIF9fbGV2ZWxzX18gYXR0cmlidXRlIG9mIHRoZSBmYWN0b3IuCgpUaGUgY29tYmluYXRpb24gb2YgYSB2ZWN0b3IgYW5kIGEgbGFiZWxpbmcgZmFjdG9yIGlzIGFuIGV4YW1wbGUgb2Ygd2hhdCBpcyBzb21ldGltZXMgY2FsbGVkIGEgKnJhZ2dlZCBhcnJheSosIHNpbmNlIHRoZSBzdWJjbGFzcyBzaXplcyBhcmUgcG9zc2libHkgaXJyZWd1bGFyLiBXaGVuIHRoZSBzdWJjbGFzcyBzaXplcyBhcmUgYWxsIHRoZSBzYW1lIHRoZSBpbmRleGluZyBtYXkgYmUgZG9uZSBpbXBsaWNpdGx5IGFuZCBtdWNoIG1vcmUgZWZmaWNpZW50bHksIGFzIHNob3duIGluIHRoZSBuZXh0IHNlY3Rpb24uCgojIyA0LjMgT3JkZXJlZCBmYWN0b3JzICMjCgpUaGUgbGV2ZWxzIG9mIGZhY3RvcnMgYXJlIHN0b3JlZCBpbiBhbHBoYWJldGljYWwgb3JkZXIsIG9yIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgc3BlY2lmaWVkIHRvIF9fZmFjdG9yX18gaWYgdGhleSB3ZXJlIHNwZWNpZmllZCBleHBsaWNpdGx5LgoKU29tZXRpbWVzIHRoZSBsZXZlbHMgd2lsbCBoYXZlIGEgbmF0dXJhbCBvcmRlcmluZyB0aGF0IHdlIHdhbnQgdG8gcmVjb3JkIGFuZCB3YW50IG91ciBzdGF0aXN0aWNhbCBhbmFseXNpcyB0byBtYWtlIHVzZSBvZi4gVGhlIF9fb3JkZXJlZCgpX18gZnVuY3Rpb24gY3JlYXRlcyBzdWNoIG9yZGVyZWQgZmFjdG9ycyBidXQgaXMgb3RoZXJ3aXNlIGlkZW50aWNhbCB0byBmYWN0b3IuIEZvciBtb3N0IHB1cnBvc2VzIHRoZSBvbmx5IGRpZmZlcmVuY2UgYmV0d2VlbiBvcmRlcmVkIGFuZCB1bm9yZGVyZWQgZmFjdG9ycyBpcyB0aGF0IHRoZSBmb3JtZXIgYXJlIHByaW50ZWQgc2hvd2luZyB0aGUgb3JkZXJpbmcgb2YgdGhlIGxldmVscywgYnV0IHRoZSBjb250cmFzdHMgZ2VuZXJhdGVkIGZvciB0aGVtIGluIGZpdHRpbmcgbGluZWFyIG1vZGVscyBhcmUgZGlmZmVyZW50LiAKCmBgYHtyfQpzdGF0ZWYKbGV2ZWxzKHN0YXRlZikKb3JkZXJlZChzdGF0ZWYpCmBgYAoKCgoKCgo=