【问题标题】:Using R, how to aggregate by day of week?使用 R,如何按星期几聚合?
【发布时间】:2011-11-12 23:04:14
【问题描述】:

我有一个 df/zoo/xts/whatever 按星期几分开。我想为每个条目按周进一步拆分。

例如,星期五,有一个 ID 列表,每个 ID 都有相关的时间。这些时间可能是一年中的任何一个星期五。我想在那个星期五制作一个新的 df,其中包含每个 id 以及每周的计数(按顺序)。

看起来像下面这样,其中每个 w 列是不同的星期五计数:

    id w1 w2 w3 w4
1 id_1  1  2  2  8
2 id_2  3  1  5  2
3 id_3  7  4 10  7

输入:

structure(list(id = c("id_1", "id_2", "id_3"), w1 = c(1, 3, 7
), w2 = c(2, 1, 4), w3 = c(2L, 5L, 10L), w4 = c(8L, 2L, 7L)), .Names = c("id", 
"w1", "w2", "w3", "w4"), row.names = c(NA, 3L), class = "data.frame")

这似乎已经成熟了聚合,但我不能完全正确的语法。我尝试过的其他事情如下:

# Applies sum to everything, which doesnt make sense in this context
apply.weekly(friday, sum)

# I considered doing something like getting the unique weeks with:
as.numeric(unique(format(friday[,2], "%U")))
# and then generating each week, getting the counts for each user, and then making a new df from this process. But this seems very inefficient.  

编辑: str(data[1:20,]) 的输出:

'data.frame':   20 obs. of  2 variables:
 $ id  : num  1 2 3 4 5 1 2 3 3 2 ...
 $ time: POSIXct, format: "2011-04-25 14:00:00" "2011-04-28 20:00:00" "2011-05-03 06:00:00" "2011-05-06 14:00:00" ...

来自 dput(data[1:20,]) 的输出:

structure(list(id = c(1, 2, 3, 4, 5, 1, 2, 3, 3, 2, 1, 4, 3, 
2, 1, 4, 3, 2, 1, 7), time = structure(c(1303754400, 1304035200, 
1304416800, 1304704800, 1304920800, 1305252000, 1305428400, 1305522000, 
1305774000, 1306404000, 1306422000, 1308261600, 1308290400, 1308340800, 
1308542400, 1308715200, 1308722400, 1308844800, 1309575600, 1309730400
), class = c("POSIXct", "POSIXt"))), .Names = c("id", "time"), row.names = c(1L, 
2L, 3L, 4L, 5L, 6L, 7L, 8L, 
9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L), class = "data.frame")

【问题讨论】:

  • 请发布您目前拥有的内容
  • 如果您在查看this question 并修改您迄今为止所写的内容后更新您的问题,您会得到更好的答案。
  • 已编辑以反映您的评论。
  • 也许其他人可以跟随这个,但我不能。如果您发布来自str(data) 的输出并使用一些假数据制作了一个可重现的示例,那么实际上会有所帮助。
  • 是的,请告诉我们。 dput(datas[1:20,]) 或类似的东西

标签: r aggregate xts zoo


【解决方案1】:

如果我理解您想要什么,您需要为一周中的某一天(以便您识别)和一年中的一周(以便您最终为每个列添加单独的列)添加额外的列.使用您给dput()data

data$day.of.week <- format(data$time, "%A")
data$week.of.year <- format(data$time, "%U")

现在你想有效地重塑数据,所以使用reshape2 包(不是唯一的方法,而是我最熟悉的方法)

library("reshape2")

dcast(data[data$day.of.week=="Friday",], id~week.of.year, 
    value_var="time", fun.aggregate=length)

在该示例中,我对数据进行了子集化以获取星期五。如果您想每天都做,但每天分开,plyr 包可以帮助您进行迭代。

library("plyr")

dlply(data, .(day.of.week), dcast, id~week.of.year, 
    value_var="time", fun.aggregate=length)

这两个的结果是:

> dcast(data[data$day.of.week=="Friday",], id~week.of.year, value_var="time", fun.aggregate=length)
  id 18 24 26
1  1  0  0  1
2  2  0  1  0
3  4  1  0  0

> dlply(data, .(day.of.week), dcast, id~week.of.year, value_var="time", fun.aggregate=length)
$Friday
  id 18 24 26
1  1  0  0  1
2  2  0  1  0
3  4  1  0  0

$Monday
  id 17
1  1  1

$Saturday
  id 19
1  2  1

$Sunday
  id 19 20 25 27
1  1  0  0  1  0
2  3  0  1  0  0
3  5  1  0  0  0
4  7  0  0  0  1

$Thursday
  id 17 19 21 24 25
1  1  0  1  1  0  0
2  2  1  0  1  0  1
3  3  0  0  0  1  0
4  4  0  0  0  1  0

$Tuesday
  id 18 25
1  3  1  1
2  4  0  1

$Wednesday
  id 20
1  3  1

attr(,"split_type")
[1] "data.frame"
attr(,"split_labels")
  day.of.week
1      Friday
2      Monday
3    Saturday
4      Sunday
5    Thursday
6     Tuesday
7   Wednesday

【讨论】:

  • 是的,这正是我想要的。我尝试复制它,发现在我正在处理的数据大小上,dcast/dlply 命令花费的时间非常长。可能只是把它从 R 上取下来做这部分。
  • 我认为(但不确定)最新的 reshape2 和 ddply 包支持 parrelisation。如果您有一台多核机器(或访问多台机器),那么这可能会加快您的速度。
  • 我试过这个;还需要一段时间。但是对于某些集合来说,加速是显而易见的。感谢您的提示。
猜你喜欢
  • 2015-05-13
  • 2020-12-11
  • 2018-08-04
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 2022-08-10
相关资源
最近更新 更多