2015-08-06 6 views
3

OK, проверить этот кадр данных ...Как оценивать группы в R?

customer_name order_dates order_values 
1   John 2010-11-01   15 
2   Bob 2008-03-25   12 
3   Alex 2009-11-15   5 
4   John 2012-08-06   15 
5   John 2015-05-07   20 

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

customer_name order_dates order_values ranked_order_values_by_max_value_date 
1   John 2010-11-01   15        3 
2   Bob 2008-03-25   12        1 
3   Alex 2009-11-15   5        1 
4   John 2012-08-06   15        2 
5   John 2015-05-07   20        1 

Где разовый заказ каждый получает 1, и все последующие заказы оценивается на основе стоимости, а галстук выключатель дата последнего заказа становится приоритетной задача. В этом примере заказ Джона 8/6/2012 получает ранг №2, потому что он был размещен после 11/1/2010. Порядок 5/7/2015 - 1, потому что он был самым большим. Таким образом, даже если этот ордер был поставлен 20 лет назад, он должен быть рангом №1, потому что это значение самого высокого порядка Джона.

Кто-нибудь знает, как я могу это сделать в R? Где я могу ранжировать в группе заданных переменных в кадре данных?

Благодарим за помощь!

+0

@akrun, а что же касается брелка для ценностей? –

+0

Вот код для создания фрейма данных в случае, если это помогает: customer_name <- c («John», «Bob», «Alex», «John», «John»); order_dates <- as.Date (c ('2010-11-1', '2008-3-25', '2009-11-15', '2012-8-6', '2015-5-7')); order_values ​​<- c (15,12,5,15,20); test_data <- данные.рамка (CUSTOMER_NAME, order_dates, order_values); –

+1

@SenorO Пример OP должен быть более сложным для тестирования. Кроме того, 'dense_rank' из' dplyr' является одним из способов для тай-брейкера – akrun

ответ

5

Вы можете сделать это довольно чисто с dplyr

library(dplyr) 
df %>% 
    group_by(customer_name) %>% 
    mutate(my_ranks = order(order_values, order_dates, decreasing=TRUE)) 

Source: local data frame [5 x 4] 
Groups: customer_name 

    customer_name order_dates order_values my_ranks 
1   John 2010-11-01   15  3 
2   Bob 2008-03-25   12  1 
3   Alex 2009-11-15   5  1 
4   John 2012-08-06   15  2 
5   John 2015-05-07   20  1 
+0

Точно то, что я хотел, и узнал что-то новое. Благодаря! –

+0

Это неверно. [Правильный ответ] (https://stackoverflow.com/a/43666202/7114709) предоставляется @ T.Himmel. – syre

1

Это может быть достигнуто с ave и rank. ave передает соответствующие группы rank. Результат от rank восстанавливается за счет запрашиваемого заказа:

with(x, ave(as.numeric(order_dates), customer_name, FUN=function(x) rev(rank(x)))) 
## [1] 3 1 1 2 1 
2

В базе R вы можете сделать это с немного громоздким

transform(df,rank=ave(1:nrow(df),customer_name, 
    FUN=function(x) order(order_values[x],order_dates[x],decreasing=TRUE))) 
 
    customer_name order_dates order_values rank 
1   John 2010-11-01   15 3 
2   Bob 2008-03-25   12 1 
3   Alex 2009-11-15   5 1 
4   John 2012-08-06   15 2 
5   John 2015-05-07   20 1 

где order обеспечивается как основной и привязывайте для каждой группы.

5

Самый рейтинговый ответ (по cdeterman) на самом деле неверен. Функция заказа обеспечивает расположение ранговых значений 1, 2, 3 и т. Д., А не ряды значений в их текущем порядке.

Давайте рассмотрим простой пример, в котором мы хотим ранжировать, начиная с наибольшей группировки по имени клиента. Я включил ручной рейтинг, чтобы мы могли проверить значения

> df 
     customer_name order_values manual_rank 
    1   John   2   5 
    2   John   5   2 
    3   John   9   1 
    4   John   1   6 
    5   John   4   3 
    6   John   3   4 
    7   Lucy   4   4 
    8   Lucy   9   1 
    9   Lucy   6   3 
    10   Lucy   2   6 
    11   Lucy   8   2 
    12   Lucy   3   5 

Если я запускаю код, предложенный cdeterman я получаю следующие неправильные ряды:

> df %>% 
    + group_by(customer_name) %>% 
    + mutate(my_ranks = order(order_values, decreasing=TRUE)) 
    Source: local data frame [12 x 4] 
    Groups: customer_name [2] 

     customer_name order_values manual_rank my_ranks 
       <fctr>  <dbl>  <dbl> <int> 
    1   John   2   5  3 
    2   John   5   2  2 
    3   John   9   1  5 
    4   John   1   6  6 
    5   John   4   3  1 
    6   John   3   4  4 
    7   Lucy   4   4  2 
    8   Lucy   9   1  5 
    9   Lucy   6   3  3 
    10   Lucy   2   6  1 
    11   Lucy   8   2  6 
    12   Lucy   3   5  4 

Order используется для переназначения dataframes в уменьшения или увеличения порядка. На самом деле мы хотим запустить функцию ордера дважды, причем функция второго порядка дает нам фактические ранги, которые мы хотим.

> df %>% 
    + group_by(customer_name) %>% 
    + mutate(good_ranks = order(order(order_values, decreasing=TRUE))) 
    Source: local data frame [12 x 4] 
    Groups: customer_name [2] 

     customer_name order_values manual_rank good_ranks 
       <fctr>  <dbl>  <dbl>  <int> 
    1   John   2   5   5 
    2   John   5   2   2 
    3   John   9   1   1 
    4   John   1   6   6 
    5   John   4   3   3 
    6   John   3   4   4 
    7   Lucy   4   4   4 
    8   Lucy   9   1   1 
    9   Lucy   6   3   3 
    10   Lucy   2   6   6 
    11   Lucy   8   2   2 
    12   Lucy   3   5   5 
Смежные вопросы