In R arguments are passed by value, so we don't need to copy anything - we are sure that functions won't modify arguments that we pass them. And well, I have a strange problem with this. In my KNN function I tune parameter k: I pass arguments to cross_validate function, which calls KNN function; I do it in loop and choose best parameter. The problem is, I get an error with original argument after cross-validation: "object 'original_training_set' not found".
if (is.data.frame(training_set))
{
original_training_set <- data.table::copy(training_set)
training_set <- data.matrix(training_set)
}
else
{
if (!is.matrix(training_set))
stop("training_set must be data frame or matrix")
}
print(original_training_set) # here everything's all right
if (is.numeric(k) && k < 1)
{ stop("k must be >= 1") }
else if (k == "all")
{ k <- nrow(training_set) }
else if (is.numeric(k))
{ k <- min(k, ncol(training_set)) }
else if (k == "best_fit")
{
best_k <- 0
best_perc <- 0
source("./source./test.R")
for (i in 1:as.integer(sqrt(nrow(training_set))))
{
perc <- cross_validate(training_set, 5, predict_param, i, metric, weighting_scheme)
if (perc > best_perc)
{
best_k <- i
best_perc <- perc
}
}
perc <- cross_validate(training_set, 5, predict_param, "all", metric, weighting_scheme)
if (perc > best_perc)
best_k <- nrow(training_set)
k <- best_k
}
else
{ stop('k must be one of: numeric, "all", "best_fit"') }
print(original_training_set) # here I get an error
cross_validate function returns only percentage of well predicted values, so it won't update any matrix. First print works fine, with second one I get an error. I have absolutely no idea why, since pass-by-value should protect me from any unwanted modifications. I even copied **training_set (**I didn't do it before), but got same results.
EDIT Contents of test.R:
cross_validate <- function(dataset, parts, predict_param, k="all", metric="hassanat", weighting_scheme="inverted")
{
percentages <- vector(length=parts)
part_size <- round(nrow(dataset) / parts)
res <- NULL
for (i in 1:parts)
{
if (i != parts)
{
left <- (i - 1) * part_size + 1
right<- i * part_size
predict_set <- dataset[left:right,]
training_set <- dataset[-(left:right),]
}
else
{
left <- (i - 1) * part_size + 1
right <- nrow(dataset)
predict_set <- dataset[left:right,]
training_set <- dataset[-(left:right),]
}
source("./source./main.R")
predicted_set <- knn(training_set, predict_set, predict_param, k, metric, weighting_scheme)
res <- rbind(res, data.frame(predicted_set))
percentages[i] <- round(100*sum(predict_set[, predict_param] == predicted_set[, predict_param]) / nrow(predict_set), digits=3)
}
write.table(res, file="./results.csv", row.names=FALSE, col.names=FALSE, sep=",", quote=FALSE)
mean(percentages)
}
Smallest reproductible example can't be provided, since I'd have to upload entire project (files are quite long and interconnected). Everything I use up to error point is in code above. I just use:
mydata <- iris
perc <- cross_validate(mydata, 5, 1, k="best_fit")