Выберите max для каждой комбинации переменных в data.frame - PullRequest
1 голос
/ 18 ноября 2011

Я пытаюсь найти легкий путь к последней уплаченной цене за комбинацию «продукт-клиент».

customers <-  c("cust_a","cust_b","cust_a","cust_b")
products <- c("prod_a","prod_b","prod_a","prod_b")
dates <- c("2011/10/25","2011/09/14","2011/03/12","2011/05/06")
prices <-c("10","12","15","18")
df <- cbind(customers,products)
df <- cbind(df, dates)
df <- as.data.frame(cbind(df,prices))

Далее я хотел бы создать новый фрейм data.frame для каждого клиента - продукт с сочетанием цены с самой высокой датой.В этом примере data.frame комбинация cust_a и prod_1 даст 10, а cust_b и prod_2 - 12.

Я знаю, как это сделать в SQL, но в этом случае решение SQL не является опцией дляя.

Ответы [ 3 ]

6 голосов
/ 18 ноября 2011

Вы можете использовать пакет plyr для этого типа проблемы:

library(plyr)

dat = data.frame(
  customers =  c("cust_a","cust_b","cust_a","cust_b"),
  products = c("prod_a","prod_b","prod_a","prod_b"),
  dates = c("2011/10/25","2011/09/14","2011/03/12","2011/05/06"),
  prices =c("10","12","15","18")
)

Сначала преобразуйте столбец dates в класс Date, используя as.Date. Это позволяет легко работать, в том числе найти максимум:

dat$dates <- as.Date(dat$dates)

Далее используйте ddply. Это разбивает data.frame на части, применяет функцию к каждому фрагменту и затем возвращает data.frame после объединения всех частей. Функция, которую вы хотите применить к каждому чанку, это subset, в частности это подмножество, где dates==max(dates):

ddply(dat, .(customers, products), subset, dates==max(dates))

  customers products      dates prices
1    cust_a   prod_a 2011-10-25     10
2    cust_b   prod_b 2011-09-14     12
2 голосов
/ 18 ноября 2011

Вы можете сделать это, используя пакет plyr.Вот решение

# CONVERT DATES TO DATE FORMAT
df <- transform(df, dates = as.Date(dates, "%Y/%m/%d"))

# FOR CUSTOMER-PRODUCT COMBINATION, EXTRACT PRICE OF MAX(DATES)
plyr::ddply(df, .(customers, products), summarize, 
  last_price = prices[which.max(dates)])

  customers products last_price
1    cust_a   prod_a         10
2    cust_b   prod_b         12
1 голос
/ 18 ноября 2011

Если ваш df упорядочен по дате (как я вижу), тогда простые split и lapply сделают эту работу:

lapply(split(df, df$customers), function(x) x$prices[1])

Если нет, то закажите df перед строкой выше или используйте его во внутренней функции:)


Результаты:

> lapply(split(df, df$customers), function(x) x$prices[1])
$cust_a
[1] 10
Levels: 10 12 15 18

$cust_b
[1] 12
Levels: 10 12 15 18

> sapply(split(df, df$customers), function(x) x$prices[1])
cust_a cust_b 
    10     12 
Levels: 10 12 15 18

Обновление : приведенный выше пример был запущен только для customers, так как в примере products не имеет роли. Но для комбинаций используйте список как f параметр split, например ::

> lapply(split(df, list(df$customers, df$products)), function(x) x$prices[1])
$cust_a.prod_a
[1] 10
Levels: 10 12 15 18

$cust_b.prod_a
[1] <NA>
Levels: 10 12 15 18

$cust_a.prod_b
[1] <NA>
Levels: 10 12 15 18

$cust_b.prod_b
[1] 12
Levels: 10 12 15 18
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...