我有一个多线图,显示了各种线路形式的20位客户的收入。
我使用了以下代码:
library(dplyr)
trainingSummary <- top20CustomersRevenue %>% group_by(custno, TrainingDate) %>%
summarize(Revenue = first(Revenue),
TrainingType = first(TrainingType))
trainingSummary$TrainingType <- as.factor(trainingSummary$TrainingType)
p <- ggplot() + geom_line(data=top20CustomersRevenue,aes(x=DeltaMonth,y=Revenue,group=custno),alpha=0.3) +
theme_bw() +
ylab('Revenue (Dollars)') + xlab('') + theme(legend.title=element_blank()) +
theme(legend.title=element_blank(),axis.text.y=element_text(hjust=0, angle=0),
axis.text.x = element_text(hjust=1, angle=45),plot.title=element_text(size=20))
p <- p + geom_point(data = trainingSummary,
aes(x = TrainingDate, y = Revenue, color= TrainingType))
p
并得到以下情节:
我的数据格式如下:
custno TrainingType Revenue TrainingDate DeltaMonth
250 Webinar 4146.80 2013-02-26 2013-01-01
250 Webinar 6211.93 2013-02-26 2013-02-01
250 Webinar 2199.72 2013-02-26 2013-03-01
250 Webinar 4452.65 2013-02-26 2013-04-01
250 Webinar 4787.83 2013-02-26 2013-05-01
250 Webinar 4004.80 2013-02-26 2013-06-01
250 Webinar 4806.69 2013-02-26 2013-07-01
示例 - 在上面的数据集中,我想在custno
TrainingDate
处的2013-02-26
250对应的行添加一个勾号。
以下是dput(head(top20CustomersRevenue))
:
structure(list(custno = c(250L, 250L, 250L, 250L, 250L, 250L),
TrainingType = structure(c(5L, 5L, 5L, 5L, 5L, 5L), .Label = c("In-person",
"In person", "In Person", "webinar", "Webinar", "Webinar "
), class = "factor"), Revenue = c(4146.8, 6211.93, 2199.72,
4452.65, 4787.83, 4004.8), TrainingDate = structure(c(1361865600,
1361865600, 1361865600, 1361865600, 1361865600, 1361865600
), class = c("POSIXct", "POSIXt"), tzone = ""), DeltaMonth = structure(c(1357027200,
1359705600, 1362124800, 1364799600, 1367391600, 1370070000
), class = c("POSIXct", "POSIXt"), tzone = "")), .Names = c("custno",
"TrainingType", "Revenue", "TrainingDate", "DeltaMonth"), row.names = c(NA,
6L), class = "data.frame")
我有20个不同客户的数据,其中custno
和TrainingDate
不同。
如何确保这些点位于正确的位置,而不是悬挂在空中?
非常感谢这方面的任何帮助。
更新
@Gregor - 非常感谢你非常有帮助的回答。我仍然面临ceiling_date
的问题:
以下是我原始数据的一部分:
[889] "2013-02-01" "2013-02-01" "2013-02-01" "2013-02-01" "2013-02-01" "2013-02-01"
[895] "2013-02-01" "2013-02-01" "2013-02-01" "2013-02-01" "2013-02-01" "2013-02-01"
[901] "2013-02-01" "2013-02-01" "2013-02-01" "2013-02-01" "2013-02-01" "2013-02-01"
[907] "2013-02-01" "2013-02-01" "2013-02-01" "2013-02-01" "2013-02-01" "2013-02-01"
运行ceiling_date(top20CustomersRevenue$TrainingDate + months(1), unit = "month")
后,这是相同的部分:
[889] NA NA NA NA NA NA
[895] NA NA NA NA NA NA
[901] NA NA NA NA NA NA
[907] NA NA NA NA NA NA
查看生成NA
的代码,我运行了以下语句,但没有生成NA
。
> ceiling_date(as.Date("2013-02-01")+months(1),unit="month")
[1] "2013-03-01"
为什么这种行为上的差异?你有什么想法吗?
答案 0 :(得分:1)
现在这是未经测试的,因为我在R会话忙于运行模型时回答这个问题,但我认为它会起作用:
正如@BondedDust建议的那样,首先我们对您的数据进行分组,每个培训每位客户1行:
library(dplyr)
trainingSummary <- top20CustomersRevenue %>% group_by(custno, TrainingDate) %>%
summarize(Revenue = first(Revenue),
TrainingType = first(TrainingType))
编辑:要为特定培训日插入收入,我们会查看上个月和下个月,并根据培训发生的月份来确定我们的位置。我将您的POSIX日期转换为Date
个对象,如果需要,您可以在最后转换回来。
library(ggplot2)
library(dplyr)
library(lubridate)
top20CustomersRevenue <- top20CustomersRevenue %>% mutate(DeltaMonth = as.Date(DeltaMonth),
TrainingDate = as.Date(TrainingDate))
trainingSummary <- top20CustomersRevenue %>%
group_by(custno, TrainingDate) %>%
mutate(prev.month.rev = Revenue[DeltaMonth == floor_date(TrainingDate, unit = "month")],
next.month.rev = Revenue[DeltaMonth == ceiling_date(TrainingDate, unit = "month")],
interp.rev = prev.month.rev + (next.month.rev - prev.month.rev) *
((mday(TrainingDate) - 1) / days_in_month(month(TrainingDate)))) %>%
summarize(Revenue = first(interp.rev),
TrainingType = first(TrainingType))
trainingSummary$TrainingType <- factor(trainingSummary$TrainingType)
p <- ggplot() +
geom_line(data = top20CustomersRevenue,
aes(x = DeltaMonth, y=Revenue, group=custno), alpha=0.3) +
theme_bw() +
labs(y = 'Revenue (Dollars)', x = '') +
theme(legend.title = element_blank()) +
theme(legend.title = element_blank(),
axis.text.y = element_text(hjust=0, angle=0),
axis.text.x = element_text(hjust=1, angle=45),
plot.title = element_text(size=20)) +
geom_point(data = trainingSummary,
aes(x = TrainingDate, y = Revenue, color= TrainingType))
p
这适用于您提供的样本。如果你有任何训练发生在最后一个DeltaMonth之后或第一个DeltaMonth之前,他们就不会工作。
我们为了获得在特定培训日期绘制的y值(即收入)而做的非常简单。我们假设我们有约会培训d
。我们获得前一个DeltaMonth的y(收入)值y_prev
,以及下个月收入的y_next
。
由于所有DeltaMonth日期值都是使用floor_date()
而在本月的第一天,ceiling_date()
会获取上一个和下一个DeltaMonth日期值。
连接上个月和下个月收入的线的斜率为
slope = change in y / change in x = (y_next - y_prev) / (number of days in month)
因此,培训日期的y值是上一个收入(y_prev
)加上斜率乘以该月初以来的天数。自月初开始的天数为mday(trainingDate) - 1
,interp.rev
中的其他内容为斜率。它只是一个有点和斜坡的高中代数。