我有一个数据框df,其中包含来自汽车销售公司的数据。数据框包含日期和特定日期的销售数量。每个销售人员都有一个staff_id。虚拟inital_sell表示哪一天是该人的第一工作日。

现在,我想添加一列months_since_start,此列自该人开始工作以来每月增加的每一天。然后,我可以使用sellsmonths_since_start列来绘制自销售人员开始工作以来每个月的平均销售量(每个销售人员第一个月的销售量,第二个月的销售量...)。由于缺少了几天和几个月的时间(例如,如示例底部所示的假期),我不能简单地添加一个序列来获取months_since_start

date        year    month   staff_id   sells  initial_sell   months_since_start
2014-11-11  2014    11      1          3      1              1
2014-11-12  2014    11      1          1      0              1
2014-11-14  2014    11      1          1      0              1
2014-11-15  2014    11      1          2      0              1
...
2014-12-10  2014    12      1          2      0              1
2014-12-11  2014    12      1          1      0              2
...
2014-12-23  2014    12      2          1      1              1
2015-02-02  2015    2       2          4      0              2
2015-02-03  2015    2       2          1      0              2
...
2015-03-23  2015    3       2          3      0              4
...

有人可以帮助我如何获取month_since_start列吗?

最佳答案

如问题中所示,假定输入按staff_iddate排序,并在注释的末尾显示。定义months函数,该函数为工作人员提供了日期的排序 vector ,该函数返回该成员自开始以来的月份(即自第一个日期开始)。然后使用tapply将其应用于每个工作人员。 tapply返回按staff_id排序的列表,因此请使用unlist解开它。不使用任何软件包。

Months <- function(date) {
  with(as.POSIXlt(date), 12 * (year - year[1]) + (mon - mon[1]) + (mday >= mday[1]))
}

transform(DF, months_since_start = unlist(tapply(date, staff_id, FUN = Months)))

给予:
         date year month staff_id sells initial_sell months_since_start
1  2014-11-11 2014    11        1     3            1                  1
2  2014-11-12 2014    11        1     1            0                  1
3  2014-11-14 2014    11        1     1            0                  1
4  2014-11-15 2014    11        1     2            0                  1
5  2014-12-10 2014    12        1     2            0                  1
6  2014-12-11 2014    12        1     1            0                  2
7  2014-12-23 2014    12        2     1            1                  1
8  2015-02-02 2015     2        2     4            0                  2
9  2015-02-03 2015     2        2     1            0                  2
10 2015-03-23 2015     3        2     3            0                  4

替代使用ave代替tapply的替代方法如下。 Months如上。 MonthsDF调用Months,但接受行号而不是日期本身。此解决方案仍假定数据在date中按staff_id排序,但是由于ave返回的输出与输入的顺序相同,因此不需要按staff_id排序。 ave的不利之处在于它无法按照此处所需的方式处理"Date"类数据,这就是为什么我们使用行号作为MonthsDF的输入的原因:
MonthsDF <- function(ix) Months(DF$date[ix])
transform(DF, months_since_start = ave(seq_along(date), staff_id, FUN = MonthsDF))

注:使用了以下输入:
Lines <- "date        year    month   staff_id   sells  initial_sell
2014-11-11  2014    11      1          3      1
2014-11-12  2014    11      1          1      0
2014-11-14  2014    11      1          1      0
2014-11-15  2014    11      1          2      0
2014-12-10  2014    12      1          2      0
2014-12-11  2014    12      1          1      0
2014-12-23  2014    12      2          1      1
2015-02-02  2015    2       2          4      0
2015-02-03  2015    2       2          1      0
2015-03-23  2015    3       2          3      0"

DF <- read.table(text = Lines, header = TRUE)
DF$date <- as.Date(DF$date)

# in the question the input is already sorted by staff_id and date so
# the next two lines are not really needed but if we had non-sorted data
# then we should first sort it like this to be in the same form as in question
o <- with(DF, order(staff_id, date))
DF <- DF[o, ]

关于r - 从数据框中开始算起的月数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35398290/

10-12 17:30
查看更多