Я ищу быстрый и эффективный способ вычисления проблемы, описанной ниже. Любая помощь будет оценена, спасибо заранее!Правильный способ векторизации функции «поиска»
У меня есть пара очень больших файлов 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()
возвращает только один матч
А теперь мы подошли к моей большой вопрос (но, вероятно, не единственная моя проблема с этим методом), наконец, Я хочу рассчитать максимальную нагрузку на каждую подстанцию за каждый год. Для этого я сначала написал цикл for, который зациклился на списке Unique_Substations, который, конечно, очень неэффективен. После этого я попытался ускорить его, используя outer()
, но Я не думаю, что у меня была правильная векторная функция. Моя максимальная функция выглядит следующим образом (я только написал ее для части солнечной панели, чтобы сохранить i t простой);
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 строк каждый или около того), так что я действительно нужна хорошая оптимизация функций, участвующих. Я пытался подумать о способах векторизации функции, но я не мог ее решить. Любая помощь будет оценена по достоинству.
EDIT:
Теперь, когда я полностью понимаю, принятый awnser у меня есть еще одна проблема. Мой фактический Customer_Information
составляет 188 тыс. Строк в длину, а мой фактический HouseHoldLoad
составляет 53 тыс. Строк. Излишне говорить, что это не merge()
очень хорошо. Есть ли другое решение этой проблемы, которое не требует merge()
или для слишком медленных циклов?
с одной стороны, вам не нужно 'data.frames', так как есть только один тип данных каждый объект. Векторов и матриц будет достаточно. Далее, а не 'which (foo% in% bar == TRUE)', просто 'which (bar == foo)' (где 'foo' - это скаляр, а' bar' - ваш вектор или матрица). –
@CarlWitthoft 'который (foo% in% bar == TRUE)' такой же, как 'which (foo% in% bar)', а не как 'which (bar == foo)'. Возьмите 'bar = c (0,1)' и 'foo = c (1,0)', и разница очевидна. Я согласен, что вы можете использовать либо, когда 'foo' содержит только один элемент, но они не совпадают. –
@JorisMeys Спасибо - хорошая точка –