R 如何从特定的工作日开始,以7天为间隔对数据进行分组

R 如何从特定的工作日开始,以7天为间隔对数据进行分组,r,group-by,R,Group By,我已经为此挣扎了一段时间。如何在7天的时间间隔内对数据进行分组 基本上,我试图在周五开始的“一周”内进行分组。日期是在星期五和下一个星期四之间随机选择的。由于人为错误,每个周期的观察次数可能不完全相同,尽管通常应为7次。有可能缺少一到两个完整的周期 理想的方法似乎是为每个日期确定一个期间(即从星期五开始的一周)编号,然后将其添加到另一列的数据集中 > str(data) 'data.frame': 55 obs. of 15 variables: $ id :

我已经为此挣扎了一段时间。如何在7天的时间间隔内对数据进行分组

基本上,我试图在周五开始的“一周”内进行分组。日期是在星期五和下一个星期四之间随机选择的。由于人为错误,每个周期的观察次数可能不完全相同,尽管通常应为7次。有可能缺少一到两个完整的周期

理想的方法似乎是为每个日期确定一个期间(即从星期五开始的一周)编号,然后将其添加到另一列的数据集中

> str(data)
'data.frame':   55 obs. of  15 variables:

 $ id           : num  7 8 9 10 11 12 13 16 17 18 ... 
 $ q_0001       : Factor w/ 2 levels "Yes","No": 1 1 1 1 1 1 2 1 1 1 ...
 $ q_0002       : Factor w/ 2 levels "Yes","No": 2 1 1 1 2 2 2 2 2 2 ...
 $ q_0003       : Factor w/ 2 levels "Yes","No": 2 2 2 1 2 2 2 2 2 2 ...
 $ q_0004       : Factor w/ 2 levels "Yes","No": 1 1 1 1 1 1 2 2 2 2 ...
 $ Assm_Date    : Date, format: "2014-01-04" "2014-01-08" "2014-01-08" ...
为了清楚起见,我删去了不相关的变量

背景:我们正在进行一项医疗服务改进项目。从周五到下周四,我们随机进行了7次观测,包括。因此,我需要在这7天内对问题的答案进行分组(即在问题1至4中计算“是”)

数据产生方式:我们正在研究医院病例中的4个质量参数(大约每周40到50例)。在前7天的案例中,使用RNG选择了7个。从逻辑上讲,我们可以在周五完成这项工作,因此这段时间是从上周五到周四(即昨天)。我们通过LimeSurvey界面输入数据。对于每个选定的案例,我们输入案例日期(关联日期)和4个问题(q_0001至q_0004)的是/否答案。我需要每周做一次手术,因为我们会做一个每周进度表

下面建议的
*lubridate*week()
方法会很好

data$week_starting_friday <- week(data$Assm_Date)+5 

data$week\u start\u friday您的意思是,您在
Assm\u Date
中有七个不同的日期,并且您想对每个日期和每个问题的所有“是”进行合计吗?在这种情况下,您可以使用
plyr
软件包中的
daply

require(plyr)
dapply(data, .(Assm_Date), summarize, 
  q1 = sum(q_0001 == "Yes", na.rm = TRUE),
  q2 = sum(q_0002 == "Yes", na.rm = TRUE))

