Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在R中查找连续两周的第一个日期(数据表)_R_Date_Indexing_Data.table - Fatal编程技术网

在R中查找连续两周的第一个日期(数据表)

在R中查找连续两周的第一个日期(数据表),r,date,indexing,data.table,R,Date,Indexing,Data.table,我试图找到第一个日期(每组),其中一周和下一周都有记录。周不从周一开始,但定义为七天 假设某个日期是第一周的第一天,我将尝试测试第二个“周”中的日期记录数是否大于1 library(data.table) dt=data.table(date=c(1,9,10,15,18,3,4,7,7,19,21,27), group=c(rep("a", 5), rep("b",7))) > dt date group 1: 1 a 2:

我试图找到第一个日期(每组),其中一周和下一周都有记录。周不从周一开始,但定义为七天

假设某个日期是第一周的第一天,我将尝试测试第二个“周”中的日期记录数是否大于1

library(data.table)

dt=data.table(date=c(1,9,10,15,18,3,4,7,7,19,21,27),
              group=c(rep("a", 5), rep("b",7)))

> dt
    date group
 1:    1     a
 2:    9     a
 3:   10     a
 4:   15     a
 5:   18     a
 6:    3     b
 7:    4     b
 8:    7     b
 9:    7     b
10:   19     b
11:   21     b
12:   27     b
适用于data.frame的for循环如下所示:

df <- data.frame(dt)

for(i in 1:length(df$date)){
  df$count[i] <- sum(df$date >= df$date[i] + 7 &
  df$date < df$date[i] + 14 &
  df$group == df$group[i])
}

> df
   date group  count
1     1     a      2
2     9     a      1
3    10     a      1
4    15     a      0
5    18     a      0
6     3     b      0
7     4     b      0
8     7     b      1
9     7     b      1
10   19     b      1
11   21     b      0
12   27     b      0
dt[, date/sum(date), by=group]

问题是,我不明白如何创建一个对data.table有效的索引函数。非常感谢您的帮助。

为什么不使用您创建的循环

dt[,count:=date]
for(i in 1:length(dt$date)){
    set(dt,i,3L, sum(dt$date >= dt$date[i] + 7 &
                           dt$date < dt$date[i] + 14 &
                           dt$group == dt$group[i]))
}
dt
#    date group count
# 1:    1     a     2
# 2:    9     a     1
# 3:   10     a     1
# 4:   15     a     0
# 5:   18     a     0
# 6:    3     b     0
# 7:    4     b     0
# 8:    7     b     1
# 9:    7     b     1
#10:   19     b     1
#11:   21     b     0
#12:   27     b     0
dt[,count:=日期]
对于(1中的i:长度(dt$日期)){
集合(dt,i,3L,总和)(dt$date>=dt$date[i]+7&
dt$日期
by
的工作方式类似于
tapply
。您通过列(例如组)中的变量将
data.table
拆分为mini data.tables,在整个mini data.table上执行一个函数,为每个mini data.table返回一些内容,然后组合返回的内容以生成输出。

我认为这是可行的:

# set the key for the rolling merges
setkey(dt, group, date)

# find start and end point of the intervals you want
start = dt[J(group, date + 7 ), .I, roll = -Inf, by = .EACHI]$I
end   = dt[J(group, date + 13), .I, roll =  Inf, by = .EACHI]$I

# if start is 0, the first condition is not satisfied, so set count to 0
dt[, count := (start != 0) * (end - start + 1)]

dt
#    date group count
# 1:    1     a     2
# 2:    9     a     1
# 3:   10     a     1
# 4:   15     a     0
# 5:   18     a     0
# 6:    3     b     0
# 7:    4     b     0
# 8:    7     b     1
# 9:    7     b     1
#10:   19     b     1
#11:   21     b     0
#12:   27     b     0

不幸的是@eddi建议的解决方案不再适用于
R 3.1.2
数据。表1.9.4
。由于此错误而失败:

Error in dt[J(group, date + 13), .I, roll = Inf]$.I : 
  $ operator is invalid for atomic vectors
下面的代码可以工作,但使用新的
foverlaps
功能是一个快速而肮脏的解决方法。我确信一定有办法解决滚动联接问题

# Find start and end point of the intervals you want
dt[, start := date + 7]
dt[, end := date + 13]

# Make two data tables for overlapping dates.
dt2 <- dt[, c("group", "start", "end")]
dt[, date2 := date] # copy date (foverlaps need an interval).

# Sort by date and overlap-merge with week ranges.
setkey(dt, group, date, date2)
dt3 <- foverlaps(dt2, dt, by.x=c("group", "start", "end"))

# Count unique values to get number of records in following week.
setkey(dt, group, start, end)
setkey(dt3, group, i.start, i.end)
dt4 <- unique(dt)[dt3]
dt4[, count := ifelse(is.na(i.start), 0L, length(unique(i.start))), by=date]

# Cleaning up.
dt5 <- dt[unique(dt4)]
dt5 <- dt5[, c("date", "group", "count")]

# > dt5
#    date group count
# 1:    1     a     2
# 2:    9     a     1
# 3:   10     a     1
# 4:   15     a     0
# 5:   18     a     0
# 6:    3     b     0
# 7:    4     b     0
# 8:    7     b     1
# 9:    7     b     1
#10:   19     b     1
#11:   21     b     0
#12:   27     b     0
#找到所需间隔的起点和终点
dt[,开始:=日期+7]
dt[,结束:=日期+13]
#为重叠的日期制作两个数据表。

dt2您能否解释更多关于dt[,date/sum(date),by=group]
?你期望什么样的产出?什么是计数?回收去年的代码,不幸的是,这个解决方案不再有效。它抛出一个错误:
dt[J(组,日期+13),.I,roll=Inf]$中的错误。I:$运算符对原子向量无效
。我使用了一种(丑陋的)方法来解决
foverlaps
的问题(参见下面的答案)。必须有一种方法来避免无效运算符错误,但仍然使用滚动联接?@BramVisser修复了-错误(主要)是由于1.9.4在没有明确说明的情况下生成的,这很快。谢谢我知道这很简单,似乎还记得在导入数据时,启动消息中提到了一些关于.EACHI的内容。table。。。我猜关注这些消息是件好事。只需删除该命令末尾的
$.I
。它已经返回了一个向量。浏览v1.9.4 README.md文件中的新闻以了解更改。