2013-08-09 3 views
2

Скажем, у меня есть следующий кадр данных:Рейтинг переменных с условиями

df <- data.frame(store  = LETTERS[1:8], 
       sales  = c( 9, 128, 54, 66, 23, 132, 89, 70), 
       successRate = c(.80, .25, .54, .92, .85, .35, .54, .46)) 

Я хочу, чтобы ранжировать магазины в соответствии с successRate, со связями, идущих в магазин с большим количеством продаж, поэтому сначала я сделать это (только сделать визуализацию проще):

df <- df[order(-df$successRate, -df$sales), ] 

для того, чтобы действительно создать переменную ранжирования, я следующее:

df$rank <- ave(df$successRate, FUN = function(x) rank(-x, ties.method='first')) 

Так df выглядит следующим образом:

store sales successRate rank 
4  D 66  0.92 1 
5  E 23  0.85 2 
1  A  9  0.80 3 
7  G 89  0.54 4 
3  C 54  0.54 5 
8  H 70  0.46 6 
6  F 132  0.35 7 
2  B 128  0.25 8 

Проблема заключается в том, я не хочу, небольшие магазины, чтобы быть частью рейтинга. В частности, Я хочу, чтобы магазины с менее чем 50 продажами не оценивались. Так вот, как я определяю df$rank вместо:

df$rank <- ifelse(df$sales < 50, NA, 
        ave(df$successRate, FUN = function(x) rank(-x, ties.method='first'))) 

Проблема заключается в том, что даже если это правильно удаляет магазины Е и А, это не переназначать рейтинга они занимали. df будет выглядеть так:

store sales successRate rank 
4  D 66  0.92 1 
5  E 23  0.85 NA 
1  A  9  0.80 NA 
7  G 89  0.54 4 
3  C 54  0.54 5 
8  H 70  0.46 6 
6  F 132  0.35 7 
2  B 128  0.25 8 

Я экспериментировал с условиями внутри и снаружи ave(), но я can'r получить R, чтобы делать то, что я хочу! Как я могу получить его для ранжирования таких магазинов?

store sales successRate rank 
4  D 66  0.92 1 
5  E 23  0.85 NA 
1  A  9  0.80 NA 
7  G 89  0.54 2 
3  C 54  0.54 3 
8  H 70  0.46 4 
6  F 132  0.35 5 
2  B 128  0.25 6 

ответ

4

Супер легко сделать с data.table:

library(data.table) 
dt = data.table(df) 

# do the ordering you like (note, could also use setkey to do this faster) 
dt = dt[order(-successRate, -sales)] 

dt[sales >= 50, rank := .I] 
dt 
# store sales successRate rank 
#1:  D 66  0.92 1 
#2:  E 23  0.85 NA 
#3:  A  9  0.80 NA 
#4:  G 89  0.54 2 
#5:  C 54  0.54 3 
#6:  H 70  0.46 4 
#7:  F 132  0.35 5 
#8:  B 128  0.25 6 

Если вы должны сделать это в data.frame, то после выбора порядка, запустите:

df$rank <- NA 
df$rank[df$sales >= 50] <- seq_len(sum(df$sales >= 50)) 
+0

Awesome! Интересно, есть ли решение, которое не требует использования 'data.table'. –

+0

@wleoncio есть, см. Edit; Я больше не использую 'data.frame', и выше приведено только одно из множества примеров того, почему :) – eddi

+0

Хорошее редактирование, но решение' data.frame' не упорядочивает по порядку, а по продажам. ;) –