2

I'm hoping someone can help me to figure out the issue with my code. I'm trying to figure out the issue with my code for like 5 hours and checked these links 1,2 but couldn't figure out the issue with my code I'm trying to build a Shiny app but when I run my code, I keep getting the error message:

Error: Problem with `mutate()` column `Date`.
ℹ `Date = ymd(Date)`.
x cannot coerce type 'closure' to vector of type 'character'

It looks like the issue is with creating the columns Date and Month but I have them in my data as you can see in this snapshot of my data :

enter image description here

This is my code for reading my data and wrangle data

#Read and wrangle data 
dvc_read <- st_read("/Users/Desktop/shap/accident_data.shp",  # shapefile stored in repo
  stringsAsFactors = FALSE  # read factor columns as character columns
) 


dvc_wrangle <- dvc_read %>% 
  st_transform(crs = 4326) %>%  # transform coords to latlong
  # decapitalise everything for easy handling
  rename_all(tolower) %>% 
  mutate_if(is.character, tolower) %>%  # simplify strings
  # deal with dates
  mutate(
    Date = ymd(Date), # the issue is with line 
    Month = case_when( # and this line
      Month == 1 ~  "Jan", Month == 2 ~  "Feb",
      Month == 3 ~  "Mar", Month == 4 ~  "Apr",
      Month == 5 ~  "May", Month == 6 ~  "Jun",
      Month == 7 ~  "Jul", Month == 8 ~  "Aug",
      Month == 9 ~  "Sep", Month == 10 ~ "Oct",
      Month == 11 ~ "Nov", Month == 12 ~ "Dec",
      TRUE ~ "Unknown"
    ),
    # clean up strings (not perfect)
    Severity = if_else(Severity %in% c("1", "2", "3"), "unknown", Severity),
    Accident.Description = if_else(Accident.Description == "Road closed", "Road_closed", Accident.Description),
    City = if_else(str_detect(City, "x") == TRUE, "unknown", City),
    City = if_else(
      City %in% c(
        "Brooklyn", "Jamaica", "Merrick", "Roosevelt", "unclassified",
      ), "unknown", City
    ),
    # final name tidy-up
    Accident.Description = str_replace_all(Accident.Description, "_", " ")
  ) %>% 
  # title case for these columns
  mutate_at(vars(Severity, Accident.Description, City), tools::toTitleCase) # To Title Case


###
# extract latlong cols from sf geometry and bind back to df
dvc_xy <- as.data.frame(st_coordinates(dvc_wrangle))
dvc <- bind_cols(dvc_wrangle, dvc_xy) %>% rename(latitude = X, longitude = Y)
saveRDS(dvc,"/Users/Desktop/shap/dvc.RDS")
dvc <- readRDS("data/dvc.RDS")

# Month order for dropdown input
mo_order <- c("Jan", "Feb", "Mar", "Apr", "May", "Jun",
              "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")

I'll add the Ui code and the server code just for a better understanding

The UI code:

ui <- dashboardPage(

  dashboardHeader(
    
    title = "Title",
    titleWidth = 450
  ),  # end dashboardHeader()
  
  dashboardSidebar(
    HTML("<br>"),
    
    box(
      title = "Filters",
      width = 12,
      background = "blue",
      collapsible = TRUE, collapsed = FALSE,
      selectInput(
        inputId = "input_year", 
        label = "Year",
        choices = sort(unique(dvc$Year)),
        multiple = TRUE,
        selected = sample(unique(dvc$Year), 1)
      ),
      selectInput(
        inputId = "input_month", 
        label = "Month",
        choices = unique(dvc$Month[order(match(dvc$Month, mo_order))]),
        multiple = TRUE,
        selected = sample(unique(dvc$Month), 3)
      ),
      selectInput(
        inputId = "input_la", 
        label = "Accident.Description",
        choices = sort(unique(dvc$Accident.Description)),
        multiple = TRUE,
        selected = sample(unique(dvc$Accident.Description), 3)
      )
    )  # end box()
  ),  # end dashboardSidebar()
  
  dashboardBody(
    
    fluidRow(
      valueBoxOutput("output_valueselection"),
      valueBoxOutput("output_valueyearla"),
      valueBoxOutput("output_valueyear"),
      tabBox(
        id = "tabset1",
        width = 12,
        tabPanel("Map", leafletOutput("output_map", height = "600px")),
        tabPanel("Table", dataTableOutput("output_table"))
      )
    )  # end fluidRow()
  )  # end dashboardBody()
  
)  # end of ui dashboardPage()

