I receive a strange error NAs not permitted in row index
My error is traditionally is somewhere between subseting/reactivity/outputting
# Load packages
library(shiny)
library(rgdal)
library(raster)
library(leaflet)
library(sp)
library(geojsonio)
library(RColorBrewer)
library(jsonlite)
library(shinythemes)
# Global code
# Read file on a local machine
data_pg <- read.csv("pg.csv", header = TRUE, stringsAsFactors = FALSE)
# Read a shapefile
countries <- readOGR(".","ne_50m_admin_0_countries")
# Merge data
data_pg_df <- merge(countries, data_pg, by.x = "NAME", by.y = "Country", duplicateGeoms = TRUE)
# Color palette
pal <- colorFactor(
palette = 'Dark2',
domain = data_pg_df$Region
)
# UI code
ui <- fluidPage(theme = shinytheme("united"),
titlePanel("PG Map"),
sidebarLayout(
sidebarPanel(
selectInput("regionInput", "Region",
choices = c("Choose region",
"Africa",
"Asia",
"Latin America",
"North America",
"Europe"),
selected = "Choose region"),
selectInput("pgInput", "Select PG",
choices = c("Choose PG",
"PG 1",
"PG 2",
"PG 3"),
selected = "Choose PG")
),
mainPanel(
# Output
tabsetPanel(type = "tabs",
tabPanel("Map", leafletOutput(outputId = 'map', height = 700)) #,
# tabPanel("Chart", plotOutput("chart")),
# tabPanel("Table", tableOutput("table"))
)
)
)
)
# Server
server <- function(input, output) {
selectedRegion <- reactive({
data_pg_df[data_pg_df$Region == input$regionInput, ]
})
output$map <- renderLeaflet({
leaflet(data_pg_df) %>%
addProviderTiles(providers$Stamen.Toner) %>%
addPolygons(stroke = FALSE,
fillOpacity = 0.75,
color = pal(selectedRegion()), weight = 1)
})
}
shinyApp(ui = ui, server = server)
So, either I subset in a wrong way. Or mess up with reactivity. Or my output is wrong.
I updated the code, but the error continues with NAs
# Global code
# Read file on a local machine
data_pg <- read.csv("pg.csv", header = TRUE, stringsAsFactors = FALSE)
# Read a shapefile
countries <- readOGR(".","ne_50m_admin_0_countries")
# Merge data
data_pg_df <- merge(countries, data_pg, by.x = "name", by.y = "Country",
duplicateGeoms = TRUE)
# UI code
ui <- fluidPage(theme = shinytheme("united"),
titlePanel("PG Map"),
sidebarLayout(
sidebarPanel(
selectInput("regionInput", "Region",
choices = c("Choose region",
"Africa",
"Asia",
"Latin America",
"North America",
"Europe"),
selected = "Choose region"),
selectInput("pgInput", "Select PG",
choices = c("Choose PG",
"PG 1",
"PG 2",
"PG 3"),
selected = "Choose PG")
),
mainPanel(
# Output
tabsetPanel(type = "tabs",
tabPanel("Map", leafletOutput(outputId = 'map', height = 700)) #,
# tabPanel("Chart", plotOutput("chart")),
# tabPanel("Table", tableOutput("table"))
)
)
)
)
# Server
server <- function(input, output) {
output$map <- renderLeaflet({
leaflet(data_pg_df) %>%
addProviderTiles(providers$Stamen.TonerLite) %>%
setView(11.0670977,0.912484, zoom = 4)
})
selectedRegion <- reactive({
data_pg_df[data_pg_df$Region == input$regionInput, ]
})
observe({
state_popup <- paste0("<strong>Region: </strong>",
selectedRegion()$Region,
"<br><strong> Client name: </strong>",
selectedRegion()$Client.name,
"<br><strong> Country: </strong>",
selectedRegion()$Country,
"<br><strong> PG: </strong>",
selectedRegion()$PG)
leafletProxy("map", data = selectedRegion()) %>%
clearShapes() %>%
addPolygons(fillColor = "blue",
popup = state_popup,
color = "#BDBDC3",
fillOpacity = 0.5,
weight = 1
)
})
}
shinyApp(ui = ui, server = server)
Resolved with a help of R community perfectly.
Treating NAs was a key:
"If you look at data_pg_df$Region, you'll see it has many NAs:
> data_pg_df$Region
[1] NA NA NA NA NA
[6] NA NA NA "Latin America" NA
[11] NA NA NA NA NA
[16] NA NA NA NA NA
[21] NA NA NA NA NA
[26] NA NA NA NA NA
[31] NA NA NA NA NA
[36] NA NA NA "North America" NA
[41] NA "Asia" NA NA NA
[46] NA NA NA NA NA
[51] NA NA NA NA NA
[56] NA NA "Europe" NA NA
[61] NA NA NA NA NA
...
With data_pg_df$Region == input$regionInput, you're comparing it to a value, like "Asia". In R, if you compare a value to NA, you get NA.
> data_pg_df$Region == "Asia"
[1] NA NA NA NA NA NA NA NA FALSE NA NA NA NA
NA NA
[16] NA NA NA NA NA NA NA NA NA NA NA NA NA
NA NA
[31] NA NA NA NA NA NA NA NA FALSE NA NA TRUE NA
NA NA
[46] NA NA NA NA NA NA NA NA NA NA NA NA FALSE
NA NA
[61] NA NA NA NA NA NA NA NA NA NA NA NA NA
NA NA
...
And you can't index into data_pg_df object using NA.
You'll need to handle the NAs somehow. I don't know for sure what's appropriate for your data set, but it looks like you might want to keep only the rows where == resolves to TRUE, and drop the rows which would result in NA and FALSE. To do this, you can add in a check with is.na():
!is.na(data_pg_df$Region) & data_pg_df$Region == "Asia"
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
FALSE FALSE
[16] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
FALSE FALSE
[31] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
FALSE FALSE
[46] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
FALSE FALSE
[61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
FALSE FALSE
...
So then you'd have:
selectedRegion <- reactive({
data_pg_df[!is.na(data_pg_df$Region) & data_pg_df$Region == input$regionInput, ]
})