R 对数据进行分组的有效方法。按年度列出结果

R 对数据进行分组的有效方法。按年度列出结果,r,data.table,R,Data.table,我正在寻求有关我是否有效使用data.table的建议 我有一个描述事件的数据集,每个事件一行。每行我都有事件发生的日期。现在我只想统计一下每年有多少起事故。我使用下面的代码完成了这项工作,但感觉效率很低。如果您能就如何改进这一点提供任何建议,我将不胜感激。(数据集比下面显示的要大得多,我还需要做其他类似但更复杂的计算) 创建从2000年到2012年底的日期列表: dates <- seq(as.Date("1/1/2000", format="%d/%m/%Y"), as.Date

我正在寻求有关我是否有效使用
data.table
的建议

我有一个描述事件的数据集,每个事件一行。每行我都有事件发生的日期。现在我只想统计一下每年有多少起事故。我使用下面的代码完成了这项工作,但感觉效率很低。如果您能就如何改进这一点提供任何建议,我将不胜感激。(数据集比下面显示的要大得多,我还需要做其他类似但更复杂的计算)

创建从2000年到2012年底的日期列表:

dates <- seq(as.Date("1/1/2000", format="%d/%m/%Y"), 
  as.Date("31/12/2012", format="%d/%m/%Y"), 
  "day")

# Choose one million occurrences on various dates:    

sampleDate <- sample(dates, 1000000, replace=TRUE)

# Create `data.table`, one line per incident:   

library(data.table)
DT.dt <- data.table(Date=sampleDate, incident=1)

# Time how long it takes to count the number of indidents in each year: 

system.time(result <- DT.dt[,count(format(Date,"%Y"))])

user  system elapsed 
11.83    0.10   11.95 

result[1:3,]
x    freq
2000 76930
2001 77101
2002 76666

日期当您使用
数据进行聚合操作(分组)时。表
,尤其是对于大型数据集,您应该将分组依据的字段设置为
(使用
setkeyv(DT,“您的密钥字段”)
,等等)。此外,我不能就这个主题进行明确的讨论,但总体而言,我认为在
数据中使用本机
数据。table::
函数/操作会获得比使用其他包函数(例如
plyr::count
时更好的性能。下面,我制作了一些
数据.table
对象-第一个与您的示例相同;第二个添加了一列
年份
(而不是在函数执行时计算
格式(日期,“%Y”)
),但将
日期
设置为
;第三个与第二个相同,只是它使用
Year
作为
键。我还制作了一些函数(为了方便基准测试),它们以不同的方式进行分组

library(data.table)
library(plyr) # for 'count' function
library(microbenchmark)
##
dates <- seq.Date(
  from=as.Date("2000-01-01"),
  to=as.Date("2012-12-31"),
  by="day")
##
set.seed(123)
sampleDate <- sample(
  dates,
  1e06,
  replace=TRUE)
##
DT.dt <- data.table(
  Date=sampleDate,
  incident=1)
##
DT.dt2 <- copy(DT.dt)
DT.dt2[,Year:=format(Date,"%Y")]
setkeyv(DT.dt2,"Date")
##
DT.dt3 <- copy(DT.dt2)
setkeyv(DT.dt3,"Year")
##
> head(DT.dt,3)
         Date incident
1: 2003-09-27        1
2: 2010-04-01        1
3: 2005-04-26        1
> head(DT.dt2,3)
         Date incident Year
1: 2000-01-01        1 2000
2: 2000-01-01        1 2000
3: 2000-01-01        1 2000
> head(DT.dt3,3)
         Date incident Year
1: 2000-01-01        1 2000
2: 2000-01-01        1 2000
3: 2000-01-01        1 2000

## your original method
f1 <- function(dt)
{
  dt[,count(format(Date,"%Y"))]
}
## your method - using 'Year' column
f1.2 <- function(dt)
{
  dt[,count(Year)]
}
## use 'Date' column; '.N' and 
## 'by=' instead of 'count'
f2 <- function(dt)
{
  dt[,.N,by=format(Date,"%Y")]
}
## use 'Year' and '.N','by='
f3 <- function(dt)
{
  dt[,.N,by=Year]
}
##
Res <- microbenchmark(
  f1(DT.dt),
  f1.2(DT.dt2),
  f1.2(DT.dt3),
  f2(DT.dt2),
  f3(DT.dt3))
##
> Res
Unit: milliseconds
         expr        min         lq     median         uq      max neval
    f1(DT.dt) 478.941767 515.144253 557.428159 585.579862 706.8724   100
 f1.2(DT.dt2)  98.722062 115.588034 126.332104 137.792116 223.4967   100
 f1.2(DT.dt3)  97.475673 118.134788 125.836817 136.136156 238.2697   100
   f2(DT.dt2) 352.767219 373.337958 387.759996 429.301164 542.1674   100
   f3(DT.dt3)   7.912803   8.441159   8.736887   9.685267  76.9629   100

(我在上面调用了
setkeyv(DT.dt3,cols=“Year”)

不确定函数
count
来自何处。
data.table
的方式是:
DT.DT[,.N,by=format(Date,“%Y”)]
。我有一种感觉,这个Q可能是一个重复的,小音符。无需为聚合操作设置密钥。我们喜欢即兴表演。你的基准测试应该包括设置键的时间。我知道post规则说我不能说谢谢。但我没有名声,所以我甚至不能投票支持你的答案。但这是惊人的。谢谢
> DT.dt3[,list(Incidents=sum(incident)),by=Year]
    Year Incidents
 1: 2000     77214
 2: 2001     77385
 3: 2002     77080
 4: 2003     76609
 5: 2004     77197
 6: 2005     76994
 7: 2006     76560
 8: 2007     76904
 9: 2008     76786
10: 2009     76765
11: 2010     76675
12: 2011     76868
13: 2012     76963