Search code examples
rreactable

I get the error message "non-numeric argument to binary operator" when trying to run code


Creating a reactable in R, I was successfully able to use the colorRamp function to make a color scale for the "Rank" column. However, when I copy the code to the PVI VALUE column, I get the error message "non-numeric argument to binary operator". Why can I not simply paste the "style" part of the code in the PVI VALUE column to achieve the identical color scale? I think it is because the "value" of the PVI_Value column is string - so how do I make the function use the "Rank" values instead?

RtoDColorPalette <- function(x) rgb(colorRamp(c("red","blue"))(x),maxColorValue = 255)

MasterIndexTable <- reactable(
  HousePVI,
  columns = list(
    ID_No = colDef(show = FALSE),
    State = colDef(defaultSortOrder = "asc", width = 60),
    District_Number = colDef(name = "District", defaultSortOrder = "asc", width = 75),
    First_Name = colDef(name = "First Name", width = 120),
    Last_Name = colDef(name = "Last Name", width = 120),
    Member_Party = colDef(name = "Party", width = 60),
    PVI_Lean = colDef(name = "PVI Lean", width = 60, show = FALSE),
    PVI_Value_Absolute = colDef(name = "PVI Value Absolute", width = 60, show = FALSE),
    PVI_Value = colDef(name = "PVI Value",
                   style = function(value) {
                     normalized <- (value - min(HousePVI$Rank))/(max(HousePVI$Rank) -     min(HousePVI$Rank))
                     color <- RtoDColorPalette(normalized)
                     list(background = color, color = 'white')
                   }
              ),
    Rank = colDef(name = "Rank - Most Republican (1) to Most Democratic (435)",  
              style = function(value) {
                normalized <- (value - min(HousePVI$Rank))/(max(HousePVI$Rank) - min(HousePVI$Rank))
                color <- RtoDColorPalette(normalized)
                list(background = color, color = 'white')
                }
              )
    ),
  sortable = TRUE,
  filterable = TRUE,
  searchable = TRUE,
  showPageSizeOptions = TRUE,
  pageSizeOptions = c(10,20,435),
  striped = TRUE,
  compact = TRUE,
  theme = fivethirtyeight () 
  ) 

Solution

  • Your guess is right. The value passed to the style function is the value of the column on which you want to apply the style.

    However, one option to style a column based on the value of another column would be to make use of the optional index argument (there is also an optional name argument, see Cell Styling) which provides the row index, i.e. using the index we could color based on HousePVI$Rank[index].

    Using a fake example:

    library(reactable)
    
    set.seed(123)
    
    RtoDColorPalette <- function(x) rgb(colorRamp(c("red", "blue"))(x), maxColorValue = 255)
    
    HousePVI <- data.frame(
      ID_No = 1:10,
      State = LETTERS[1:10],
      Rank = sample(1:10)
    )
    
    reactable(
      HousePVI,
      columns = list(
        ID_No = colDef(show = FALSE),
        Rank = colDef(
          name = "Rank (Most Republican (1) to Most Democratic (435)", width = 230,
          style = function(value) {
            normalized <- (value - min(HousePVI$Rank)) / (max(HousePVI$Rank) - min(HousePVI$Rank))
            color <- RtoDColorPalette(normalized)
            list(background = color, color = "white")
          }
        ),
        State = colDef(
          style = function(value, index) {
            normalized <- (HousePVI$Rank[index] - min(HousePVI$Rank)) / (max(HousePVI$Rank) - min(HousePVI$Rank))
            color <- RtoDColorPalette(normalized)
            list(background = color, color = "white")
          }
        )
      ),
      theme = reactableTheme(
        color = "black",
        backgroundColor = "white",
        borderColor = "black",
        stripedColor = "aliceblue"
      )
    )
    

    enter image description here