R中多列的条件求和

时间:2017-04-07 18:09:40

标签: r time data.table

我想绘制每个用户的点数与时间的关系,但我不确定如何对列进行以实现该结果。这就是我的数据:

> head(data, n=3)
points   user       time
25        1      02/22/2017
0         2      02/26/2017
15        3      02/27/2017

> dput(data)
structure(list(points = c(25, 0, 15), user = c(1, 2, 3), time = c("02/22/2017", "02/26/2017", "02/27/2017")), .Names = c("points", "user", "time"), row.names = c(NA, -3L), class = "data.frame")

仅供参考,有多个用户ID(我认为最多15个)。但是,我想要做的是将每个用户的总积分相加(然后用户列中的数字对应于用户的ID号。然后根据时间(特别是按天)绘制这些值。

这是我用来生成每个用户总分的代码

library(data.table)
ppu = setkey(setDT(df), user_id)[, list(points=sum(points)), by=list(user_id)]

这给出了以下结果:

enter image description here

但我希望找到每位用户每天的总积分!我真的很感激任何指导。

2 个答案:

答案 0 :(得分:3)

请尝试(使用Q中df的结果给出的dput()):

library(data.table)   # version 1.10.4 used
ppu <- setDT(df)[, .(points = sum(points)), by = .(user, time)]

ppu
#   user       time points
#1:    1 02/22/2017     25
#2:    2 02/26/2017      0
#3:    3 02/27/2017     15

这将按照user中显示的顺序返回timedf。如果要对结果进行排序,则有两种选择:

例如,用于打印,请使用

ppu[order(user, time)]
# or
ppu[order(time, user)]

或者,如果结果应该键入,请尝试keyby

ppu <- setDT(df)[, .(points = sum(points)), keyby = .(user, time)]

一些评论:

  • 当您的数据样本使用user_id时,您的代码段使用user。此外,数据样本包含一个名为time的列,其中包含日期作为字符串,但在文本中您使用的术语是&#34; day&#34;。
  • by接受多个分组变量。您甚至可以动态创建表达式
  • 作为简化,只要同一日期以相同的方式编写,time就不需要被强制转换为Data类。
  • data.table语法中,。()list()的缩写。
  • data.table的最新版本已经解除了设置密钥的要求。

this comment中,OP询问了如何

  

绘制每个用户的点数与时间(每天)。

这需要ppu的一些修改才能更好地与ggplot2一起使用。

# coerce user to factor to get a discrete colour scale
# only required here because user was given as numeric 
ppu[, user := factor(user)]
# coerce time from character to Date class
# to get a nicely scaled x-axis instead of discrete values
ppu[, time := lubridate::mdy(time)]

现在,pointstime相对,但每个user都有一个单独的颜色编码行:

library(ggplot2)
ggplot(ppu, aes(time, points, group = user, colour = user)) + 
  geom_point() + geom_line()

enter image description here

好吧,如果有足够的样本数据,你可能会看到这里的行......

答案 1 :(得分:0)

首先,您需要将日期转换为一种不错的格式,因为我建议您使用library(lubridate)这样:

data$day <- mdy(data$day)

然后将每个用户每天的积分数相加:

library(plyr)
pts_user_day <- ddply(data, .(user, day), summarise, pts_day = sum(points))

最后随着时间的推移绘制所有这些:

library(ggplot2)
ggplot(pts_user_day, aes(x=day, y=pts_day, col=factor(user))) + geom_line() + scale_x_date()

希望有所帮助!