我有一个数据框df
,其中包含来自汽车销售公司的数据。数据框包含日期和特定日期的销售数量。每个销售人员都有一个staff_id
。虚拟inital_sell
表示哪一天是该人的第一工作日。
现在,我想添加一列months_since_start
,此列自该人开始工作以来每月增加的每一天。然后,我可以使用sells
和months_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_id
和date
排序,并在注释的末尾显示。定义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/