这是一个玩具数据。
library(data.table)
rowlength<-100000
set.seed(10)
Nametypes<-c("A1","B2","C3","D4","E5","F6","G7");
DT<-data.table(DTName1 = sample(Nametypes,rowlength,replace = TRUE),DTName2 = sample(Nametypes,rowlength,replace = TRUE),Criteria1=round(runif(rowlength,min = 0,max = 1)),
Numeric1=rnorm(rowlength,mean = 1,sd = 100),
bins=round(runif(rowlength,min = 1,max = 1e9)))
values<-c(0,2,5,7,9,10,12,15,18,20,25,30,35,50,100,150,200,500,Inf)*1e5;
binL<-values[-length(values)];binU<-values[-1];
我想完全按照下面提到的那样进行:一个涉及计算总和,另一个涉及计数,两者都具有多个标准。
Input1<-"DTName1";
Input2<-"Numeric1";
sapply(Nametypes, \(j){cbind(sapply(1: 19,\(i)sum(DT[Criteria1==1 & bins>= binL[i] & bins < binU[i] & get(Input1)== j, .(get(Input2))])))})
sapply(Nametypes, \(j){cbind(sapply(1: 19,\(i)nrow(DT[Criteria1==1 & bins>= binL[i] & bins < binU[i] & get(Input1)== j, .(get(Input2))])))})
但是,由于处理速度慢,我的代码效率极低。在我的玩具数据中,我只使用了 10 万个条目,但它可能会扩展到 500 万个。
1.如果不满足条件,我需要将值显示为零。 2.请仅使用data.table包。 3.Input1 和 Input2 可能会有所不同,因为它们来自外部源,这就是我使用
get
函数的原因。我不确定是否应该避免这种情况。欢迎替代方案。
我们可以像这样使用
tapply
和 table
:
DT[Criteria1 == 1, tapply(.SD[[Input2]], .(cut(bins, values, include.lowest = TRUE),
.SD[[Input1]]), sum, .default = 0)]
DT[Criteria1 == 1, table(cut(bins, values, include.lowest = TRUE), .SD[[Input1]])]