我正在寻找一种快速高效的方法来计算下面描述的问题。任何帮助都将不胜感激,谢谢提前!
我有两个非常大的csv文件,它们对同一个对象有不同的信息,但在最后的计算中,我需要不同表中的所有属性。我正在努力计算大量变电站的负荷,首先我有一个独特的变电站清单;
Unique_Substations <- data.frame(Name = c("SubA", "SubB", "SubC", "SubD"))
在另一个列表中,我有关于这些变电站背后的客户的信息;
Customer_Information <- data.frame(
Customer = 1001:1010,
SubSt_Nm = sample(unique(Unique_Substations$Name), 10, replace = TRUE),
HouseHoldType = sample(1:2, 10, replace = TRUE)
)
在另一个列表中,我有关于这些客户屋顶上的太阳能电池板的信息(不同年份);
Solar_Panels <- data.frame(
Customer = sample(1001:1010, 10, replace = TRUE),
SolarPanelYear1 = sample(10:20, 10, replace = TRUE),
SolarPanelYear2 = sample(15:20, 10, replace = TRUE)
)
现在我想看看每年每个变电站的负荷是多少。我有一个家庭负荷和太阳能电池板负荷正常化的每户或太阳能电池板;
SolarLoad <- data.frame(Load = c(0, -10, -10, 5))
HouseHoldLoad <- data.frame(Type1 = c(1, 3, 5, 2), Type2 = c(3, 5, 6, 1))
因此,现在我必须匹配这些清单;
ML_SubSt_Cust <- sapply(Unique_Substations$Name,
function(x) which(Customer_Information$SubSt_Nm %in% x == TRUE))
ML_Cust_SolarP <- sapply(Customer_Information$Customer,
function(x) which(Solar_Panels$Customer %in% x == TRUE))
(这里我使用which(xxx %in% x == TRUE)
方法,因为我需要多个匹配,而match()
只返回一个匹配
现在我们来问我的大问题(但这可能不是我唯一的问题)。我想计算每个变电站每年的最大负荷。为此,我首先编写了一个遍历Unique_Substations列表的for循环,这当然是非常低效率的。之后,我尝试使用outer()
加快速度,但我认为我没有正确地将函数向量化。我的最大功能如下(我只为太阳能电池板部分写出来,以保持它的简单);
GetMax <- function(i, Yr) {
max(sum(Solar_Panels[unlist(ML_Cust_SolarP[ML_SubSt_Cust[[i]]], use.names= FALSE),Yr])*SolarLoad)
}
我相信这是没有效率的,但我不知道如何以任何其他方式。
为了得到我的最终结果,我使用了一个外部函数;
Results <- outer(1:nrow(Unique_Substations), 1:2, Vectorize(GetMax))
在我的示例中,所有这些数据帧都要大得多(每行40000行左右),因此我确实需要对所涉及的函数进行一些良好的优化。我试着想出将函数向量化的方法,但是我想不出来。任何帮助都将不胜感激。
编辑:
现在我已经完全理解了被接受的awnser,我还有另一个问题。我的实际Customer_Information
为188行,实际HouseHoldLoad
为53k行。不用说,这并不是很好的merge()
。对于这个问题,还有另一种不需要merge()
或太慢的循环的解决方案吗?
发布于 2014-08-28 11:51:56
第一:生成随机数据时的set.seed()
!在为这些结果编写代码之前,我做了set.seed(1000)
。
我认为一点merge
,-ing和dplyr
可以在这里有所帮助。首先,我们将数据变得更好:
library(dplyr)
library(reshape2)
HouseHoldLoad <- melt(HouseHoldLoad, value.name="Load") %>%
select(HouseHoldType=variable, Load) %>%
mutate(HouseHoldType=gsub("Type", "", HouseHoldType))
Solar_Panels <- melt(Solar_Panels, id.vars="Customer",
value.name="SPYearVal") %>%
select(Customer, SolarPanelYear=variable, SPYearVal) %>%
mutate(SolarPanelYear=gsub("SolarPanelYear", "", SolarPanelYear))
dat <- merge(Customer_Information, Solar_Panels, by="Customer")
这使我们:
## Customer SubSt_Nm HouseHoldType SolarPanelYear SPYearVal
## 1 1001 SubB 1 1 16
## 2 1001 SubB 1 2 18
## 3 1001 SubB 1 2 16
## 4 1001 SubB 1 1 20
## 5 1002 SubD 2 1 16
## 6 1002 SubD 2 1 13
## 7 1002 SubD 2 2 20
## 8 1002 SubD 2 2 18
## 9 1003 SubA 1 2 15
## 10 1003 SubA 1 1 16
## 11 1005 SubC 2 2 19
## 12 1005 SubC 2 1 10
## 13 1006 SubA 1 1 15
## 14 1006 SubA 1 2 19
## 15 1007 SubC 1 1 17
## 16 1007 SubC 1 2 19
## 17 1009 SubA 1 1 10
## 18 1009 SubA 1 1 18
## 19 1009 SubA 1 2 18
## 20 1009 SubA 1 2 18
现在我们只是分组总结:
dat %>% group_by(SubSt_Nm, SolarPanelYear) %>%
summarise(mx=max(sum(SPYearVal)*SolarLoad))
## SubSt_Nm SolarPanelYear mx
## 1 SubA 1 295
## 2 SubA 2 350
## 3 SubB 1 180
## 4 SubB 2 170
## 5 SubC 1 135
## 6 SubC 2 190
## 7 SubD 1 145
## 8 SubD 2 190
如果您使用data.table
vs数据帧,即使使用40K条目,它也应该非常快速。
更新给那些不能安装dplyr
的人,这只是使用reshape2
(希望这是可安装的)
library(reshape2)
HouseHoldLoad <- melt(HouseHoldLoad, value.name="Load")
colnames(HouseHoldLoad) <- c("HouseHoldType", "Load")
HouseHoldLoad$HouseHoldType <- gsub("Type", "", HouseHoldLoad$HouseHoldType)
Solar_Panels <- melt(Solar_Panels, id.vars="Customer", value.name="SPYearVal")
colnames(Solar_Panels) <- c("Customer", "SolarPanelYear", "SPYearVal")
Solar_Panels$SolarPanelYear <- gsub("SolarPanelYear", "", Solar_Panels$SolarPanelYear)
dat <- merge(Customer_Information, Solar_Panels, by="Customer")
rbind(by(dat, list(dat$SubSt_Nm, dat$SolarPanelYear), function(x) {
mx <- max(sum(x$SPYearVal) * SolarLoad)
}))
## 1 2
## SubA 295 350
## SubB 180 170
## SubC 135 190
## SubD 145 190
如果您甚至连reshape2
都不能安装,那么这只适用于基本的stats
包:
colnames(HouseHoldLoad) <- c("Load.1", "Load.2")
HouseHoldLoad <- reshape(HouseHoldLoad, varying=c("Load.1", "Load.2"), direction="long", timevar="HouseHoldType")[1:2]
colnames(Solar_Panels) <- c("Customer", "SolarPanelYear.1", "SolarPanelYear.2")
Solar_Panels <- reshape(Solar_Panels, varying=c("SolarPanelYear.1", "SolarPanelYear.2"), direction="long", timevar="SolarPanelYear")[1:2]
colnames(Solar_Panels) <- c("Customer", "SPYearVal")
Solar_Panels$SolarPanelYear <- gsub("^[0-9]+\\.", "", rownames(Solar_Panels))
dat <- merge(Customer_Information, Solar_Panels, by="Customer")
rbind(by(dat, list(dat$SubSt_Nm, dat$SolarPanelYear), function(x) {
mx <- max(sum(x$SPYearVal) * SolarLoad)
}))
## 1 2
## SubA 295 350
## SubB 180 170
## SubC 135 190
## SubD 145 190
https://stackoverflow.com/questions/25545194
复制相似问题