The server code:

server <- function(input, output) {
  
  # Value box - year
  output$output_valueyear <- renderValueBox({
    shinydashboard::valueBox(
      value = dvc %>% st_drop_geometry() %>% filter(Year %in% input$input_year) %>% count() %>% pull(),
      subtitle = "Collisions in selected year(s)",
      icon = icon("calendar", lib = "font-awesome"),
      color = "blue",
      width = 4
    )
  })  # end of renderValueBox
  
  # Value box - year by la
  output$output_valueyearla <- renderValueBox({
    shinydashboard::valueBox(
      value = dvc %>% st_drop_geometry() %>% filter(Year %in% input$input_year, Accident.Description %in% input$input_la) %>% count() %>% pull(),
      subtitle = "Collisions in selected LA(s) and year(s)",
      icon = icon("map-o", lib = "font-awesome"),
      color = "blue",
      width = 4
    )
  })  # end of renderValueBox
  
  # Value box - total in your selection
  output$output_valueselection <- renderValueBox({
    shinydashboard::valueBox(
      value = dvc %>% st_drop_geometry() %>% filter(Year %in% input$input_year, Month %in% input$input_month, Accident.Description %in% input$input_la) %>% count() %>% pull(),
      subtitle = "Collisions in selection",
      icon = icon("car", lib = "font-awesome"),
      color = "blue",
      width = 4
    )
  })  # end of renderValueBox
  
  # Interactive map with Leaflet
  output$output_map <- renderLeaflet({
    dvc %>%
      filter(
        Year %in% input$input_year,
        Month %in% input$input_month,
        Accident.Description %in% input$input_la
      ) %>% 
      leaflet() %>% 
      addProviderTiles(providers$OpenStreetMap) %>% 
      addAwesomeMarkers(
        icon = awesomeIcons(
          icon = "exclamation-circle",
          iconColor = "#FFFFFF",
          library = "fa",
          markerColor = "darkblue"
        ),
        popup = ~paste0(
          "<style>
            td, th {
              text-align: left;
              padding: 3px;
            }
            </style>",
          "<table>",
          "<tr>","<td>", "Date", "</td>", "<td>", Date, "</td>", "<tr>",
          "<tr>","<td>", "LA", "</td>", "<td>", Accident.Description, "</td>", "<tr>",
          "<tr>","<td>", "City", "</td>", "<td>", City, "</td>", "<tr>",
          "<tr>","<td>", "Species", "</td>", "<td>", Severity, "</td>", "<tr>",
          "</table>"
        )
      )
  })  # end of renderLeaflet
  
  # Interactive table with DT
  output$output_table <- renderDataTable({
    dvc %>% 
      st_drop_geometry() %>%
      filter(
        Year %in% input$input_year,
        Month %in% input$input_month,
        Accident.Description %in% input$input_la
      ) %>%
      select(
       Date = Date,
        Year = Year,
        Month = Month,
        `Accident.Description` = Accident.Description,
       City = City,
        `Severity` = Severity
      ) %>%
      datatable(
        filter = "top",
        extensions = c("Scroller", "Buttons"),  # scroll instead of paginate
        rownames = FALSE,  # remove row names
        style = "bootstrap",  # style
        width = "100%",  # full width
        height = "800px",
        options = list(
          deferRender = TRUE,
          # scroll
          scrollY = 300,
          scroller = TRUE,
          # button
          autoWidth = TRUE,  # column width consistent when making selections
          dom = "Blrtip",
          buttons =
            list(
              list(
                extend = "collection",
                buttons = c("csv", "excel"),  # download extension options
                text = "Download"  # text to display
              )
            )
        )  # end of options = list()
      )  # end of datatable() 
  })  # end of renderDataTable()
  
}  # end of server function

