2016-04-12 11 views
3

Sagen, ich habe Daten in der folgenden Form:Rang Daten mit Subsets

> x <- data.frame(yr = c(1,1,1,1), wk = c(1,1,2,2), id = c("a","b","a","b"), dat1 = c(3,1,10,11), dat2 = c(3,1,10,11), dat3 = c(4,2,12,8)) 
> x 
yr wk id dat1 dat2 dat3 
01 01 a  3  3  4 
01 01 b  1  1  2 
01 02 a  10 10 12 
01 02 b  11 11 8 

ich einen Datenrahmen von rank über die Untergruppen yr und wk zurückkehren möchten. Gibt es eine Abkürzung dafür?

yr wk id dat1Rnk dat2Rnk dat3Rnk 
01 01 a  1   1  1 
01 01 b  2   2  2 
01 02 a  2   2  1 
01 02 b  1   1  2 

Antwort

2

Sie könnten etwas wie folgt mit data.table tun. Zuerst die Spalten definieren, dann die Spalten negieren (weil Sie in absteigender Reihenfolge Rang), dann weisen Sie die Spalten

library(data.table) 
cols <- paste0("dat", 1:3) 
setDT(x)[, (cols) := lapply(-.SD, frank), .SDcols = cols, by = .(yr, wk)] 
x 
# yr wk id dat1 dat2 dat3 
# 1: 1 1 a 1 1 1 
# 2: 1 1 b 2 2 2 
# 3: 1 2 a 2 2 1 
# 4: 1 2 b 1 1 2 

Oder mit dplyr

library(dplyr) 
x %>% 
    group_by(yr, wk) %>% 
    mutate_each(funs(rank(-.)), -id) 
# Source: local data frame [4 x 6] 
# Groups: yr, wk [2] 
# 
#  yr wk  id dat1 dat2 dat3 
# (dbl) (dbl) (fctr) (dbl) (dbl) (dbl) 
# 1  1  1  a  1  1  1 
# 2  1  1  b  2  2  2 
# 3  1  2  a  2  2  1 
# 4  1  2  b  1  1  2 
+0

Basisversion - 'x [cols] <- lapply (x [cols], Funktion (d) ave (-d, x [c ("yr", "wk")], FUN = Rang)) ' – thelatemail

+0

Das ist großartig, danke. Leider wurde mir klar, dass ich eine Schleife machen muss, weil sich einige der Rangordnungen (asc/desc) in den realen Daten von Jahr zu Jahr ändern. Ich kann eine Art Mass-Zeichen-Inversion machen, also kann ich das einfach benutzen. Das ist eine große Hilfe, danke! –

+0

@thelatemail das ist eine nette Alternative. Ich habe mir überlegt, wie man es einfach in der Basis machen kann. –