ggplot2绘图出现错误: “由于纬度* pi而引起的错误”

huangapple go评论64阅读模式
英文:

Plotting with ggplot2 gives error: "Caused by error in lat * pi"

问题

以下是您提供的内容的翻译:

我正在尝试在我的RShiny应用程序中,当用户输入特定数据时,创建一个ggplot2的区域地图。如下所示,我将我的空间数据框与我的数据合并,我认为这样可以正常工作:

# 在RShiny应用程序中输入数据:
output$contents <- renderTable({
    file <- input$uploaded_data
    ext <- tools::file_ext(file$datapath)
    
    req(file)
    
    counties_and_trash <- read_csv(file$datapath)
    
    mean_each_type <- counties_and_trash %>%
      group_by(COUNTY) %>%
      summarise(mean_plastics = mean(PLASTICS, na.rm = TRUE),
                mean_papers = mean(PAPERS, na.rm = TRUE),
                mean_metals = mean(METALS, na.rm = TRUE))
})

# 合并spdf和数据:
spdf <- geojson_read('County_Boundaries_of_NJ.geojson',  what = "sp")
merged <- merge(spdf, mean_each_type, by.x = 'COUNTY', by.y = 'mean_plastics')

请注意,目前我只尝试在区域地图中绘制“mean_plastics”。其他两个(“mean_papers”和“mean_metals”)在此刻是不相关的。我尝试在RShiny应用程序中输出ggplot2的区域地图,如下所示:

output$plot <- renderPlot({
    ggplot(merged, aes(x = x, y = y)) + 
    geom_polygon(aes(fill = mean_plastics), data = mean_each_type, x = 'COUNTY', y = 'mean_plastics') +
    theme_void() +
    coord_map()
})

当我尝试输出时,出现以下错误:

警告:geom_polygon中出现问题,转换图形时出错。
ℹ 第一层中发生错误。
由于在`lat * pi`中出现错误:
!二进制运算符的非数值参数

我确定“output$plot...”代码块中有问题,但我不确定如何修复它。

如果需要更多信息,我可以提供。如果我没有解释得足够清楚,我为此道歉,这是我第一次进行更复杂的R项目。感谢任何和所有的帮助!

编辑:我已经添加了下面的最小可重现示例。

为了使代码正常工作,您只需下载以下链接的文件(下载的文件应该命名为“County_Boundaries_of_NJ.geojson”):

NJ县边界geojson的下载链接

以下是最小可重现代码:

library(shiny)
library(tidyverse)
library(ggplot2)
library(geojsonio)
library(broom)
library(sp)
library(sf)

ui <- fluidPage(
  fluidRow(
    h1(strong('NJ Beachsweep Mapping with R'), align = 'center'),
    column(6,
           # 这个空列只是为了将其他列放在正确的位置
    ),
    column(6,
           tableOutput("contents")
    ),
    mainPanel(
      plotOutput("plot")
    )
  )
)

server <- function(input, output, session) {
  counties_and_trash <- structure(list(COUNTY = c("Atlantic", "Atlantic", "Bergen", "Burlington", 
                                                  "Burlington", "Essex", "Middlesex", "Cape May", "Cape May", "Cape May", 
                                                  "Monmouth", "Monmouth", "Monmouth", "Monmouth", "Monmouth", "Monmouth", 
                                                  "Ocean"), PLASTICS = c(340, 300, 325, 467, 545, 354, 433, 325, 
                                                                         324, 653, 768, 457, 486, 944, 356, 457, 568), PAPERS = c(260, 
                                                                                                                                  210, 453, 223, 235, 356, 324, 274, 540, 346, 475, 462, 342, 354, 
                                                                                                                                  435, 346, 234), METALS = c(45, 35, 123, 124, 224, 124, 134, 342, 
                                                                                                                                                             230, 243, 324, 125, 323, 122, 334, 421, 401)), row.names = c(NA, 
                                                                                                                                                                                                                          -17L), spec = structure(list(cols = list(COUNTY = structure(list(), class = c("collector_character", 
                                                                                                                                                                                                                                                                                                        "collector")), PLASTICS = structure(list(), class = c("collector_double", 
                                                                                                                                                                                                                                                                                                                                                              "collector")), PAPERS = structure(list(), class = c("collector_double", 
                                                                                                                                                                                                                                                                                                                                                                                                                  "collector")), METALS = structure(list(), class = c("collector_double", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      "collector"))), default = structure(list(), class = c("collector_guess", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            "collector")), delim = ","), class = "col_spec"), class = c("spec_tbl_df", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        "tbl_df", "tbl", "data.frame"))
  mean_each_type <- counties_and_trash %>%
    group_by(COUNTY) %>%
    summarise(mean_plastics = mean(PLASTICS, na.rm = TRUE),
              mean_papers = mean(PAPERS, na.rm = TRUE),
              mean_metals = mean(METALS, na.rm = TRUE))
  
  output$contents <- renderTable({
    counties_and_trash
  })
  
  spdf <- geojson_read('County_Boundaries_of_NJ.geojson',  what = "sp") 
  merged <- merge(spdf, mean_each_type, by.x = 'COUNTY', by.y = 'mean_plastics')
  
  output$plot <- renderPlot({ # 这个代码块最有可能出现问题
    ggplot(merged, aes(x = x, y = y)) + 
      geom_polygon(aes(fill = mean_plastics)) +
      theme_void() +
      coord_map()
  })
}
shinyApp(ui = ui, server = server)