I really appreciate your help with this issue and fixing the bug I have in my code.


Update:

Here's my data using dput():

structure(list(lat = c(40.61955, 40.61955, 40.61955, 40.61955, 
40.61955, 40.61955), long = c(-74.02346, -74.02346, -74.02346, 
-74.02346, -74.02346, -74.02346), Year = c("2020", "2020", "2019", 
"2020", "2020", "2019"), Month = c("2", "11", "10", "9", "1", 
"9"), Day = c("6", "21", "26", "20", "11", "15"), Date = c("2020-02-06", 
"2020-11-21", "2019-10-26", "2020-09-20", "2020-01-11", "2019-09-15"
), Accident.Description = c("Right lane blocked", "Two lanes blocked", 
"Two lanes blocked", "Right lane blocked", "Right lane blocked", 
"One lane blocked"), Severity = c("3", "3", "3", "3", "3", "3"
), geometry = structure(list(structure(c(-74.02346, 40.61955), class = c("XY", 
"POINT", "sfg")), structure(c(-74.02346, 40.61955), class = c("XY", 
"POINT", "sfg")), structure(c(-74.02346, 40.61955), class = c("XY", 
"POINT", "sfg")), structure(c(-74.02346, 40.61955), class = c("XY", 
"POINT", "sfg")), structure(c(-74.02346, 40.61955), class = c("XY", 
"POINT", "sfg")), structure(c(-74.02346, 40.61955), class = c("XY", 
"POINT", "sfg"))), class = c("sfc_POINT", "sfc"), precision = 0, bbox = structure(c(xmin = -74.02346, 
ymin = 40.61955, xmax = -74.02346, ymax = 40.61955), class = "bbox"), crs = structure(list(
    input = "NAD83", wkt = "GEOGCRS[\"NAD83\",\n    DATUM[\"North American Datum 1983\",\n        ELLIPSOID[\"GRS 1980\",6378137,298.257222101,\n            LENGTHUNIT[\"metre\",1]]],\n    PRIMEM[\"Greenwich\",0,\n        ANGLEUNIT[\"degree\",0.0174532925199433]],\n    CS[ellipsoidal,2],\n        AXIS[\"latitude\",north,\n            ORDER[1],\n            ANGLEUNIT[\"degree\",0.0174532925199433]],\n        AXIS[\"longitude\",east,\n            ORDER[2],\n            ANGLEUNIT[\"degree\",0.0174532925199433]],\n    ID[\"EPSG\",4269]]"), class = "crs"), n_empty = 0L)), row.names = c(NA, 
6L), class = c("sf", "data.frame"), sf_column = "geometry", agr = structure(c(lat = NA_integer_, 
long = NA_integer_, Year = NA_integer_, Month = NA_integer_, 
Day = NA_integer_, Date = NA_integer_, Accident.Description = NA_integer_, Severity = NA_integer_), .Label = c("constant", "aggregate", 
"identity"), class = "factor"))

Update II:

Thank you all for helping! I really appreciate all the answers you gave me!! I fixed the issues with the code but I'm still facing issues with one column which is the "accident.description" column. Although I changed the name to be "accident" where I thought the dot caused the issue but couldn't figure it out. The error message for this column below:

Error: Problem with `mutate()` column `accident.description`.
ℹ `accident.description = if_else(...)`.
x object 'accident.description' not found

This is my updated code:

