【发布时间】:2019-01-11 05:31:27
【问题描述】:
我有一个要求,我有一个包含大约 200 万 条记录的庞大数据库,其中我需要根据来自另一个数据框的信息为某些特定变量创建带有代码的新变量。所以情况是——
- 有一个参考数据库,其中包含 IBD (inter1) 变量的截止值
- 有一个向量,其中包含需要根据截止值创建代码的变量列表 (v0int)
- 需要在其上创建具有基于截止值的代码的新变量的主数据库 (smpl)
例如,对于 IBD 5 和变量 var1a,请考虑 inter1 文件中的以下信息 -
IBD var1a
5 11
5 18
5 30
5 63
基于上述信息,我想在 smpl 数据框中创建一个新变量,这样 -
if smpl$var1a <= 11 then var1a_INT = 1
if smpl$var1a > 11 & smpl$var1a <= 18 then var1a_INT = 2
if smpl$var1a > 18 & smpl$var1a <= 30 then var1a_INT = 3
if smpl$var1a > 30 & smpl$var1a <= 63 then var1a_INT = 4
if smpl$var1a > 63 then var1a_INT = 5
由于这需要通过 IBD 为多个变量完成,因此我使用 for 循环 编写了我的代码。我的示例代码如下 -
set.seed(1200)
IBD <- sort(rep(1:10,4))
var1a <- c()
var2a <- c()
var3a <- c()
var4a <- c()
var5a <- c()
j=10
for (i in 1:10){
set.seed(1200)+(j*i)
var1 <- sort(sample(1:(10*i),4))
var2 <- sort(sample(11:(15*i),4))
var3 <- sort(sample(10:(17*i),4))
var4 <- sort(sample(11:(19*i),4))
var5 <- sort(sample(10:(16*i),4))
var1a <- c(var1a,var1)
var2a <- c(var2a,var2)
var3a <- c(var3a,var3)
var4a <- c(var4a,var4)
var5a <- c(var5a,var5)
}
inter1 <- data.frame(IBD,var1a,var2a,var3a,var4a,var5a)
sm=5000
ID <- seq(1:sm)
IBD <- sample(1:10,sm,replace = T)
CELL <- sample(1001:9999,sm)
var1a <- sample(1:150,sm,replace = T)
var2a <- sample(1:200,sm,replace = T)
var3a <- sample(1:200,sm,replace = T)
var4a <- sample(1:350,sm,replace = T)
var5a <- sample(1:250,sm,replace = T)
var6a <- sample(1:150,sm,replace = T)
var7a <- sample(1:250,sm,replace = T)
var8a <- sample(1:350,sm,replace = T)
var9a <- sample(1:450,sm,replace = T)
loc <- sample(1:20,sm,replace = T)
bill <- sample(1:2,sm,replace = T)
smpl <- data.frame(ID,IBD,CELL,var1a,var2a,var3a,var4a,var5a,var6a,var7a,var8a,var9a,loc,bill)
v0int <- c("var1a","var2a","var3a","var4a","var5a")
df_smpl <- data.frame(matrix(NA,nrow = 0,ncol = ncol(smpl)))
#l=1
start_time <- Sys.time()
for (l in (unique(inter1$IBD))){
df1 <- subset(smpl,IBD == l)
for (k in 1:length(v0int)){
#k=1
q0 <- v0int[k]
q1 <- sort(inter1[inter1$IBD == l,q0])
for (m in 1:nrow(df1)){
#print(q0)
#print(l)
#print(m)
if (length(q1) == 0){
df1[m,paste0(q0,"_INT")]=NA
} else if(length(q1) == 1){
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] <= q1[1]) df1[m,paste0(q0,"_INT")]=1
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] > q1[1]) df1[m,paste0(q0,"_INT")]=2
} else if(length(q1) == 2){
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] <= q1[1]) df1[m,paste0(q0,"_INT")]=1
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] > q1[1] & df1[m,q0] <= q1[2]) df1[m,paste0(q0,"_INT")]=2
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] > q1[2]) df1[m,paste0(q0,"_INT")]=3
} else if(length(q1) == 3) {
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] <= q1[1]) df1[m,paste0(q0,"_INT")]=1
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] > q1[1] & df1[m,q0] <= q1[2]) df1[m,paste0(q0,"_INT")]=2
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] > q1[2] & df1[m,q0] <= q1[3]) df1[m,paste0(q0,"_INT")]=3
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] > q1[3]) df1[m,paste0(q0,"_INT")]=4
} else if(length(q1) == 4) {
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] <= q1[1]) df1[m,paste0(q0,"_INT")]=1
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] > q1[1] & df1[m,q0] <= q1[2]) df1[m,paste0(q0,"_INT")]=2
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] > q1[2] & df1[m,q0] <= q1[3]) df1[m,paste0(q0,"_INT")]=3
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] > q1[3] & df1[m,q0] <= q1[4]) df1[m,paste0(q0,"_INT")]=4
if(!is.null(df1[m,q0]) & df1[m,"IBD"]==l & df1[m,q0] > q1[4]) df1[m,paste0(q0,"_INT")]=5
}
}
#q1 <- NULL
}
df_smpl <- rbind(df_smpl,df1)
#q0 <- NULL
}
time_taken <- as.numeric(difftime(Sys.time(), start_time, units = 'secs'))
对于 5000 条记录的样本数据,这在我的机器上需要 5.859623 秒,它有 16GB RAM SSD HDD 和 2 核。
当尝试处理具有 500000 条记录的数据时,这需要 752.7261 秒。
我的实际数据有 200 万 条记录,我需要以迭代方式多次运行它,因此所需时间会大大增加。
在进行一些搜索时,我了解到 data.table 速度更快,并且可以节省大量时间。我不太了解 data.table,希望在这方面寻求您的帮助。
如果我们可以优化这段代码,那将是一个巨大的帮助和节省大量的时间。
【问题讨论】:
-
您好,我认为您需要提供有关您当前环境的更多信息 - 目前数据在哪里?
-
@MandyShaw,感谢您对此进行调查。数据以 csv 格式本地存在于我的机器中。
-
@Roland,请您指导一下您是如何正确发布帖子的。我的意思是我缩进了我的代码,它不允许我发布,而且你似乎编辑了几行。你到底做了什么,它起作用了
-
嗨,我自己(不是 R 人)无法查看它,但知道数据在哪里无疑会对其他人有所帮助。但即使我可以看到在 csv 文件中处理大量数据肯定会很慢,您将需要一个专门的数据存储。
-
你可以看到what I did,但是不知道哪部分解决了你报告的问题。可能删除多余的反引号?
标签: r performance for-loop optimization data.table