【问题标题】:Alternatives to MAPPLY in RR中MAPPLY的替代品
【发布时间】:2016-07-02 02:14:38
【问题描述】:

我有一个包含以下内容的数据框:

1) 商店 2) DayOfWeek
3) 日期 4) 销售
5) 客户
6) 打开 7) 促销
8) 国庆节 9) 学校假期
10) 商店类型
11) 分类
12) 比赛距离 13) 竞赛OpenSinceMonth
14) 竞赛OpenSinceYear
15) 促销2
16) Promo2SinceWeek 17) Promo2SinceYear 18) 促销间隔
19) CompanyDistanceBin
20) 竞赛OpenSinceDate
21) DaysSinceCompetionOpen

我正在尝试根据日期(基本上是日期 - 3 个月)计算上一季度的平均销售额。但是,我还需要根据 DayOfWeek 和 Promo 进行子集化。我写了一个函数并且正在使用mapply。

quarter.store.sales.func <- function(storeId, storeDate, dayofweekvar, promotion)
{   
    storeDate = as.Date(storeDate,"%Y-%m-%d")
    EndDate = ymd(as.Date(storeDate)) + ddays(-1)
    EndDate = as.Date(storeDate,"%Y-%m-%d")
    StartDate = ymd(storeDate + months(-3))
    StartDate = as.Date(StartDate)

    quarterStoresales <- subset(saleswithstore, Date >= StartDate & Date <= EndDate & Store == storeId & DayOfWeek == dayofweekvar & Promo == promotion)
    quarterSales = 0
    salesDf <- ddply(quarterStoresales,.(Store),summarize,avgSales=mean(Sales))  

    if (nrow(salesDf)>0)
      quarterSales = as.numeric(round(salesDf$avgSales,digits=0))     

    return(quarterSales)
}

saleswithstore$QuarterSales <- mapply(quarter.store.sales.func, saleswithstore$Store, saleswithstore$Date, saleswithstore$DayOfWeek, saleswithstore$Promo)

 head(exampleset)
           Store         DayOfWeek Date               Sales           Promo
186            1                3  2013-06-05         5012            1
296            1                3  2013-04-10         4903            1
337            1                3  2013-05-29         5784            1
425            1                3  2013-05-08         5230            0
449            1                3  2013-04-03         4625            0
477            1                3  2013-03-27         6660            1

saleswithstore 是一个包含 1,000,000 行的数据框。所以,这个解决方案是不可行的,因为它性能很差并且永远存在。有没有更好、更有效的方法在这样的数据帧上拥有一个特定的子集,然后像我在这里尝试做的那样取平均值?

我愿意接受任何建议。诚然,我是 R 的新手。

【问题讨论】:

  • 这里的瓶颈可能是数据帧对信号的多次分配。您尝试使用 dplyr 的 group_by 功能?或者,data.table 可能会完成这项工作
  • 一些注意事项:(1) 将“日期”操作函数移出您的函数并在整个列上使用 as.Date 等(因为这些函数接受 length &gt; 1 的向量)而不是mapply 在每个元素中,(2)您创建 quarterStoresales 的方式建议由 c(Store, DayOfWeek, Promo) 分组的操作,R 为这些操作提供内置功能和包。另外,您能否提供一个 example dataset 仅包含必要的列和预期输出?
  • Alexis,这里是 1 家商店的负责人:
  • Alexis,我已将示例集添加到我的原始帖子中,并将以下 QuarterStartDate 和 QuarterEndDate 添加到函数外部的数据框中。 saleswithstore$QuarterStartDate = QuarterStartDate和日期

标签: r


【解决方案1】:

@maubin0316,您的直觉是正确的,您可以按其余变量分组。我使用data.table 整理了这个示例

library(data.table)
set.seed(343)

# Create sample data
dt <- data.table('Store' = sample(1:10, 100, replace=T),
                 'DayOfWeek' = sample(1:7, 100, replace=T),
                 'Date' = sample(as.Date('2013-01-01'):as.Date('2013-06-30'), 100, replace=T),
                 'Sales' = sample(1000:10000, 100),
                 'Promo' = sample(c(0,1), 10, replace=T))

QuarterStartDate <- as.Date('2013-01-01')
QuarterEndDate <- as.Date('2013-03-31')

# Function to calculate your quarterly sales
QuarterlySales <- function(startDate, endDate, data){
  # Limit between your dates, group by your variables of interest
  data <- data[between(Date,startDate,endDate),list(TotalSales=sum(Sales)), by=list(Store,DayOfWeek,Promo)]
  # Sort in an order that makes sense
  data <- data[order(Store, DayOfWeek, Promo)]
  return(data)
}

salesSummary <- QuarterlySales(QuarterStartDate, QuarterEndDate, dt)
salesSummary

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-26
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多