我有一个数据框“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和编程都很陌生 - 我是一名法学教授,试图分析法庭数据......我的帮助表示赞赏。谢谢。 肯
答案 0 :(得分: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)))
答案 1 :(得分:2)
我对滚动计算没有多少经验,但是......
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)