非常感谢!

英文:

I'm trying to create a ggplot 2 choropleth when the user inputs specific data in my RShiny app. I merged my spatial dataframe with my data as shown below, and I think that worked properly:

# inputting data in RShiny app:
output$contents &lt;- renderTable({
file &lt;- input$uploaded_data
ext &lt;- tools::file_ext(file$datapath)
req(file)
counties_and_trash &lt;- read_csv(file$datapath)
mean_each_type &lt;- counties_and_trash %&gt;%
group_by(COUNTY) %&gt;%
summarise(mean_plastics = mean(PLASTICS, na.rm = TRUE),
mean_papers = mean(PAPERS, na.rm = TRUE),
mean_metals = mean(METALS, na.rm = TRUE))
})
# merging spdf and data:
spdf &lt;- geojson_read(&#39;County_Boundaries_of_NJ.geojson&#39;,  what = &quot;sp&quot;)
merged &lt;- merge(spdf, mean_each_type, by.x = &#39;COUNTY&#39;, by.y = &#39;mean_plastics&#39;)

Please note that, as of right now, I'm only trying to plot "mean_plastics" in the choropleth. The other ones ("mean_papers" and "mean_metals") are irrelevant at the moment. I tried to output the ggplot2 choropleth plot in the RShiny app, as shown below:

output$plot &lt;- renderPlot({
ggplot(merged, aes(x = x, y = y)) + 
geom_polygon(aes(fill = mean_plastics), data = mean_each_type, x = &#39;COUNTY&#39;, y = &#39;mean_plastics&#39;) +
theme_void() +
coord_map()
})

When I try to output that, I get the following error:

Warning: Error in geom_polygon: Problem while converting geom to grob.
ℹ Error occurred in the 1st layer.
Caused by error in `lat * pi`:
! non-numeric argument to binary operator

I'm certain there's something wrong with the "output$plot..." block of code, but I'm not sure how to fix it.

If more information is needed, I can provide it. I apologize if I didn't explain it well enough, this is my first time doing a more complicated R project. Thank you for any and all help!

EDIT: I've added the minimal reproducible example below.

The only file you'll have to download for the code to work is at the following link (the downloaded file should have the name "County_Boundaries_of_NJ.geojson"):

download link for NJ county boundaries geojson

Here's the minimal reproducible code:

library(shiny)
library(tidyverse)
library(ggplot2)
library(geojsonio)
library(broom)
library(sp)
library(sf)
ui &lt;- fluidPage(
fluidRow(
h1(strong(&#39;NJ Beachsweep Mapping with R&#39;), align = &#39;center&#39;),
column(6,
# this empty column is just to put the other column in the right place
),
column(6,
tableOutput(&quot;contents&quot;)
),
mainPanel(
plotOutput(&quot;plot&quot;)
)
)
)
server &lt;- function(input, output, session) {
counties_and_trash &lt;- structure(list(COUNTY = c(&quot;Atlantic&quot;, &quot;Atlantic&quot;, &quot;Bergen&quot;, &quot;Burlington&quot;, 
&quot;Burlington&quot;, &quot;Essex&quot;, &quot;Middlesex&quot;, &quot;Cape May&quot;, &quot;Cape May&quot;, &quot;Cape May&quot;, 
&quot;Monmouth&quot;, &quot;Monmouth&quot;, &quot;Monmouth&quot;, &quot;Monmouth&quot;, &quot;Monmouth&quot;, &quot;Monmouth&quot;, 
&quot;Ocean&quot;), PLASTICS = c(340, 300, 325, 467, 545, 354, 433, 325, 
324, 653, 768, 457, 486, 944, 356, 457, 568), PAPERS = c(260, 
210, 453, 223, 235, 356, 324, 274, 540, 346, 475, 462, 342, 354, 
435, 346, 234), METALS = c(45, 35, 123, 124, 224, 124, 134, 342, 
230, 243, 324, 125, 323, 122, 334, 421, 401)), row.names = c(NA, 
-17L), spec = structure(list(cols = list(COUNTY = structure(list(), class = c(&quot;collector_character&quot;, 
&quot;collector&quot;)), PLASTICS = structure(list(), class = c(&quot;collector_double&quot;, 
&quot;collector&quot;)), PAPERS = structure(list(), class = c(&quot;collector_double&quot;, 
&quot;collector&quot;)), METALS = structure(list(), class = c(&quot;collector_double&quot;, 
&quot;collector&quot;))), default = structure(list(), class = c(&quot;collector_guess&quot;, 
&quot;collector&quot;)), delim = &quot;,&quot;), class = &quot;col_spec&quot;), class = c(&quot;spec_tbl_df&quot;, 
&quot;tbl_df&quot;, &quot;tbl&quot;, &quot;data.frame&quot;))
mean_each_type &lt;- counties_and_trash %&gt;%
group_by(COUNTY) %&gt;%
summarise(mean_plastics = mean(PLASTICS, na.rm = TRUE),
mean_papers = mean(PAPERS, na.rm = TRUE),
mean_metals = mean(METALS, na.rm = TRUE))
output$contents &lt;- renderTable({
counties_and_trash
})
spdf &lt;- geojson_read(&#39;County_Boundaries_of_NJ.geojson&#39;,  what = &quot;sp&quot;) 
merged &lt;- merge(spdf, mean_each_type, by.x = &#39;COUNTY&#39;, by.y = &#39;mean_plastics&#39;)
output$plot &lt;- renderPlot({ # this block of code is where the issue most likely is
ggplot(merged, aes(x = x, y = y)) + 
geom_polygon(aes(fill = mean_plastics)) +
theme_void() +
coord_map()
})
}
shinyApp(ui = ui, server = server)

Thank you so much!

答案1

得分: 0

你的代码存在多个问题,但与Shiny无关。首先,你读取的shapefile是一个sp对象。对于这种类型的对象,简单地合并数据或使用geom_polygon进行绘图是行不通的。相反,你应该将其转换为一个sf对象,它与标准数据框的行为几乎相同,并可以使用geom_sf轻松绘图。其次,按照mean_plastics进行合并是没有意义的,因为在空间数据集中没有这样的列。第三,合并只有在两个数据集中存在相同的关键字时才有效,不仅仅是相同的列名,也就是说,你必须将mean_each_type数据集中的COUNTY列转换为大写字母。否则,将找不到匹配项。

以下是翻译好的代码部分:

library(shiny)
library(tidyverse)
library(geojsonio)
library(sp)
library(sf)

ui <- fluidPage(
  fluidRow(
    h1(strong("NJ Beachsweep Mapping with R"), align = "center"),
    column(
      6,
      plotOutput("plot")
    ),
    column(
      6,
      tableOutput("contents")
    )
  )
)

server <- function(input, output, session) {
  mean_each_type <- counties_and_trash %>%
    group_by(COUNTY) %>%
    summarise(
      mean_plastics = mean(PLASTICS, na.rm = TRUE),
      mean_papers = mean(PAPERS, na.rm = TRUE),
      mean_metals = mean(METALS, na.rm = TRUE)
    ) %>%
    mutate(COUNTY = toupper(COUNTY))

  output$contents <- renderTable({
    counties_and_trash
  })

  spdf <- geojson_read("County_Boundaries_of_NJ.geojson", what = "sp")
  # 转换为 sf
  spdf <- sf::st_as_sf(spdf)

  merged <- merge(spdf, mean_each_type, by = "COUNTY")

  output$plot <- renderPlot({ # 这段代码中最可能存在问题的地方
    ggplot(merged) +
      # 使用 geom_sf
      geom_sf(aes(fill = mean_plastics)) +
      theme_void()
  })
}
shinyApp(ui = ui, server = server)

请注意,此翻译仅包括代码部分,不包括其他内容。

英文:

There are multiple issues with your code but none is related to shiny. First, the shapefile your read is a sp object. For this type of object neither simply merging your data nor plotting via geom_polygon works. Instead convert to a sf object which behave fairly identical to standard dataframes and which can be easily plotted using geom_sf. Second, merging on mean_plastics doesn't make sense as there is no such column in the spatial dataset. Third, merging will only work if there is an identical key in both datasets not just the same column name, i.e. you have to convert the COUNTY column to upper-case in the mean_each_type dataset. Otherwise there are no matches.

library(shiny)
library(tidyverse)
library(geojsonio)
library(sp)
library(sf)
ui &lt;- fluidPage(
fluidRow(
h1(strong(&quot;NJ Beachsweep Mapping with R&quot;), align = &quot;center&quot;),
column(
6,
plotOutput(&quot;plot&quot;)
),
column(
6,
tableOutput(&quot;contents&quot;)
)
)
)
server &lt;- function(input, output, session) {
mean_each_type &lt;- counties_and_trash %&gt;%
group_by(COUNTY) %&gt;%
summarise(
mean_plastics = mean(PLASTICS, na.rm = TRUE),
mean_papers = mean(PAPERS, na.rm = TRUE),
mean_metals = mean(METALS, na.rm = TRUE)
) |&gt;
mutate(COUNTY = toupper(COUNTY))
output$contents &lt;- renderTable({
counties_and_trash
})
spdf &lt;- geojson_read(&quot;County_Boundaries_of_NJ.geojson&quot;, what = &quot;sp&quot;)
# Convert to sf
spdf &lt;- sf::st_as_sf(spdf)
merged &lt;- merge(spdf, mean_each_type, by = &quot;COUNTY&quot;)
output$plot &lt;- renderPlot({ # this block of code is where the issue most likely is
ggplot(merged) +
# Use geom_sf
geom_sf(aes(fill = mean_plastics)) +
theme_void()
})
}
shinyApp(ui = ui, server = server)

ggplot2绘图出现错误: “由于纬度* pi而引起的错误”

huangapple
  • 本文由 发表于 2023年3月4日 05:34:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75632074.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定