【问题标题】:Plot the count of purchase per day and month in R在 R 中绘制每天和每月的购买次数
【发布时间】:2017-12-03 14:53:17
【问题描述】:

数据集表示哪个客户 (Cstid = Customer id) 在哪一天进行了购买。

我很难找到解决方案来绘制每天和每月的购买数量。

请在下面找到数据集的示例,我总共有 7505 个观察值。

  "Cstid"  "Date"
1  4195     19/08/17
2  3937     16/08/17
3  2163     07/09/17
4  3407     08/10/16
5  4576     04/11/16
6  3164     16/12/16
7  3174     18/08/15
8  1670     18/08/15
9  1671     18/08/15
10 4199     19/07/14
11 4196     19/08/14
12 6725     14/09/14
13 3471     14/09/13

我已经开始转换日期列:

 df$Date <- as.Date(df$Date, '%d/%m/%Y')

然后使用以下方法计算每个日期的观察次数:

library(data.table)
dt <- as.data.table(df)
dt[,days:=format(Date,"%d.%m.%Y")]
dt1 <- data.frame(dt[,.N,by=days])

并尝试使用:

plot(dt1$days, dt1$N,type="l")

但我收到以下错误消息:

Error in plot.window(...) : need finite 'xlim' values
In addition: Warning messages:
1: In xy.coords(x, y, xlabel, ylabel, log) : NAs introduced by coercion
2: In min(x) : no non-missing arguments to min; returning Inf
3: In max(x) : no non-missing arguments to max; returning -Inf

有人可以告诉我应该如何进行吗?

【问题讨论】:

  • 请展示你在绘制它时的尝试。
  • @jmuhlenkamp 感谢您的反馈。我已经编辑了问题并添加了我收到的错误消息。
  • 正如我的回答中提到的,您可能选择了错误的年份格式。

标签: r plot ggplot2


【解决方案1】:

您需要使用 %y(小写)指定 2 位数的年份,以便将 Date 列从字符转换为类 Date

如果ggplot2 用于绘图,它也会进行聚合。 geom_bar() 默认使用 count 统计信息。这让我们不必事先计算聚合(计数)。

对于按月聚合,我建议将所有日期映射到每个月的第一天,例如,使用 lubridate::floor_date()。这会在 x 轴上保持连续的刻度。

所以,完整的代码是:

# convert Date from character to class Date using a 2 digit year
df$Date <- as.Date(df$Date, '%d/%m/%y')

library(ggplot2)
# aggregate by day
ggplot(df) + aes(x = Date) + 
  geom_bar()

#aggregate by month
ggplot(df) + aes(x = lubridate::floor_date(Date, "month")) + 
  geom_bar()

或者,日期可以映射到字符月份,例如,"2015-08"。但这会将 x 轴变成一个离散的刻度,不再显示购买之间的经过时间:

# aggregate by month using format() to create discrete scale
ggplot(df) + aes(x = format(Date, "%Y-%m")) + 
  geom_bar()

【讨论】:

    【解决方案2】:
    #reproduciable data:
    df <- data.frame(Cstid=c(4195,3937,2163,3407,4576,3164,3174,1670,1671,4199,4196,6725,3471),
               Date=c('19/08/17','16/08/17','07/09/17','08/10/16','04/11/16','16/12/16','18/08/15','18/08/15',
    '18/08/15','19/07/14','19/08/14','14/09/14','14/09/13'))
    #convert format:
    df$Date <- as.character(df$Date)
    Y <- paste('20',sapply(strsplit(df$Date,split = '/'),function(x){x[3]}),sep='')
    M <- sapply(strsplit(df$Date,split = '/'),function(x){x[2]})
    D <- sapply(strsplit(df$Date,split = '/'),function(x){x[1]})
    df$Date <-  as.POSIXct(paste(Y,M,D,sep='-'),format='%Y-%m-%d')
    #count per day plot:
    days <- unique(df$Date)
    dcount <- vector()
    for (i in 1:length(days)) {
    dcount[i]  <- nrow(df[df$Date==days[i],])
    }
    library(ggplot2)
    ggplot(data=data.frame(days,dcount),aes(x=days,y=dcount))+geom_point()
    #count per month plot:
    df$month <- months(df$Date)
    mon <- unique(df$month)
    mcount <- vector()
    for (i in 1:length(mon)) {
      mcount[i]  <- nrow(df[df$month==mon[i],])
    }
    ggplot(data.frame(mon,mcount),aes(x=mon,y=mcount))+geom_point()
    

    【讨论】:

    • Uwe's answer的日期格式转换方法效率更高。
    • geom_bar(stat='count') 可以自己完成计数工作。但是如果你想要一个pointline 绘图,你可以先构建计数时间数据框。
    • 明白了!谢谢@YQ.Wang
    猜你喜欢
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多