dvc_wrangle <- dvc_read %>% 
  st_transform(crs = 4326) %>%  # transform coords to latlong
  # decapitalise everything for easy handling
  rename_all(tolower) %>% 
  mutate_if(is.character, tolower) %>%  # simplify strings
  # deal with dates
  mutate(
    Date = ymd(date),
    Month = case_when(
      month == 1 ~  "Jan", month == 2 ~  "Feb",
      month == 3 ~  "Mar", month == 4 ~  "Apr",
      month == 5 ~  "May", month == 6 ~  "Jun",
      month == 7 ~  "Jul", month == 8 ~  "Aug",
      month == 9 ~  "Sep", month == 10 ~ "Oct",
      month == 11 ~ "Nov", month == 12 ~ "Dec",
      TRUE ~ "Unknown"
    ),
    # clean up strings (not perfect)
    Severity = if_else(severity %in% c("1", "2", "3"), "unknown", severity),
    accident.description = if_else(accident.description == "Road closed", "Road_closed", accident.description),
    City = if_else(str_detect(city, "x") == TRUE, "unknown", city),
    City = if_else(
      city %in% c(
        "Brooklyn", "Jamaica", "Merrick", "Roosevelt", "unclassified",
      ), "unknown", city
    ),
    # final name tidy-up
    Accident.Description = str_replace_all(Accident.Description, "_", " ")
  ) %>% 
  # title case for these columns
  mutate_at(vars(Severity, Accident.Description, City), tools::toTitleCase) # To Title Case

I changed the Road closed to be "road closed" and the name of the column to be "accident" like this but still getting the same error message:

   Accident = if_else(accident %in% c("Road closed", "Two lanes blocked", "One lane blocked"), "unknown", accident),

Update III:

Thank you all for all the help and support guys! You all are amazing! I fixed the code based on your notes and regarding Update II, I changed the "Accident.Description" column name on the LHS to be in the upper case instead of small case. However, I get a new error message:

Error in rename.sf(.tbl, !!!syms) : 
  internal error: can't find `agr` columns

This is the modified code:

dvc_wrangle <- dvc_read %>% 
  st_transform(crs = 4326) %>%  # transform coords to latlong
  # decapitalise everything for easy handling
  rename_all(tolower) %>% 
  mutate_if(is.character, tolower) %>%  # simplify strings
  # deal with dates
  mutate(
    Date = ymd(date),
    Month = case_when(
      month == 1 ~  "Jan", month == 2 ~  "Feb",
      month == 3 ~  "Mar", month == 4 ~  "Apr",
      month == 5 ~  "May", month == 6 ~  "Jun",
      month == 7 ~  "Jul", month == 8 ~  "Aug",
      month == 9 ~  "Sep", month == 10 ~ "Oct",
      month == 11 ~ "Nov", month == 12 ~ "Dec",
      TRUE ~ "Unknown"
    ),
    # clean up strings (not perfect)
    Severity = if_else(severity %in% c("1", "2", "3"), "unknown", severity),
    Accident.Description = if_else(accident.description == "Road closed", "Road_closed", accident.description),
    City = if_else(str_detect(city, "x") == TRUE, "unknown", city),
    City = if_else(
      city %in% c(
        "Brooklyn", "Jamaica", "Merrick", "Roosevelt", "unclassified",
      ), "unknown", city
    ),
    # final name tidy-up
    Accident.Description = str_replace_all(accident.description, "_", " ")
  ) %>% 
  # title case for these columns
  mutate_at(vars(Severity, Accident.Description, City), tools::toTitleCase) # To Title Case
Reta
  • 363
  • 3
  • 4
  • 15
  • Hello, can you add the code to remake a subset of your data with `dput()`? (see [here](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) for more info) – bretauv Jan 20 '22 at 09:14
  • I just updated my question and added the data. I'd really appreciate it if you could help me with the issue – Reta Jan 20 '22 at 15:37

2 Answers2

3

Diagnosis

Your issue is fairly simple. Once the Date column is renamed as date

  # decapitalise everything for easy handling
  rename_all(tolower) %>% 

