计算R数据框中的累积唯一出现次数

时间:2017-06-11 02:51:22

标签: r dataframe

我正在处理一个数据集,它有两列:id,日期/时间。请找到以下示例,

id  date_time
1   2016-10-29 18:01:03.0000000 +08:00
1   2016-10-29 19:34:17.0000000 +08:00
1   2016-10-30 14:08:03.0000000 +08:00
1   2016-10-30 15:55:12.0000000 +08:00
2   2016-10-31 11:32:12.0000000 +08:00
2   2016-10-31 14:59:56.0000000 +08:00
2   2016-11-01 12:49:44.0000000 +08:00
2   2016-11-01 13:55:16.0000000 +08:00
2   2016-11-01 19:18:22.0000000 +08:00
2   2016-11-01 20:40:48.0000000 +08:00
3   2016-11-01 21:19:50.0000000 +08:00
3   2016-11-02 14:20:15.0000000 +08:00
3   2016-11-02 18:52:27.0000000 +08:00
3   2016-11-02 19:39:32.0000000 +08:00
3   2016-11-03 08:55:41.0000000 +08:00

我想获得的只有两列:第1列有使用日期和时间排序的每个id的累计出现次数,第2列有每个id的累积日期,如下表所示,

id  date_time                           occ date
1   2016-10-29 18:01:03.0000000 +08:00  1   1
1   2016-10-29 19:34:17.0000000 +08:00  2   1
1   2016-10-30 14:08:03.0000000 +08:00  3   2
1   2016-10-30 15:55:12.0000000 +08:00  4   2
2   2016-10-31 11:32:12.0000000 +08:00  1   1
2   2016-10-31 14:59:56.0000000 +08:00  2   1
2   2016-11-01 12:49:44.0000000 +08:00  3   2
2   2016-11-01 13:55:16.0000000 +08:00  4   2
2   2016-11-01 19:18:22.0000000 +08:00  5   2
2   2016-11-01 20:40:48.0000000 +08:00  6   2
3   2016-11-01 21:19:50.0000000 +08:00  1   1
3   2016-11-02 14:20:15.0000000 +08:00  2   2
3   2016-11-02 18:52:27.0000000 +08:00  3   2
3   2016-11-02 19:39:32.0000000 +08:00  4   2
3   2016-11-03 08:55:41.0000000 +08:00  5   3
  1. (注意+8:00是冗余的)。要生成第1列(occ):我已尝试将aveFUN=seq_along一起使用,首先分割日期和时间,然后使用ID,日期和时间order

    Q1 :有什么方法可以直接对date_time列进行排序吗?

  2. 对于第2列(日期),我首先使用唯一值获取数据框的子集我使用aveseq_along生成索引。之后我在循环中合并两个数据集。

    Q2 :是否有更有效的方法来实现相同目标?

1 个答案:

答案 0 :(得分:1)

我不清楚您date_time变量的格式是什么。我假设它是POSIXct。我已经修剪了垃圾并将其转换成了它。

d <- read.table(text="id,  date_time
1,   2016-10-29 18:01:03.0000000 +08:00
...
3,   2016-11-03 08:55:41.0000000 +08:00", header=TRUE, sep=",")
d$date_time <- as.POSIXct(substr(as.character(d$date_time), 4, 22))

此时,您可以使用?order对数据框进行排序,包括按日期排序(另请参阅:Understanding the order() function):

d <- d[order(d$id, d$date_time),]

对数据框进行排序后,要计算每个id中的行数,您可以使用?tapply。您也可以使用tapply通过撰写as.characteras.Date以及as.numericfactor来标记唯一日期。考虑一下:

d$occ  <- unlist(with(d, tapply(id, id, FUN=function(x){ 1:length(x) })))
d$date <- unlist(with(d, tapply(date_time, id, FUN=function(x){ 
                                  x = as.character(as.Date(x))
                                  as.numeric(factor(x, levels=unique(x))) 
                                })))
d
#    id           date_time occ date
# 1   1 2016-10-29 18:01:03   1    1
# 2   1 2016-10-29 19:34:17   2    1
# 3   1 2016-10-30 14:08:03   3    2
# 4   1 2016-10-30 15:55:12   4    2
# 5   2 2016-10-31 11:32:12   1    1
# 6   2 2016-10-31 14:59:56   2    1
# 7   2 2016-11-01 12:49:44   3    2
# 8   2 2016-11-01 13:55:16   4    2
# 9   2 2016-11-01 19:18:22   5    2
# 10  2 2016-11-01 20:40:48   6    3
# 11  3 2016-11-01 21:19:50   1    1
# 12  3 2016-11-02 14:20:15   2    1
# 13  3 2016-11-02 18:52:27   3    1
# 14  3 2016-11-02 19:39:32   4    1
# 15  3 2016-11-03 08:55:41   5    2