我正在尋找一種快速有效的方法來計算下面描述的問題。任何幫助將不勝感激,在此先感謝!向量化「查找」功能的正確方法
我有幾個非常大的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)
)
現在我想看看每個變電站每年的負載是多少。我有一個家庭負載和一個太陽能電池板負載正常化的每種類型的家庭或solarpanel;
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()
只返回一個匹配
現在我們來到我的大問題(但可能不是我唯一的,最後用這種方法的問題)我想計算每個變電站每年的最大負載,爲此我首先編寫了一個for循環,通過Unique_Substations列表循環,這當然是非常低效的。之後我嘗試使用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
是188K行長,我的實際HouseHoldLoad
是53K行長。不用說這不是merge()
非常好。是否有另一種解決方案,不需要merge()
或循環太慢?
首先,你不需要'data.frames',因爲只有一個數據類型每個對象。向量和矩陣就足夠了。接下來,不是'which(foo%in%bar == TRUE)',而只是'which(bar == foo)'(其中'foo'是一個標量,'bar'是你的向量或矩陣)。 – 2014-08-28 11:20:47
@CarlWitthoft'which(foo%in%bar == TRUE)'與'which(foo%in%bar)'相同,而不是'which(bar == foo)'。拿'bar = c(0,1)'和'foo = c(1,0)',差別很明顯。我同意你可以在'foo'只包含一個元素時使用,但它們不一樣。 – 2014-08-28 11:52:57
@JorisMeys謝謝 - 好點 – 2014-08-28 12:37:39