R Error: Optimization resulting in "unused argument(x)"
R Error: Optimization resulting in "unused argument(x)"
我正在使用 R 编程语言。我定义了以下函数,我正在尝试对该函数执行“随机搜索”算法。
首先,我加载了库:
#load library : https://cran.r-project.org/web/packages/randomsearch/index.html
library(randomsearch)
然后,我定义了函数:
# create some data for this example
a1 = rnorm(1000,100,10)
b1 = rnorm(1000,100,10)
c1 = sample.int(1000, 1000, replace = TRUE)
train_data = data.frame(a1,b1,c1)
#define function (4 inputs x[1], x[2], x[3], x[4] and 4 outputs f1, f2, f3, f4)
fn <- function(i) {
x1 <- x[i,1]; x2 <- x[i,2]; x3 <- x[i,3] ; x4 <- x[i,4]
f <- numeric(4)
#bin data according to random criteria
train_data <- train_data %>%
mutate(cat = ifelse(a1 <= x1 & b1 <= x3, "a",
ifelse(a1 <= x2 & b1 <= x4, "b", "c")))
train_data$cat = as.factor(train_data$cat)
#new splits
a_table = train_data %>%
filter(cat == "a") %>%
select(a1, b1, c1, cat)
b_table = train_data %>%
filter(cat == "b") %>%
select(a1, b1, c1, cat)
c_table = train_data %>%
filter(cat == "c") %>%
select(a1, b1, c1, cat)
#calculate quantile ("quant") for each bin
table_a = data.frame(a_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 150,1,0 )))
table_b = data.frame(b_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 300,1,0 )))
table_c = data.frame(c_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 400,1,0 )))
f1 = mean(table_a$quant)
f2 = mean(table_b$quant)
f3 = mean(table_c$quant)
#group all tables
final_table = rbind(table_a, table_b, table_c)
# calculate the total mean : this is what needs to be optimized
f4 = mean(final_table$quant)
#add some constraints
if((x3 - x1) < 0. | (x4 - x2) < 0.) {
f[1] <- NaN
f[2] <- NaN
f[3] <- NaN
f[4] <- NaN
}
return (f)
}
最后,我尝试运行这个函数上的“随机搜索”算法:
#run algorithm
res = randomsearch(fn, lower = c(80, 80, 80, 80), upper = c(100,120,100,120), minimize = c(TRUE, TRUE, TRUE, TRUE), max.evals = 30)
rs = summary(res)
但这导致了以下错误:
Error in fun(x, ...) : unused argument (x)
有谁知道为什么会产生这个错误?是不是和我定义函数“fn”的方式有关?
谢谢
以下代码有效,但我无法使约束起作用:
library(randomsearch)
# create some data for this example
a1 = rnorm(1000,100,10)
b1 = rnorm(1000,100,10)
c1 = sample.int(1000, 1000, replace = TRUE)
train_data = data.frame(a1,b1,c1)
fun_1 <- function(x) {
x1 <- x[1]
x2 <- x[2]
x3 <- x[3]
x4 <- x[4]
#bin data according to random criteria
train_data <- train_data %>%
mutate(cat = ifelse(a1 <= x1 & b1 <= x3, "a",
ifelse(a1 <= x2 & b1 <= x4, "b", "c")))
train_data$cat = as.factor(train_data$cat)
#new splits
a_table = train_data %>%
filter(cat == "a") %>%
select(a1, b1, c1, cat)
b_table = train_data %>%
filter(cat == "b") %>%
select(a1, b1, c1, cat)
c_table = train_data %>%
filter(cat == "c") %>%
select(a1, b1, c1, cat)
#calculate quantile ("quant") for each bin
table_a = data.frame(a_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 200,1,0 )))
table_b = data.frame(b_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 300,1,0 )))
table_c = data.frame(c_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 400,1,0 )))
f1 = mean(table_a$quant)
f2 = mean(table_b$quant)
f3 = mean(table_c$quant)
#group all tables
final_table = rbind(table_a, table_b, table_c)
# calculate the total mean : this is what needs to be optimized
f4 = mean(final_table$quant)
return(c(f1, f2,f3))
}
res = randomsearch(fun_1, lower = c(90, 100, 90, 100), upper = c(100,120,100,120), minimize = c(TRUE, TRUE,TRUE), max.evals = 30)
rs = summary(res)
现在,查看结果:
> head(rs)
$pareto.front
y_1 y_2 y_3 x1 x2 x3 x4
1 0.7605634 0.6851628 0.6400000 91.12101 114.1228 96.77341 117.0649
4 0.7611940 0.6974249 0.5867238 90.16010 110.6879 99.06183 103.1964
5 0.7631579 0.6996337 0.5863570 93.49183 103.2529 90.54579 100.0828
8 0.7804878 0.7196653 0.5791667 93.37388 101.6645 91.03374 100.0605
9 0.7878788 0.6862745 0.5936842 92.85005 106.4595 94.16650 105.3454
14 0.7884615 0.6828423 0.6010782 94.17298 106.6873 91.62018 109.2036
@Sam Rogers:我很想知道你在想什么?
谢谢!
正如我在评论中提到的,我不完全确定你的目标是什么,或者你试图解决什么问题,所以我所做的只是优化你的代码已经写好了。如果我自己从头开始,完全有可能写出非常相似的代码,或者可能会有很大不同。
我添加了一个注释版本,以便您可以看到我所做的,还添加了一个删除了不需要的代码的简化版本。根据您的最终目标,可能仍然可以减少最小版本的行数,也可能加快它的速度,但它们可能不是重要的考虑因素。
我在这种情况下使用的一个基本原则是没有必要 运行 代码或保存不使用的东西。
评论版本
library(randomsearch)
library(tidyverse)
# create some data for this example
a1 = rnorm(1000,100,10)
b1 = rnorm(1000,100,10)
c1 = sample.int(1000, 1000, replace = TRUE)
train_data = data.frame(a1,b1,c1)
fun_2 <- function(x) {
# x1 <- x[1] # Storing these as additional variables doesn't help at all
# x2 <- x[2] # They are only used to bin the data
# x3 <- x[3]
# x4 <- x[4]
#bin data according to random criteria
train_data <- train_data %>%
mutate(cat = ifelse(a1 <= x[1] & b1 <= x[3], "a",
ifelse(a1 <= x[2] & b1 <= x[4], "b", "c")))
train_data$cat = as.factor(train_data$cat)
#new splits
a_table = train_data %>%
filter(cat == "a") #%>%
# select(a1, b1, c1, cat) # There are no other columns to select, so this is not needed
b_table = train_data %>%
filter(cat == "b") #%>%
# select(a1, b1, c1, cat)
c_table = train_data %>%
filter(cat == "c") #%>%
# select(a1, b1, c1, cat)
#calculate quantile ("quant") for each bin
# table_a = data.frame(a_table %>% group_by(cat) # We don't need another variable for this
# %>% mutate(quant = ifelse(c1 > 200,1,0 )))
a_table$quant = ifelse(a_table$c1 > 200, 1, 0) # It can also be simlpified
# table_b = data.frame(b_table%>% group_by(cat) %>%
# mutate(quant = ifelse(c1 > 300,1,0 )))
b_table$quant = ifelse(b_table$c1 > 300, 1, 0)
# table_c = data.frame(c_table%>% group_by(cat) %>%
# mutate(quant = ifelse(c1 > 400,1,0 )))
c_table$quant = ifelse(c_table$c1 > 400, 1, 0)
# f1 = mean(a_table$quant)
# f2 = mean(b_table$quant)
# f3 = mean(c_table$quant)
#group all tables
# final_table = rbind(table_a, table_b, table_c) # This is not used
# calculate the total mean : this is what needs to be optimized
# f4 = mean(final_table$quant) # This is not used
return(c(mean(a_table$quant), mean(b_table$quant), mean(c_table$quant)))
}
缩小版
fun_2 <- function(x) {
#bin data according to random criteria
train_data <- train_data %>%
mutate(cat = factor(ifelse(a1 <= x[1] & b1 <= x[3], "a",
ifelse(a1 <= x[2] & b1 <= x[4], "b", "c"))))
train_data$cat = as.factor(train_data$cat)
#new splits
a_table = train_data %>% filter(cat == "a")
b_table = train_data %>% filter(cat == "b")
c_table = train_data %>% filter(cat == "c")
#calculate quantile ("quant") for each bin
a_table$quant = ifelse(a_table$c1 > 200, 1, 0)
b_table$quant = ifelse(b_table$c1 > 300, 1, 0)
c_table$quant = ifelse(c_table$c1 > 400, 1, 0)
return(c(mean(a_table$quant), mean(b_table$quant), mean(c_table$quant)))
}
不幸的是,它们不会产生相同的结果,但我相信这是由于搜索的随机性,而不是代码中的错误。
希望对您有所帮助。我有时间再看看你的其他问题。
我正在使用 R 编程语言。我定义了以下函数,我正在尝试对该函数执行“随机搜索”算法。
首先,我加载了库:
#load library : https://cran.r-project.org/web/packages/randomsearch/index.html
library(randomsearch)
然后,我定义了函数:
# create some data for this example
a1 = rnorm(1000,100,10)
b1 = rnorm(1000,100,10)
c1 = sample.int(1000, 1000, replace = TRUE)
train_data = data.frame(a1,b1,c1)
#define function (4 inputs x[1], x[2], x[3], x[4] and 4 outputs f1, f2, f3, f4)
fn <- function(i) {
x1 <- x[i,1]; x2 <- x[i,2]; x3 <- x[i,3] ; x4 <- x[i,4]
f <- numeric(4)
#bin data according to random criteria
train_data <- train_data %>%
mutate(cat = ifelse(a1 <= x1 & b1 <= x3, "a",
ifelse(a1 <= x2 & b1 <= x4, "b", "c")))
train_data$cat = as.factor(train_data$cat)
#new splits
a_table = train_data %>%
filter(cat == "a") %>%
select(a1, b1, c1, cat)
b_table = train_data %>%
filter(cat == "b") %>%
select(a1, b1, c1, cat)
c_table = train_data %>%
filter(cat == "c") %>%
select(a1, b1, c1, cat)
#calculate quantile ("quant") for each bin
table_a = data.frame(a_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 150,1,0 )))
table_b = data.frame(b_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 300,1,0 )))
table_c = data.frame(c_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 400,1,0 )))
f1 = mean(table_a$quant)
f2 = mean(table_b$quant)
f3 = mean(table_c$quant)
#group all tables
final_table = rbind(table_a, table_b, table_c)
# calculate the total mean : this is what needs to be optimized
f4 = mean(final_table$quant)
#add some constraints
if((x3 - x1) < 0. | (x4 - x2) < 0.) {
f[1] <- NaN
f[2] <- NaN
f[3] <- NaN
f[4] <- NaN
}
return (f)
}
最后,我尝试运行这个函数上的“随机搜索”算法:
#run algorithm
res = randomsearch(fn, lower = c(80, 80, 80, 80), upper = c(100,120,100,120), minimize = c(TRUE, TRUE, TRUE, TRUE), max.evals = 30)
rs = summary(res)
但这导致了以下错误:
Error in fun(x, ...) : unused argument (x)
有谁知道为什么会产生这个错误?是不是和我定义函数“fn”的方式有关?
谢谢
以下代码有效,但我无法使约束起作用:
library(randomsearch)
# create some data for this example
a1 = rnorm(1000,100,10)
b1 = rnorm(1000,100,10)
c1 = sample.int(1000, 1000, replace = TRUE)
train_data = data.frame(a1,b1,c1)
fun_1 <- function(x) {
x1 <- x[1]
x2 <- x[2]
x3 <- x[3]
x4 <- x[4]
#bin data according to random criteria
train_data <- train_data %>%
mutate(cat = ifelse(a1 <= x1 & b1 <= x3, "a",
ifelse(a1 <= x2 & b1 <= x4, "b", "c")))
train_data$cat = as.factor(train_data$cat)
#new splits
a_table = train_data %>%
filter(cat == "a") %>%
select(a1, b1, c1, cat)
b_table = train_data %>%
filter(cat == "b") %>%
select(a1, b1, c1, cat)
c_table = train_data %>%
filter(cat == "c") %>%
select(a1, b1, c1, cat)
#calculate quantile ("quant") for each bin
table_a = data.frame(a_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 200,1,0 )))
table_b = data.frame(b_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 300,1,0 )))
table_c = data.frame(c_table%>% group_by(cat) %>%
mutate(quant = ifelse(c1 > 400,1,0 )))
f1 = mean(table_a$quant)
f2 = mean(table_b$quant)
f3 = mean(table_c$quant)
#group all tables
final_table = rbind(table_a, table_b, table_c)
# calculate the total mean : this is what needs to be optimized
f4 = mean(final_table$quant)
return(c(f1, f2,f3))
}
res = randomsearch(fun_1, lower = c(90, 100, 90, 100), upper = c(100,120,100,120), minimize = c(TRUE, TRUE,TRUE), max.evals = 30)
rs = summary(res)
现在,查看结果:
> head(rs)
$pareto.front
y_1 y_2 y_3 x1 x2 x3 x4
1 0.7605634 0.6851628 0.6400000 91.12101 114.1228 96.77341 117.0649
4 0.7611940 0.6974249 0.5867238 90.16010 110.6879 99.06183 103.1964
5 0.7631579 0.6996337 0.5863570 93.49183 103.2529 90.54579 100.0828
8 0.7804878 0.7196653 0.5791667 93.37388 101.6645 91.03374 100.0605
9 0.7878788 0.6862745 0.5936842 92.85005 106.4595 94.16650 105.3454
14 0.7884615 0.6828423 0.6010782 94.17298 106.6873 91.62018 109.2036
@Sam Rogers:我很想知道你在想什么?
谢谢!
正如我在评论中提到的,我不完全确定你的目标是什么,或者你试图解决什么问题,所以我所做的只是优化你的代码已经写好了。如果我自己从头开始,完全有可能写出非常相似的代码,或者可能会有很大不同。
我添加了一个注释版本,以便您可以看到我所做的,还添加了一个删除了不需要的代码的简化版本。根据您的最终目标,可能仍然可以减少最小版本的行数,也可能加快它的速度,但它们可能不是重要的考虑因素。
我在这种情况下使用的一个基本原则是没有必要 运行 代码或保存不使用的东西。
评论版本
library(randomsearch)
library(tidyverse)
# create some data for this example
a1 = rnorm(1000,100,10)
b1 = rnorm(1000,100,10)
c1 = sample.int(1000, 1000, replace = TRUE)
train_data = data.frame(a1,b1,c1)
fun_2 <- function(x) {
# x1 <- x[1] # Storing these as additional variables doesn't help at all
# x2 <- x[2] # They are only used to bin the data
# x3 <- x[3]
# x4 <- x[4]
#bin data according to random criteria
train_data <- train_data %>%
mutate(cat = ifelse(a1 <= x[1] & b1 <= x[3], "a",
ifelse(a1 <= x[2] & b1 <= x[4], "b", "c")))
train_data$cat = as.factor(train_data$cat)
#new splits
a_table = train_data %>%
filter(cat == "a") #%>%
# select(a1, b1, c1, cat) # There are no other columns to select, so this is not needed
b_table = train_data %>%
filter(cat == "b") #%>%
# select(a1, b1, c1, cat)
c_table = train_data %>%
filter(cat == "c") #%>%
# select(a1, b1, c1, cat)
#calculate quantile ("quant") for each bin
# table_a = data.frame(a_table %>% group_by(cat) # We don't need another variable for this
# %>% mutate(quant = ifelse(c1 > 200,1,0 )))
a_table$quant = ifelse(a_table$c1 > 200, 1, 0) # It can also be simlpified
# table_b = data.frame(b_table%>% group_by(cat) %>%
# mutate(quant = ifelse(c1 > 300,1,0 )))
b_table$quant = ifelse(b_table$c1 > 300, 1, 0)
# table_c = data.frame(c_table%>% group_by(cat) %>%
# mutate(quant = ifelse(c1 > 400,1,0 )))
c_table$quant = ifelse(c_table$c1 > 400, 1, 0)
# f1 = mean(a_table$quant)
# f2 = mean(b_table$quant)
# f3 = mean(c_table$quant)
#group all tables
# final_table = rbind(table_a, table_b, table_c) # This is not used
# calculate the total mean : this is what needs to be optimized
# f4 = mean(final_table$quant) # This is not used
return(c(mean(a_table$quant), mean(b_table$quant), mean(c_table$quant)))
}
缩小版
fun_2 <- function(x) {
#bin data according to random criteria
train_data <- train_data %>%
mutate(cat = factor(ifelse(a1 <= x[1] & b1 <= x[3], "a",
ifelse(a1 <= x[2] & b1 <= x[4], "b", "c"))))
train_data$cat = as.factor(train_data$cat)
#new splits
a_table = train_data %>% filter(cat == "a")
b_table = train_data %>% filter(cat == "b")
c_table = train_data %>% filter(cat == "c")
#calculate quantile ("quant") for each bin
a_table$quant = ifelse(a_table$c1 > 200, 1, 0)
b_table$quant = ifelse(b_table$c1 > 300, 1, 0)
c_table$quant = ifelse(c_table$c1 > 400, 1, 0)
return(c(mean(a_table$quant), mean(b_table$quant), mean(c_table$quant)))
}
不幸的是,它们不会产生相同的结果,但我相信这是由于搜索的随机性,而不是代码中的错误。
希望对您有所帮助。我有时间再看看你的其他问题。