0
votes

I have a function to create a datatable in Shiny based on department numbers and how many times an event happened in that department during a time period. My issue is that if the date range is short enough, no departments will have had the event occur. In those instances, I get the error Error in rowSums(x) : 'x' must be an array of at least two dimensions which initially just appeared within the Shiny app and you could just ignore it. Now, the app crashes and you have to go back to R to look at it.

I understand why the error is occurring but I don't know if there's a way around it for my situation because I don't know if the events occur until the data is subset. The function is called a number of times in my code, so I don't want to write an if statement outside the function each time it is used.

I tried adding if(length(b$Department <= 1)){tab<-renderDataTable({datatable(NULL)})} right after defining b and then had an else statement around the remainder of the function, but I get the message Warning: Error in [.data.frame: undefined columns selected

I have also tried other if statements such as creating a dataframe full of NAs but this returned the original error message.

dept.table<-function(df, date1, date2){
  a<-df[which(DATE >= as.Date(date1) & DATE <= as.Date(date2)),]
  b<-as.data.frame(table((a[,c("Event", "Department")])))
  d<-reshape(b, direction="wide", idvar="Event", timevar="Department")
  names(d)<-sub('^Freq\\.', '', names(d)) 
  d$Total<-round(rowSums(d[,-1]), 0)
  levels(d$Event)<-c(levels(d$Event), "Total")
  d<-rbind(d, c("Total", colSums(d[,-1])))tab<-DT::renderDataTable({
  datatable(d, extensions="FixedColumns", options=list(dom='t', scrollX=T, fixedColumns=list(leftColumns=1, rightColumns=1)), rownames=FALSE)
 })
}

Sample data

 df<-data.frame(Department=rep(100:109, 3), Event=rep(c("A", "B", "C"),10),
     Date=sample(seq(as.Date('2018/01/01'), as.Date('2018/09/01'), by="day"), 30))
1

1 Answers

0
votes

It's not pretty, but I figured out a solution. There were two different issues. One when there was no data and another when there was only 2 departments, so I needed two if statements.

dept.table<-function(df, date1, date2)  {a<-df[DATE >= as.Date(date1) & DATE <= as.Date(date2)),]
   b<-as.data.frame(table((a[,c("Event", "Department")])))
   if(nrow(b)==0){tab<-DT::renderDataTable(NULL)}
   else{d<-reshape(b, direction="wide", idvar="CODE", timevar="Department")
        names(d)<-sub('^Freq\\.', '', names(d)) 
        if(ncol(d)>3){d$Total<-round(rowSums(d[,-1]), 0)
          levels(d$Event)<-c(levels(d$Event), "Total")
          d<-rbind(d, c("Total", colSums(d[,-1])))
          tab<-DT::renderDataTable({
               datatable(d, extensions="FixedColumns", options=list(dom='t', scrollX=T, fixedColumns=list(leftColumns=1, rightColumns=1)), rownames=FALSE)})}
        else{tab<-DT::renderDataTable(datatable(d))}
   }
 tab
}