假设您在数据帧df中有一组随机日期:

  #Create random dates
  df <- data.frame(date=rep(seq.POSIXt(as.POSIXct("2011-11-01 11:23"), by="day", length.out=4), each=4), var=rnorm(4))
  df <- rbind(df,data.frame(date=rep(seq.POSIXt(as.POSIXct("2011-11-02 01:20"), by="day", length.out=4), each=4), var=rnorm(4)))
  df <- rbind(df,data.frame(date=rep(seq.POSIXt(as.POSIXct("2011-11-02 05:13"), by="day", length.out=4), each=4), var=rnorm(4)))
  df <- rbind(df,data.frame(date=rep(seq.POSIXt(as.POSIXct("2011-11-03 18:22"), by="day", length.out=4), each=4), var=rnorm(4)))
  df <- rbind(df,data.frame(date=rep(seq.POSIXt(as.POSIXct("2011-11-11 16:44"), by="day", length.out=4), each=4), var=rnorm(4)))
  df <- rbind(df, data.frame(date=rep(seq.POSIXt(as.POSIXct("2011-11-11 02:26"), by="day", length.out=4), each=4), var=rnorm(4)))
  df <- rbind(df,data.frame(date=rep(seq.POSIXt(as.POSIXct("2011-11-12 13:13"), by="day", length.out=4), each=4), var=rnorm(4)))
  df <- rbind(df,data.frame(date=rep(seq.POSIXt(as.POSIXct("2011-11-13 19:33"), by="day", length.out=4), each=4), var=rnorm(4)))
在您的示例中,请尝试以下操作:

  split(data, cut(strptime(paste(df$Assm_Date), format="%F"),"7 day"))

结合库巴的建议,我认为你是在寻找每周的观察结果,而不是每天的

library(lubridate)
library(plyr)
data <- ...

# this defaults to Sunday, but adding 5 will push it to Friday
data$week_starting_friday <- week(data$Assm_Date) + 5

# isolate non-question columns
notQuestionColumns <- data[, !grepl('q_', names(data))]

# convert Yes/No answers to binary
data <- ifelse(data[, grepl('q_', names(data))] == 'Yes', 1, 0)

# combine non-question columns and data
data <- data.frame(notQuestionColumns, data)

# aggregate answers by week
ddply(data, .(week_starting_friday), numcolwise(sum))
库(lubridate)
图书馆(plyr)

数据以下是一个基本解决方案:

# Assumes data is sorted by date
data$week <- cumsum(weekdays(data$Assm_Date) == "Friday")  # highlight week
aggregate(. ~ week, data, function(x) sum(x==1))[-ncol(data)]

非基本可能性:

如果您使用诸如
data.table
(或
dplyr
)之类的附加软件包,您可以获得fancier:

library(data.table)
data.table(data)[, 
  c(
    list(Dates=paste(range(format(Assm_Date, "%b-%d")), collapse=" to ")),
    lapply(
      .SD[, -5, with=F], 
      function(x) paste(names(table(x)), table(x), collapse=";"))
  ),
  by=week
]
产生:

   week            Dates     q_0001     q_0002     q_0003     q_0004
1:    0 Jan-01 to Jan-02 No 1;Yes 1 No 2;Yes 0 No 1;Yes 1 No 1;Yes 1
2:    1 Jan-03 to Jan-09 No 4;Yes 3 No 1;Yes 6 No 3;Yes 4 No 3;Yes 4
3:    2 Jan-10 to Jan-16 No 2;Yes 5 No 2;Yes 5 No 1;Yes 6 No 4;Yes 3
4:    3 Jan-17 to Jan-23 No 4;Yes 3 No 3;Yes 4 No 3;Yes 4 No 4;Yes 3
5:    4 Jan-24 to Jan-30 No 5;Yes 2 No 3;Yes 4 No 3;Yes 4 No 2;Yes 5
6:    5 Feb-01 to Jan-31 No 5;Yes 2 No 4;Yes 3 No 2;Yes 5 No 2;Yes 5
7:    6 Feb-07 to Feb-13 No 4;Yes 3 No 4;Yes 3 No 5;Yes 2 No 5;Yes 2
8:    7 Feb-14 to Feb-20 No 6;Yes 1 No 4;Yes 3 No 3;Yes 4 No 5;Yes 2
9:    8 Feb-21 to Feb-24 No 2;Yes 2 No 1;Yes 3 No 1;Yes 3 No 3;Yes 1
以下是我使用的数据:

