2012-05-25 9 views
17

Przeanalizowałem wiele postów dotyczących czynników zamówienia, ale nie znalazłem żadnego rozwiązania dla mojego problemu. Niestety moja wiedza na temat R jest wciąż dość szczątkowa.R - Zamów współczynnik w oparciu o wartość w jednej lub kilku innych kolumnach

Posiadam podzbiór katalogu artefaktów archeologicznych, nad którym pracuję. Próbuję zestawić krzyżowo diagnostyczne typy historycznych artefaktów i lokalizacje testowania witryn. Wystarczająco łatwe z ddply lub tapply.

Mój problem polega na tym, że chcę posortować typy artefaktów (czynnik) według ich średniej daty diagnostycznej (liczba/rok) i nadal otrzymuję je alfabetycznie. Wiem, że muszę sprawić, by był to uporządkowany czynnik, ale nie mogę wymyślić, jak zamówić go przez wartość roku w drugiej kolumnie.

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 
... 

który musi być zamawiane:

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 
... 

Współczynnik (OKREŚLIĆ) musi być uporządkowane według daty (MIDDATE). Myślałem, że to z

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

ale dostać ostrzeżenie:

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

OKREŚLIĆ ma ~ 130 poziomów czynnika a wiele z nich ma taką samą wartość dla MIDDATE, więc muszę zamówić OKREŚLIĆ przez MIDDATE i innym kolumna TYPENAME.

Trochę więcej szczegółów:

Mam dataframe Catalog, który rozkłada (tj str(Catalog)) jako:

> 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 ... 

muszę dokonać IDENTIFY uporządkowaną czynnik, a kolejność przez MIDDATE ->TYPENAME -> alfa przez IDENTIFY.

To, czego tak naprawdę nie rozumiem, to jak zmienić kolejność za pomocą złożonych zamówień z wielu kolumn.

Po prostu robiłbym to w db, ale wiele z tego, co robię, jest ważonych oznacza wszystkie rodzaje tabel krzyżowych (np. Ważone średnie głębokości poniżej powierzchni ziemi dla klas artefaktów według lokalizacji) ...

... wykonalne w programie Access, ale niechlujne i nieprzewidywalne. Znacznie łatwiejsze i bardziej przejrzyste zarządzanie w R, ale wolałbym nie ręcznie ręcznie sortować wynikowych tabel.

Co staram się produkować szereg rzeczy wzdłuż tych linii:

>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 
... 

... ale trzeba je uporządkować w logiczną (tj chronologiczny/typ) kolejność zamiast alfabetycznej.

Dzięki.

Zwycięskie rozwiązanie okazało się być:

Catalog$IDENTIFY = factor(Catalog$IDENTIFY, levels = 
+ Catalog$IDENTIFY[order(Catalog$MIDDATE, Catalog$MATNAME, 
+ Catalog$TYPENAME, Catalog$CATNAME, Catalog$IDENTIFY)], ordered=TRUE) 

Catalog$IDENTIFY <- factor(Catalog$IDENTIFY[,drop=TRUE]) 

str(Catalog$IDENTIFY) 

Ord.factor w/ 112 levels "brown-dotted yellow lead-glazed buff earthenware"<..: 63 85 48 59 17 112 4 24 36 8 ... 
+0

Zapraszamy do obejrzenia funkcji 'zamówić urządzenia()' w statystykach pakiet (tj. podstawa R). – Andrie

+0

Wypróbowałem 'reorder (katalog $ IDENTIFY, katalog $ MIDDATE)' ale otrzymałem takie samo ostrzeżenie o duplikatach poziomów i IDENTIFY wszystkie zmienione na 'NA's ... – Scard

+1

Ciężko ci pomóc bez powtarzalnego kodu. Czy możesz spróbować zrobić powtarzalny przykład i będę musiał rzucić okiem? – Andrie

Odpowiedz

28

Oto powtarzalne próbki z roztworem:

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 

teraz na nowy czynnik:

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 

sortowane po " sam ", następny" b "i wreszcie" f "(chociaż w tym przykładzie" a "nie ma powtarzających się wartości).

+0

Dziękuję. Dam to spróbować i zobacz, jak to działa. Podejrzewam, że będę musiał stworzyć oddzielny uporządkowany wektor czynnikowy z MIDDATE, ale wtedy kombinacje pól powinny zapobiec powieleniu problemu (te trzy powinny stworzyć unikalną pozycję). – Scard

+0

To się udało. Dziękuję Ci. – Scard

+1

Jeśli ktoś odpowiedział na twoje pytanie, proponuję użyć znaku zaznaczenia (kolor zielony), aby to zaznaczyć. Jest to uprzejmy i bardzo pomocne dla przyszłych poszukiwaczy. –

12

polecam następujące podejścia dplyr oparte (h/t daattali), który może zostać przedłużony do jak największej liczby kolumn, jak chcesz:

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

Daj mi następujący błąd: 'Błąd na' poziomach <-' ('* tmp *', wartość = jeśli (nl == nL) jako.charakter (etykiety) else wklej0 (etykiety,: poziom czynnika [2] to duplikowane', zdecydowanie mam powtarzane wartości zarówno w 'IDENTIFY' i' TYPENAME' ... Czy ta sztuczka działa tylko na kolumnach o unikalnej wartości? –

+1

wymyśliła to: ponieważ 'IDENTIFY' ma zduplikowane wartości, potrzebuje' unikalnego' na poziomie definicja –

Powiązane problemy