0

我有一个数据框“x”,有 590 万行和 4 列:idnumber/integer、compdate/integer 和 Judge/character,代表在行政法院完成的个别案件。数据是从 stata 数据集导入的,日期字段以整数形式出现,这对我来说很好。我想通过计算法官在相关案件完成日期的 30 天窗口内完成的案件数量来创建案件量变量。

这是前 34 行数据:

idnumber    compdate    judge
1   9615    JVC
2   15316   BAN
3   15887   WLA
4   11968   WFN
5   15001   CLR
6   13914   IEB
7   14760   HSD
8   11063   RJD
9   10948   PPL
10  16502   BAN
11  15391   WCP
12  14587   LRD
13  10672   RTG
14  11864   JCW
15  15071   GMR
16  15082   PAM
17  11697   DLK
18  10660   ADP
19  13284   ECC
20  13052   JWR
21  15987   MAK
22  10105   HEA
23  14298   CLR
24  18154   MMT
25  10392   HEA
26  10157   ERH
27  9188    RBR
28  12173   JCW
29  10234   PAR
30  10437   ADP
31  11347   RDW
32  14032   JTZ
33  11876   AMC
34  11470   AMC

这就是我想出的。因此,对于每条记录,我都会为该特定法官获取数据的子集,然后对 30 天窗口中决定的案例进行子集化,然后将子集化数据帧中向量的长度分配给主题案例的 caseload 变量,如下:

for(i in 1:length(x$idnumber)){
  e<-x$compdate[i]
  f<-e-29
  a<-x[x$judge==x$judge[i] & !is.na(x$compdate),]
  b<-a[a$compdate<=e & a$compdate>=f,]
  x$caseload[i]<-length(b$idnumber)
}

它正在工作,但需要很长时间才能完成。我怎样才能优化这个或更容易做到这一点。抱歉,我对 r 和编程很陌生——我是一名试图分析法庭数据的法学教授……感谢您的帮助。谢谢。肯

4

2 回答 2

3

您不必遍历每一行。您可以一次对整个列进行操作。首先,创建一些数据:

# Create some data.
n<-6e6 # cases
judges<-apply(combn(LETTERS,3),2,paste0,collapse='') # About 2600 judges
set.seed(1)
x<-data.frame(idnumber=1:n,judge=sample(judges,n,replace=TRUE),compdate=Sys.Date()+round(runif(n,1,120)))

现在,您可以制作一个滚动窗口函数,并在每个判断上运行它。

# Sort
x<-x[order(x$judge,x$compdate),]
# Create a little rolling window function.
rolling.window<-function(y,window=30) seq_along(y) - findInterval(y-window,y)
# Run the little function on each judge.
x$workload<-unlist(by(x$compdate,x$judge,rolling.window)))
于 2013-10-06T19:59:45.633 回答
2

我对滚动计算没有太多经验,但是...

  • 每天计算这个,而不是每个案例(因为同一天的案例是相同的)。
  • 计算病例数的累计总和,然后取该总和的当前值与 31 天前(或min{daysAgo:daysAgo>30}由于不是每天都解决病例)的总和值的差值。

使用 data.table 可能是最快的。这是我的尝试,使用@nograpes 模拟数据。评论以#.

require(data.table)
DT <- data.table(x)
DT[,compdate:=as.integer(compdate)]
setkey(DT,judge,compdate)

# count cases for each day
ldt <- DT[,.N,by='judge,compdate']
# cumulative sum of counts
ldt[,nrun:=cumsum(N),by=judge]
# see how far to look back
ldt[,lookbk:=sapply(1:.N,function(i){
    z       <-  compdate[i]-compdate[i:1]
    older   <-  which(z>30)
    if (length(older)) min(older)-1L else as(NA,'integer')
}),by=judge]
# compute cumsum(today) - cumsum(more than 30 days ago)
ldt[,wload:=list(sapply(1:.N,function(i)
    nrun[i]-ifelse(is.na(lookbk[i]),0,nrun[i-lookbk[i]])
))]

在我的笔记本电脑上,这需要不到一分钟的时间。运行此命令以查看一位法官的输出:

print(ldt['XYZ'],nrow=120)
于 2013-10-06T23:50:15.897 回答