set.seed(1)
data <- as.data.frame(
  c(
    setNames(replicate(4, sample(c("Yes", "No"), 55, r=T), s=F), paste0("q_000", 1:4)),
    Assm_Date=list(seq(as.Date("2014-01-01"), by="+1 day", len=55))
) )
set.seed(1)
数据由于建议,我看了一个起初看起来很难理解的例子。一旦我明白了,它是非常简单和优雅的。我的问题的解决方案:

data$Assmt_Week <- 1+ as.numeric(data$Assm_Date - as.Date("2014-01-03")) %/% 7

data$Assmt_Week也许你能找到一些帮助。在理解这是如何工作的过程中遇到一些问题后,我调整了它,并且-它工作了!!!我必须输入正确的开始日期,而不是样本中的第一个日期,但这是一个非常优雅和简单的解决方案——大多数都是正确的算法和正确的数据类型,使用的是基本知识,即时间是如何在不间断的几周内计算的。非常感谢,在我把所有数据都放进去之后,我会把答案全部放进去<代码>作为数字(数据$Assm_Date-as.Date(“2014-01-03”))%/%7
非常感谢,事实上我正在尝试汇总每周观察结果。我正在尝试这种方法,我发现(x)+5周似乎将5添加到了日期x的周数中,而不是从星期五开始。因此,我在$week_starting_Friday数据中得到了一个常规的周数+5作为值,而不是从周五开始的周数。我想如果我做一些修改,它应该会起作用:数据$week_starting_Friday好的,不,这不太有效。不是每天+5天都能进入正确的周期。我已经检查了原始数据——从周五开始,所有日期都符合每周7次的观察结果。如果使用上面的公式,我们可以得到2次观察的周数,以及9次左右的周数。我真的需要重新创建原来的7天垃圾箱-星期五+6天(或从星期五开始的7天,包括星期五或星期五到下星期四)。嘿,很抱歉误解了提问。。。
lubridate
中的另一个很棒的功能是
floor\u date
floor_date(data$Assm_date)+5是否有效?基本解决方案让我深入了解了一些R函数,看起来非常优雅。不幸的是,结果并不正确。由于目前的数据集非常小,我在电子表格中对此进行了测试。分组总数是正确的,但分为7天的时间段是不正确的-上一个“星期”有大部分观察结果。更奇特的解决方案也不能给出正确的结果,这似乎也是由于分组不正确,但在这种情况下,我对解决方案和如何补救的理解有点遥不可及。@r0berts,您确定数据是按日期排序的吗?此外,如果您查看聚合前添加的“周”列,它是否有意义(即每7天更改一次)?没有可复制的数据,我很难调试。感谢您的关注,我添加了一个链接到我用于测试的数据样本。共有55项观察结果(1项是肯定的,2项是否定的),日期是正确的,我在Calc中手动添加了一个名为“Week”的列,以显示原始日期在从周五开始的7天内。我确实在加载前按日期对csv进行了排序,并且在加载后也对数据帧进行了排序。如果我没有弄错的话,我会认为你的方法添加的列应该有相同的数字。这很好,但不知为什么分组是不正确的。最可能的原因是,在第一个时期,第一次观测不是在星期五,而是在星期六。但这是一个很好的例子,可以在7天的时间间隔内分割数据。Thanksys.一个快速的、相当老套的解决方法是向数据集中添加一个人工的星期五“异常值”数据点(例如Fri 1-5-1900)。这将使拆分与星期五对齐,第一个拆分可以安全忽略。谢谢,不,我有7个固定的7天周期内的随机观察日期,每个日期从星期五开始。我需要在这7天内总结数据。
set.seed(1)
data <- as.data.frame(
  c(
    setNames(replicate(4, sample(c("Yes", "No"), 55, r=T), s=F), paste0("q_000", 1:4)),
    Assm_Date=list(seq(as.Date("2014-01-01"), by="+1 day", len=55))
) )
data$Assmt_Week <- 1+ as.numeric(data$Assm_Date - as.Date("2014-01-03")) %/% 7
dvec <- as.Date("2001-04-01")+0:90
dweek <- as.numeric(dvec-dvec[1]) %/% 7