0

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")
qalis
  • 1,314
  • 1
  • 16
  • 44
  • What's the error message? – rg255 Jun 23 '19 at 08:52
  • I edited my question to answer your question. – qalis Jun 23 '19 at 08:57
  • What us the content of test.R? – Roland Jun 23 '19 at 09:33
  • It would be simpler to help you with a [small reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example), including some example data, used packages etc. Currently my best guess is that you have a `rm(list = ls())` or similar somewhere outside the code your showing (`test.r` for example). – Oliver Jun 23 '19 at 09:45
  • I've edited my question with additional code. I don't remove anything, I don't even touch KNN directly, it gets tables from cross_validate – qalis Jun 23 '19 at 10:01

0 Answers0