1

I have created the correct number of indeces for my vectors and I am trying to input the i'th element from the for loop as the index to hold the classification error value. But I get the error:

Error in indeces.gen_error[[i]] <- paste(classification_error) :
attempt to select less than one element

uspscl.txt

uspsdata.txt

My code:

library(e1071)
library(caret)

set.seed(733)
uspscldf = read.table('uspscl.txt', header=F, sep=',')
uspsdatadf = read.table('uspsdata.txt', header=F, sep='\t')

trainIndex <- createDataPartition(uspscldf$V1,list=FALSE, p = .80,times=1)
dataTrain <- uspsdatadf[ trainIndex,]
dataTest  <- uspsdatadf[-trainIndex,]

classTrain <- uspscldf[ trainIndex,]
classTest  <- uspscldf[-trainIndex,]

indeces = seq(0.00001, 1, by=0.001)

indeces.gen_error = NULL
indeces.softmargin = NULL
for (i in seq(0.00001, 1, by=0.001)){
    # For svm(): soft margin is "cost" 
    # Gaussian kernel bandwidth (sigma) = is implicitly defined by "gamma"
    # kernal=radial is non-linear while kernal=linear is linear
    svm.model <- svm(classTrain ~ ., data = dataTrain, cost = i,type="C-classification",kernal = "linear")

    svm.pred <- predict(svm.model, dataTrain)

    # confusion matrix
    tab <- table(pred = svm.pred, true = classTrain)

    classification_error <- 1- sum(svm.pred == classTrain)/length(svm.pred)

    indeces.gen_error[[i]] <- paste(classification_error)
    indeces.softmargin[[i]]<-i
}

I printed the first i in the first iteration and it give 1e-5 which is correct so I am at a loss as to why it says I am selecting less than one element. Any help would be appreciated. Thanks

ANSWER::: I did not see Pierre's answer to this until I solved the answer myself but his explanation is better so I am accepting his answer. My new code now is:

indeces = seq(0.00001, 1, by=0.001)

indeces.gen_error = NULL
indeces.softmargin = NULL
count=0
for (i in indeces){
  count=count+1
    # For svm(): soft margin is "cost" 
    # Gaussian kernel bandwidth (sigma) = is implicitly defined by "gamma"
    # kernal=radial is non-linear while kernal=linear is linear
    svm.model <- svm(classTrain ~ ., data = dataTrain, cost = i,type="C-classification",kernal = "linear")

    svm.pred <- predict(svm.model, dataTrain)

    # confusion matrix
    tab <- table(pred = svm.pred, true = classTrain)

    classification_error <- 1- sum(svm.pred == classTrain)/length(svm.pred)

    indeces.gen_error[[count]] <- paste(classification_error)
    indeces.softmargin[[count]]<-i
}
hope288
  • 725
  • 12
  • 23
  • 2
    Can you explain what an index of 0.00001 should mean to an array? The indices are supposed to be integers; if not, they are somehow coerced (which, in this case, appears to be causing a problem for you). – r2evans Feb 27 '16 at 04:12
  • On Stack Overflow, any debugging questions ("why is this code not working?") must include a reproducible example. In this case we don't have uspscl.txt or uspsdata.txt so we can't replicate your error. You might either post a data sample or use a built-in dataset to make your question reproducible. To read more about reproducible examples in R, please see http://stackoverflow.com/questions/5963269. – josliber Feb 27 '16 at 04:14
  • 1
    You are subsetting with values like `0.00001`. I'm sure that is not intended. To see the error reproduced try `x <- NULL; x[[0.001]] <- "a"` – Pierre L Feb 27 '16 at 04:22
  • @josliber I added the text files. – hope288 Feb 27 '16 at 04:29
  • @PierreLafortune hm I see that you reproduced the code but I still don't understand. – hope288 Feb 27 '16 at 04:33
  • @r2evans I changed it to indeces = seq(0, 999) but still the same response. The length of the loop iteration is 1000, same as the indeces. I also tried indeces.gen_error[i] instead of [[i]] but that makes indeces.gen_error equal to numeric(0) – hope288 Feb 27 '16 at 04:39

1 Answers1

4
#Example
x <- NULL
for( i in seq(0.01, 1, .01)) {
  a <- 10 * i
  x[[i]] <- paste("b", a)
}
# Error in x[[i]] <- paste("b", a) : 
#   attempt to select less than one element

#The right way
x <- NULL
myseq <- seq(0.01, 1, 0.01)
for( i in 1:length(myseq)) {
  a <- 10 * myseq[i]
  x[i] <- paste("b", a)
}

Why the first way fails for( i in seq(0.01, 1, .01)) will use the sequence as 'i'. Anytime when a loop fails, the first way to troubleshoot is to try out each loop one by one. So each loop takes a value of the sequence and enters it wherever there is an i. The first loop looks like:

for (i in seq(0.00001, 1, by=0.001)){

    svm.model <- svm(classTrain ~ ., data = dataTrain, cost = 0.00001,type="C-classification",kernal = "linear")

    svm.pred <- predict(svm.model, dataTrain)

    # confusion matrix
    tab <- table(pred = svm.pred, true = classTrain)

    classification_error <- 1- sum(svm.pred == classTrain)/length(svm.pred)

    indeces.gen_error[[0.00001]] <- paste(classification_error)
    indeces.softmargin[[0.00001]]<- 0.00001
}

Do you see the problem? With indeces.gen_error[[0.00001]] pay attention to what is happening here. You did not mean to do this. You meant for indeces.gen_error[[1]] to be the first entry.

You are subsetting by a decimal. If we had:

x <- 1:10

What do you think would happen with x[2.5]? We are asking R for the element at the position 2.5. That doesn't make sense. There is no half position. There's either the 2nd or 3rd. Try it to see what is returned.

In your loop you are asking R for indeces.gen_error[[0.00001]]. Therefore, you are requesting the 1/100,000th position. That doesn't make sense. The evaluator will force the subset to be an integer. It goes to 0. And we get an error.

Pierre L
  • 28,203
  • 6
  • 47
  • 69
  • Thank you for your explanation :) I changed my code if you see above. How is the best way to tell it to go to the first position in R? My solution was to use a count but I think there is a more elegant solution that I am not thinking of. – hope288 Feb 27 '16 at 05:04
  • Use the example in the answer and apply the idea to your loop `for (i in 1:length(indeces))` is the start – Pierre L Feb 27 '16 at 05:06
  • In your model use `cost = indeces[i]`. At the end use `indeces.gen_error[i]`. – Pierre L Feb 27 '16 at 05:07
  • Ahh I see. THANK YOU! :) – hope288 Feb 27 '16 at 05:24