Charles Woodson
Charles Woodson

Reputation: 39

R Shiny select column by checkboxGroupInput

The following code works when I pass an int in for col_num:

makeHRdata = function(Test, model, col_num) {
  means = 1:length(Test)
  for (i in 1:length(Test)) means[i] = mean(Test[,i])
  TestCopy = Test[1,]
  TestCopy[1,] = t(means)
  pdpHR = range(Test[col_num])
  for (i in range(Test[col_num])[1]:range(Test[col_num])[2]) {
    TestCopy[1,col_num] = i
    pdpHR[i] = predict(model,TestCopy) 
  }
  return(pdpHR)
}

I want users to be able to select the col_num in a checkboxGroupInput (to allow this function to be called multiple times).

I can print out the user's input with checkboxGroupInput like this:

output$text5 <- renderText({ 
      paste( "The object you selected is ",
            input$select_columns2)
})

So, input$select_columns2 contains a string of the name of a column.

I tried rewriting that function to incorporate the string instead of the int for column name:

makeHRdata = function(Test, model, col_num) {
  means = 1:length(Test)
  for (i in 1:length(Test)) means[i] = mean(Test[,i])
  TestCopy = Test[1,]
  TestCopy[1,] = t(means)
  pdpHR = range(Test$col_num)
  for (i in range(Test$col_num)[1]:range(Test$col_num)[2]) {
    #TestCopy[1,col_num] = i
    TestCopy$col_num[1] = i
    pdpHR[i] = predict(model,TestCopy)  
  }
  return(pdpHR)
}

I'm calling this function with this:

reactiveHRdata = reactive({
      makeHRdata(get(input$select_test_data2),eecs,input$select_columns2) 
})

The error I get when I try this is: Error in range(Test$col_num)[1]:range(Test$col_num)[2] : result would be too long a vector

The range is 0 to 63, which certainly isn't "too long." And I don't get this error when I specify the column with an int.

Also, I tested my new function by just writing in a column name instead of using the variable col_num, and it worked perfectly. (HR is a column name.):

makeHRdata = function(Test, model, col_num) {
  means = 1:length(Test)
  for (i in 1:length(Test)) means[i] = mean(Test[,i])
  TestCopy = Test[1,]
  TestCopy[1,] = t(means)
  pdpHR = range(Test$HR)
  for (i in range(Test$HR)[1]:range(Test$HR)[2]) {
    TestCopy$HR[1] = i
    pdpHR[i] = predict(model,TestCopy)  
  }
  return(pdpHR)
}

Any idea what I can do to pass in the column name as a string and have everything work? Thanks so much!

Upvotes: 0

Views: 278

Answers (1)

K. Rohde
K. Rohde

Reputation: 9676

This is a funny error. See this for explanation:

> df <- data.frame(a = 1:10)
> range(df$b)
[1]  Inf -Inf
Warning messages:
1: In min(x, na.rm = na.rm) :
  no non-missing arguments to min; returning Inf
2: In max(x, na.rm = na.rm) :
  no non-missing arguments to max; returning -Inf

So apparently, when you call Test$col_num it does not recognize col_num to be a variable. It searches for the column "col_num" which is NULL. The range becomes [-Inf, Inf] and you don't see the warnings, because it is executed inside the function environment. And of course, the vector -Inf:Inf is way too large.

Here is the fix (and the way to call columns through variables): Use Test[[col_num]] instead of Test$col_num.

Upvotes: 1

Related Questions