【发布时间】:2019-05-12 00:18:50
【问题描述】:
我正在创建一个面板数据框。这是一组学校。对于这个面板,我想合并第一个最近的气象站,然后是第二个、第三个等,直到第 10 个最近的气象站。我写了一个循环,对不同的变量执行此操作:最高温度、最低温度、降水等。我遇到的问题是,由于内存不足,我似乎在此循环内的某处分配了不必要的内存。
我知道我有足够的内存来创建面板,因为我已经在没有循环的情况下做了一次。我正在使用 8GB RAM 的 64 位 Windows 上工作。我有 2010-2015 年期间 7800 所学校和 800 个气象站的样本。
这是一个可重复的示例,仅包含 5 所学校、10 个气象站和 2 个月的数据,并且仅匹配 3 个最近的气象站。真实的例子是 7800 所学校、800 个气象站、5 年的数据并匹配 10 个最近的气象站。
library(data.table)
Dist_Temp_Max<-data.frame(ID_School=seq(1:5),ID_Station_1=floor(runif(5, min=0, max=10)),Dist_1=floor(runif(5, min=0, max=10)),
ID_Station_2=floor(runif(5, min=0, max=10)),Dist_2=floor(runif(5, min=11, max=100)),
ID_Station_3=floor(runif(5, min=0, max=10)),Dist_3=floor(runif(5, min=101, max=200)))
Dist_Temp_Min<-data.frame(ID_School=seq(1:5),ID_Station_1=floor(runif(5, min=0, max=10)),Dist_1=floor(runif(5, min=0, max=10)),
ID_Station_2=floor(runif(5, min=0, max=10)),Dist_2=floor(runif(5, min=11, max=100)),
ID_Station_3=floor(runif(5, min=0, max=10)),Dist_3=floor(runif(5, min=101, max=200)))
Dist_Prec<-data.frame(ID_School=seq(1:5),ID_Station_1=floor(runif(5, min=0, max=10)),Dist_1=floor(runif(5, min=0, max=10)),
ID_Station_2=floor(runif(5, min=0, max=10)),Dist_2=floor(runif(5, min=11, max=100)),
ID_Station_3=floor(runif(5, min=0, max=10)),Dist_3=floor(runif(5, min=101, max=200)))
years<-seq.Date(as.Date("2014-01-01"),as.Date("2015-02-28"),by="1 day")
Weather_Data<-data.frame(ID_School=seq(1:5))
Weather_Data<-expand.grid(Weather_Data$ID_School,years)
names(Weather_Data)<-c("ID_Station","Date")
Weather_Data$Temp_Max_T<-runif(nrow(Weather_Data), min=10, max=40)
Weather_Data$Temp_Min_T<-Weather_Data$Temp_Max-10
Weather_Data$Prec_T<-floor(runif(nrow(Weather_Data),min=0, max=10))
Weather_Data$Cod_Merge<-paste(Weather_Data$ID_Station,Weather_Data$Date,sep="-")
#Add Values per Station
var_list<-c("Temp_Max","Temp_Min","Prec")
for (i in var_list) {
dist<-paste0("Dist_",i)
dist<-get(dist)
dist<-as.data.frame(subset(dist,!is.na(dist$ID_Station_1)))
matr<-dist[c("ID_School","ID_Station_1","Dist_1")]
matr<-setDT(matr)[, list(Date=years,ID_Station_1=ID_Station_1,Dist_1=Dist_1) , ID_School]
matr$Cod_Merge<-paste(matr$ID_Station_1,matr$Date,sep="-")
matr<-as.data.frame(matr[,c("Cod_Merge","ID_School","Date","ID_Station_1","Dist_1")])
matr<-merge(matr,Weather_Data[c("Cod_Merge",paste0(i,"_T"))],by="Cod_Merge",all.x=T)
matr$Cod_Merge<-paste(matr$ID_School,matr$Date,sep="-")
names(matr)[6]<-paste0(i,"_T_1")
Sys.sleep(0.1)
print(i)
for(n in 2:3) {
matr2<-dist[c("ID_School",paste0("ID_Station_",n),paste0("Dist_",n))]
matr2<-subset(dist,!is.na(dist[paste0("ID_Station_",n)]))
matr3<-expand.grid(matr2$ID_School,years)
names(matr3)<-c("ID_School","Date")
matr3<-matr3[order(matr3$ID_School,matr3$Date), ]
matr2<-merge(matr3,matr2,by="ID_School")
rm(matr3)
Sys.sleep(0.1)
print(i)
matr2$Cod_Merge<-paste(matr2[,paste0("ID_Station_",n)],matr2$Date,sep="-")
matr2<-matr2[c("Cod_Merge","ID_School","Date",paste0("ID_Station_",n),paste0("Dist_",n))]
matr2<-merge(matr2,Weather_Data[,c("Cod_Merge",paste0(i,"_T"))],by="Cod_Merge",all.x=T)
matr2$Cod_Merge<-paste(matr2$ID_School,matr2$Date,sep="-")
names(matr2)[6]<-paste0(i,"_T_",n)
matr<-merge(matr,matr2[,c("Cod_Merge",
paste0("ID_Station_",n),
paste0("Dist_",n),
paste0(i,"_T_",n))],
by="Cod_Merge",all.x=T)
Sys.sleep(0.1)
print(i)
}
assign(paste0("Mat_Dist_",i),matr)
}
任何帮助将不胜感激。
解决方案
对于任何感兴趣的人,我在第二个循环中遗漏了几个逗号:
library(data.table)
Dist_Temp_Max<-data.frame(ID_School=seq(1:5),ID_Station_1=floor(runif(5, min=0, max=10)),Dist_1=floor(runif(5, min=0, max=10)),
ID_Station_2=floor(runif(5, min=0, max=10)),Dist_2=floor(runif(5, min=11, max=100)),
ID_Station_3=floor(runif(5, min=0, max=10)),Dist_3=floor(runif(5, min=101, max=200)))
Dist_Temp_Min<-data.frame(ID_School=seq(1:5),ID_Station_1=floor(runif(5, min=0, max=10)),Dist_1=floor(runif(5, min=0, max=10)),
ID_Station_2=floor(runif(5, min=0, max=10)),Dist_2=floor(runif(5, min=11, max=100)),
ID_Station_3=floor(runif(5, min=0, max=10)),Dist_3=floor(runif(5, min=101, max=200)))
Dist_Prec<-data.frame(ID_School=seq(1:5),ID_Station_1=floor(runif(5, min=0, max=10)),Dist_1=floor(runif(5, min=0, max=10)),
ID_Station_2=floor(runif(5, min=0, max=10)),Dist_2=floor(runif(5, min=11, max=100)),
ID_Station_3=floor(runif(5, min=0, max=10)),Dist_3=floor(runif(5, min=101, max=200)))
years<-seq.Date(as.Date("2014-01-01"),as.Date("2015-02-28"),by="1 day")
Weather_Data<-data.frame(ID_School=seq(1:5))
Weather_Data<-expand.grid(Weather_Data$ID_School,years)
names(Weather_Data)<-c("ID_Station","Date")
Weather_Data$Temp_Max_T<-runif(nrow(Weather_Data), min=10, max=40)
Weather_Data$Temp_Min_T<-Weather_Data$Temp_Max-10
Weather_Data$Prec_T<-floor(runif(nrow(Weather_Data),min=0, max=10))
Weather_Data$Cod_Merge<-paste(Weather_Data$ID_Station,Weather_Data$Date,sep="-")
#Add Values per Station
var_list<-c("Temp_Max","Temp_Min","Prec")
for (i in var_list) {
dist<-paste0("Dist_",i)
dist<-get(dist)
dist<-as.data.frame(subset(dist,!is.na(dist$ID_Station_1)))
matr<-dist[c("ID_School","ID_Station_1","Dist_1")]
matr<-setDT(matr)[, list(Date=years,ID_Station_1=ID_Station_1,Dist_1=Dist_1) , ID_School]
matr$Cod_Merge<-paste(matr$ID_Station_1,matr$Date,sep="-")
matr<-as.data.frame(matr[,c("Cod_Merge","ID_School","Date","ID_Station_1","Dist_1")])
matr<-merge(matr,Weather_Data[c("Cod_Merge",paste0(i,"_T"))],by="Cod_Merge",all.x=T)
matr$Cod_Merge<-paste(matr$ID_School,matr$Date,sep="-")
names(matr)[6]<-paste0(i,"_T_1")
Sys.sleep(0.1)
print(i)
for(n in 2:3) {
matr2<-dist[c("ID_School",paste0("ID_Station_",n),paste0("Dist_",n))]
matr2<-subset(dist,!is.na(dist[paste0("ID_Station_",n)]))
matr3<-expand.grid(matr2$ID_School,years)
names(matr3)<-c("ID_School","Date")
matr3<-matr3[order(matr3$ID_School,matr3$Date), ]
matr2<-merge(matr3,matr2,by="ID_School")
rm(matr3)
Sys.sleep(0.1)
print(i)
matr2$Cod_Merge<-paste(matr2[,paste0("ID_Station_",n)],matr2$Date,sep="-")
matr2<-matr2[,c("Cod_Merge","ID_School","Date",paste0("ID_Station_",n),paste0("Dist_",n))]
matr2<-merge(matr2,Weather_Data[,c("Cod_Merge",paste0(i,"_T"))],by="Cod_Merge",all.x=T)
matr2$Cod_Merge<-paste(matr2$ID_School,matr2$Date,sep="-")
names(matr2)[6]<-paste0(i,"_T_",n)
matr<-merge(matr,matr2[,c("Cod_Merge",
paste0("ID_Station_",n),
paste0("Dist_",n),
paste0(i,"_T_",n))],
by="Cod_Merge",all.x=T)
Sys.sleep(0.1)
print(i)
}
assign(paste0("Mat_Dist_",i),matr)
}
【问题讨论】:
-
我无法真正理解这一点,因为似乎发生了很多事情。你能简化吗?您的代码似乎很难理解。您能否提供一个能够运行您的代码的最小示例?
-
您不需要为示例数据重新创建 1700 万行...现在就看看。您实际上收到了宽格式的天气数据帧并分开了吗?
-
是的,它们是宽格式的。这是一项简单的任务,但是当我将代码转移到循环中时,我的内存不足。
-
我正在尝试帮助您重写您的流程,但要这样做,我需要了解您在做什么。你告诉我你这样做的内存不足。在我看来,您不应该合并这么多行并且有更好的方法。如果您不告诉我,我无法帮助您到达那里,“我从这 3 个数据框开始。COD 意味着这个。对于每一天,对于每所学校,我需要将天气信息放在它旁边以获得顶部10 个站” --- 当我无法理解您想要的结果时,我不知道如何提供帮助
-
您的 expand.grid 函数是错误的根源。我想弄清楚你为什么要使用它