循环遍历 R 中的一组项目
Loop through a set of items in R
我正在尝试模拟线性规划问题。该模型有一个 obj
函数和一些约束。在本例中,我引入了 2 个从正态分布中随机抽取的值。
然后我使用 for 循环模拟优化模型 10.000 次。我知道使用 for 循环是不好的 R 实践,但在这种情况下我不关心速度。
#List of 10000 random, normally distributed observations:
Demand = rnorm(10000, mean=5, sd=2.5)
Demand
Performance = rnorm(10000, mean=100, sd=6)
Performance
Optimas = NULL
#combined_list = c(Demand, Performance)
for (i in Performance){
op <- OP(objective = c(2.5, 4, i), #Performance value[i]: works fine
L_constraint(L = matrix(c(1, 0, 0, #LHS
0, 1, 0,
0, 0, 1),
ncol=3, nrow = 3,
byrow = TRUE),
dir = c("<=", "<=", "<="),
rhs = c(50, 70, Demand)), #Demand value[i]: should go here
maximum = TRUE,
types = c("B", "I", "I"))
Optima <- ROI_solve(op, solver = "glpk") #solve
print(Optima)
print(i)
Optimas = rbind(Optimas, Optima)
}
Optimas <- as.data.frame(Optimas)
Optimas$objval <- as.numeric(Optimas$objval)
hist(Optimas$objval)
如上所示,我的循环只通过一个变量(性能),我希望将需求向量中行(i)的需求值与性能值同时放入模型中对于性能向量中的第 (i) 行。
总的来说 objective 是对 LP 模型进行 10.000 次模拟,其中性能值和需求值只出现一次(因为我已有的循环之外的另一个循环将产生两个列表的笛卡尔积)。
请注意,您的 Performance
和 Demand
向量包含的元素数量完全相同。因此,您可以简单地遍历向量索引并使用各自的索引值来提取相关元素。
我无法 运行 你的示例代码,因为我不确定你的 OP
函数使用的是哪个优化包。作为示例,我将定义一个简单的 dummyFunction
,它将性能和需求值作为输入,如下所示:
dummyFunction <- function(perf, dem){ return (perf+dem)}
在您的特定用例中,dummyFunction
将包含优化逻辑。接下来,您可以通过迭代向量索引来获得所需的解决方案,如下所示:
Optimas = vector(mode="numeric", length=length(Performance))
for(idx in 1:length(Performance)){
Optimas[idx] <- dummyFunction(Performance[idx], Demand[idx])
}
或者,您可以通过将优化逻辑放在 for
循环中来避免函数定义。
更多 "R like solution" 考虑使用 sapply
/ lapply
类型函数:
Optimas <- sapply(1:length(Performance), function(idx) dummyFunction(Performance[idx], Demand[idx]))
请注意,在此特定示例中,您还可以执行以下操作:
Optimas <- dummyFunction(Performance, Demand)
最后,如果性能成为问题,请考虑使用 foreach
和 doparallel
包来 运行 同时优化多核:
library(doParallel)
library(foreach)
nrCores <- detectCores()
cl <- makeCluster(nrCores); registerDoParallel(cl)
clusterExport(cl,c("Demand", "Performance", "dummyFunction"), envir=environment())
Optimas <- foreach(idx=1:length(Performance), .combine="rbind") %dopar%{
dummyFunction(Performance[idx], Demand[idx])
}
stopCluster(cl)
考虑一个 mapply() 方法,apply 函数迭代多个 lists/vectors 传递相应的元素。首先将所有操作包装在一个函数中,然后在 mapply()
中调用它,为向量传递两个参数。最后,使用 lapply()
转置为一长串数据帧,这些数据帧与 do.call(rbind...)
.
行绑定
Performance = rnorm(10000, mean=100, sd=6)
Demand = rnorm(10000, mean=5, sd=2.5)
optimizefct <- function(p, d){
op <- OP(objective = c(2.5, 4, p), # Performance
L_constraint(L = matrix(c(1, 0, 0, # LHS
0, 1, 0,
0, 0, 1),
ncol=3, nrow = 3,
byrow = TRUE),
dir = c("<=", "<=", "<="),
rhs = c(50, 70, d)), # Demand
maximum = TRUE,
types = c("B", "I", "I"))
Optima <- ROI_solve(op, solver = "glpk") #solve
print(Optima)
print(i)
return(Optima)
}
# WIDE FORMAT
dfList <- mapply(optimizefct, Performance, Demand)
# LONG FORMAT
dfList <- lapply(1:10000, function(i) data.frame(dfList[,i]))
# BIND TO FINAL DF
Optimas <- do.call(rbind, dfList)
Optimas$objval <- as.numeric(Optimas$objval)
我正在尝试模拟线性规划问题。该模型有一个 obj
函数和一些约束。在本例中,我引入了 2 个从正态分布中随机抽取的值。
然后我使用 for 循环模拟优化模型 10.000 次。我知道使用 for 循环是不好的 R 实践,但在这种情况下我不关心速度。
#List of 10000 random, normally distributed observations:
Demand = rnorm(10000, mean=5, sd=2.5)
Demand
Performance = rnorm(10000, mean=100, sd=6)
Performance
Optimas = NULL
#combined_list = c(Demand, Performance)
for (i in Performance){
op <- OP(objective = c(2.5, 4, i), #Performance value[i]: works fine
L_constraint(L = matrix(c(1, 0, 0, #LHS
0, 1, 0,
0, 0, 1),
ncol=3, nrow = 3,
byrow = TRUE),
dir = c("<=", "<=", "<="),
rhs = c(50, 70, Demand)), #Demand value[i]: should go here
maximum = TRUE,
types = c("B", "I", "I"))
Optima <- ROI_solve(op, solver = "glpk") #solve
print(Optima)
print(i)
Optimas = rbind(Optimas, Optima)
}
Optimas <- as.data.frame(Optimas)
Optimas$objval <- as.numeric(Optimas$objval)
hist(Optimas$objval)
如上所示,我的循环只通过一个变量(性能),我希望将需求向量中行(i)的需求值与性能值同时放入模型中对于性能向量中的第 (i) 行。
总的来说 objective 是对 LP 模型进行 10.000 次模拟,其中性能值和需求值只出现一次(因为我已有的循环之外的另一个循环将产生两个列表的笛卡尔积)。
请注意,您的 Performance
和 Demand
向量包含的元素数量完全相同。因此,您可以简单地遍历向量索引并使用各自的索引值来提取相关元素。
我无法 运行 你的示例代码,因为我不确定你的 OP
函数使用的是哪个优化包。作为示例,我将定义一个简单的 dummyFunction
,它将性能和需求值作为输入,如下所示:
dummyFunction <- function(perf, dem){ return (perf+dem)}
在您的特定用例中,dummyFunction
将包含优化逻辑。接下来,您可以通过迭代向量索引来获得所需的解决方案,如下所示:
Optimas = vector(mode="numeric", length=length(Performance))
for(idx in 1:length(Performance)){
Optimas[idx] <- dummyFunction(Performance[idx], Demand[idx])
}
或者,您可以通过将优化逻辑放在 for
循环中来避免函数定义。
更多 "R like solution" 考虑使用 sapply
/ lapply
类型函数:
Optimas <- sapply(1:length(Performance), function(idx) dummyFunction(Performance[idx], Demand[idx]))
请注意,在此特定示例中,您还可以执行以下操作:
Optimas <- dummyFunction(Performance, Demand)
最后,如果性能成为问题,请考虑使用 foreach
和 doparallel
包来 运行 同时优化多核:
library(doParallel)
library(foreach)
nrCores <- detectCores()
cl <- makeCluster(nrCores); registerDoParallel(cl)
clusterExport(cl,c("Demand", "Performance", "dummyFunction"), envir=environment())
Optimas <- foreach(idx=1:length(Performance), .combine="rbind") %dopar%{
dummyFunction(Performance[idx], Demand[idx])
}
stopCluster(cl)
考虑一个 mapply() 方法,apply 函数迭代多个 lists/vectors 传递相应的元素。首先将所有操作包装在一个函数中,然后在 mapply()
中调用它,为向量传递两个参数。最后,使用 lapply()
转置为一长串数据帧,这些数据帧与 do.call(rbind...)
.
Performance = rnorm(10000, mean=100, sd=6)
Demand = rnorm(10000, mean=5, sd=2.5)
optimizefct <- function(p, d){
op <- OP(objective = c(2.5, 4, p), # Performance
L_constraint(L = matrix(c(1, 0, 0, # LHS
0, 1, 0,
0, 0, 1),
ncol=3, nrow = 3,
byrow = TRUE),
dir = c("<=", "<=", "<="),
rhs = c(50, 70, d)), # Demand
maximum = TRUE,
types = c("B", "I", "I"))
Optima <- ROI_solve(op, solver = "glpk") #solve
print(Optima)
print(i)
return(Optima)
}
# WIDE FORMAT
dfList <- mapply(optimizefct, Performance, Demand)
# LONG FORMAT
dfList <- lapply(1:10000, function(i) data.frame(dfList[,i]))
# BIND TO FINAL DF
Optimas <- do.call(rbind, dfList)
Optimas$objval <- as.numeric(Optimas$objval)