Вычисляемое поле на основе диапазонов во втором фрейме данных в R - PullRequest
0 голосов
/ 30 апреля 2018

Я нашел похожие посты относительно этой задачи, но все они имеют общий идентификатор, объединяющий две таблицы.

У меня есть один фрейм данных, который содержит записи о продажах (sales_df). Для этого примера я упростил таблицу данных, чтобы она содержала только 5 записей. Я хотел бы создать в столбце sales_df новый столбец, в котором будет указана сумма вознаграждения, которая будет указана в сумме продажной цены, определенной в таблице вознаграждений (pricing_fees). Обратите внимание, что количество фактических ценовых диапазонов, которые я должен учитывать, составляет около 30, поэтому я бы хотел попытаться избежать этого в выражении mutate.

Два кадра данных кодируются следующим образом

    sales_df <- data.frame(invoice_id = 1:5, 
sale_price = c(100, 275, 350, 500, 675))

    pricing_fees <- data.frame(min_range = c(0, 50, 100, 200, 300, 400, 500), # >=
    max_range = c(50, 100, 200, 300, 400, 500, 1000), # <
    buyer_fee = c(1, 1, 25, 50, 75, 110, 125))

В конце я бы хотел, чтобы итоговый sales_df выглядел примерно так.

  invoice_id sale_price buyer_fee
1          1        100        25
2          2        275        50
3          3        350        75
4          4        500       125
5          5        675       125

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Вы также можете использовать cut для "корзины" sales_df$sale_price значений и меток с соответствующими buyer_fee значениями.

# Make pricing_fee table with unique buyer_fee
brks <- do.call(rbind, by(pricing_fees, pricing_fees$buyer_fee, FUN = function(x)
    data.frame(min_range = min(x$min_range), max_range = max(x$max_range), buyer_fee = unique(x$buyer_fee))))

sales_df$buyer_fee = as.numeric(as.character(cut(
    sales_df$sale_price,
    breaks = c(0, brks$max_range),
    labels = brks$buyer_fee,
    right = F)))
#  invoice_id sale_price buyer_fee
#1          1        100        25
#2          2        275        50
#3          3        350        75
#4          4        500       125
#5          5        675       125
0 голосов
/ 30 апреля 2018

Вы можете использовать функцию findInterval, которая должна быть эффективной при разбиении значений по диапазонам (так как она использует двоичный поиск):

# build consecutive increasing ranges of fees 
# (in order to use findInterval, since it works on ranges defined in a single vector)
pricing_fees <- pricing_fees[order(pricing_fees$min_range),]
consecFees <- data.frame(ranges=c(pricing_fees$min_range[1], pricing_fees$max_range),
                         fees=c(pricing_fees$buyer_fee,NA))
# consecFees now is :
#
#   ranges fees
# 1      0    1  ---> it means for price in [0,50) -> 1
# 2     50    1  ---> it means for price in [50,100) -> 1
# 3    100   25  ---> it means for price in [100,200) -> 25
# 4    200   50  ... and so on
# 5    300   75
# 6    400  110
# 7    500  125
# 8   1000   NA ---> NA because for values >= 1000 we set NA


# add the column to sales_df using findInterval
sales_df$buyer_fee <- consecFees$fees[findInterval(sales_df$sale_price,consecFees$ranges)]

Результат:

> sales_df
  invoice_id sale_price buyer_fee
1          1        100        25
2          2        275        50
3          3        350        75
4          4        500       125
5          5        675       125
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...