then that problematic line

  # deal with dates
  mutate(
    Date = ymd(Date), # the issue is with line 

contains an expression ymd(Date) that refers to a nonexistent column Date.

So R searches outside the data mask for something named Date...and the first thing it finds is the function lubridate::Date(), which has (presumably) been loaded into your workspace as Date, via library(lubridate). Note that functions are also known as "closures" in R.

In that problematic expression

ymd(Date)

you are thus supplying a closure as input to ymd(), which expects a character vector. Hence the error:

x cannot coerce type 'closure' to vector of type 'character'

Solution

Simply alter your code to reference the date column, which is now lowercase.

  # deal with dates
  mutate(
    Date = ymd(date),
    #          ^^^^

Warning

As observed here by @bretauv, there are further errors later in your code. Some you can fix by making the same correction to other column names.

Greg
  • 3,054
  • 6
  • 27
  • thank you so much!! it worked with the other column but still having issues with the "accident.description" column. – Reta Jan 20 '22 at 17:34
  • @Reta Would you kindly update your `dvc_read` sample? – Greg Jan 20 '22 at 17:52
  • 1
    @Reta As for your **Update II**, I'm unable to reproduce that error. You *did* correct the code on the right hand side (RHS), so it refers to existing lowercase columns like `date` and `month` and `accident.description`. You've also kept the LHS in the uppercase convention: `Date =` and `Month =`; **but `accident.description =` is the odd one out**. Try changing the LHS to the uppercase `Accident.Description =`, while still keeping the lowercase `accident.description` on the RHS. – Greg Jan 20 '22 at 17:57
  • @Reta Any luck? – Greg Jan 21 '22 at 19:23
  • I changed the accident. description on LHS in the upper case as you see in the updated question, however, I still get the error message "Error in rename.sf(.tbl, !!!syms) : internal error: can't find `agr` columns". I don't have "agr" column and I'm searching for a similar post that talks about this error message but no luck. Do you have an idea of what could be the problem here? I really appreciate your help. – Reta Jan 23 '22 at 21:00
  • @Reta I'm unable to reproduce this error. I ran your sample dataset on your workflow from **Update III**, and it ran successfully! Maybe try reinstalling the **`sf`** package? – Greg Jan 24 '22 at 14:49
  • 1
    @Reta I found the issue [here](https://github.com/r-spatial/sf/issues/1483) on the **`sf`** GitHub page. It was supposedly [fixed](https://github.com/r-spatial/sf/commit/5e5268b798b84b1e26e18c9b0fa5aec72640fb40) in September 2020... – Greg Jan 24 '22 at 14:52
  • Thank you@Greg! I reinstalled the sf package, and I still have the issue. For the link, you shared, I don't know how to apply it. I have already updated the SF package and will keep looking for solutions. I really appreciate your help, Greg! – Reta Jan 24 '22 at 23:45
  • 1
    I think I know why I have this issue. I'm using shapefile data not CSV data. The sample dataset I provided you was CSV, but I'm using the shapefile format in my code.. when I try to run the data as CSV format, I get the error message: Error in UseMethod("st_transform") : no applicable method for 'st_transform' applied to an object of class "data.frame". Using shapefile format will assign the geometry type and the decoding CRS. Can I share with you the shapefile and try to run it on your end and see if it produced the same error I have. Thank you Greg! – Reta Jan 25 '22 at 01:02
  • @Reta It looks like the shapefile format has compatibility issues with `rename_all()`. Perhaps this should be posted as a separate question, complete with a `dput()` of your shapefile. Right now, I would suggest that you simply replace the line `replace_all(tolower)` with the line `\`names<-\`(tolower(names(.)))`. – Greg Jan 25 '22 at 01:18
  • 1
    I replaced "replace_all(tolower) with the line `names<-`(tolower(names(.)))" and I still face the same issue. I posted my question as a separate question here with the shapefile data sample https://stackoverflow.com/questions/70852093/error-in-rename-sf-tbl-syms-internal-error-cant-find-agr-columns. I hope I can get thoughts regarding the error message – Reta Jan 25 '22 at 16:23
2

You put every column name to lowercase with rename_all(tolower). Therefore, column Date doesn't exist but column date does. Replacing Date by date works.

You have to fix that for all other column names in mutate(). Also, you modify the variable City but it is not in the data you provide (perhaps you just forgot to include it).

I didn't run the app but this should fix your dplyr error.

bretauv
  • 7,756
  • 2
  • 20
  • 57