使用 Patchwork 时出现不一致错误(二元运算符的非数字参数)
Inconsistent Error (Non-Numeric Argument to Binary Operator) When Using Patchwork
我正在构建一个 Rshiny 应用程序,它接受用户输入并生成带有图表的 Rmd powerpoint 幻灯片。我基于我在 https://mattherman.info/blog/ppt-patchwork/ 找到的例子。当我尝试 运行 关闭 Matt Herman 博客的示例时,它会按预期生成 ppt。昨天,当我 运行 我的代码时,我不断收到错误消息“+ 中的错误:二元运算符的非数字参数”。我慢慢地将我的 graphs/charts/code 替换到示例代码中,并且能够生成没有错误的 ppt 幻灯片。我以为我没事了。
今天早上,我在打开和关闭 R 后再次尝试 运行 程序,现在我得到了与昨天相同的错误,尽管 Matt Herman 示例代码仍然 运行s完美。我认为这与拼凑包加载不正确有关,但我是 R 的新手,我不是 100% 确定。如果有人可以提供帮助,将不胜感激!这种不一致让我发疯。
(PS 我知道现在的代码有点草率——我在过去的尝试中添加了一些我可能不再需要的库,我正在写这篇文章并试图弄清楚这个拼凑的问题,所以对混乱表示歉意。)
闪亮应用代码:
library(config)
library(shiny)
library(dplyr)
library(DBI)
library(odbc)
library(ggplot2)
library(ggthemes)
library(convertr)
library(forcats)
library(gt)
library(gridExtra)
library(tidyr)
library(ggpubr)
library(plotly)
library(DT)
library(knitr)
library(rmarkdown)
library(tidyverse)
library(gapminder)
library(scales)
library(gridExtra)
library(patchwork)
conn_args <- config::get("dataconnection")
con <- dbConnect(odbc::odbc(),
Driver = conn_args$driver,
Server = conn_args$server,
UID = conn_args$uid,
PWD = conn_args$pwd,
Port = conn_args$port,
Database = conn_args$database
)
project_list <- dbGetQuery(con, "select projectname as project, report
from projectlist join project on project.id = projectlist.project
order by projectname")
map_data <- dbGetQuery(con, "select * from sitesubjectprojecttotal")
site_enrollment <- dbGetQuery(con, "select * from dashboard.all_enrollment_site_unlimited")
ui <- fluidPage(
selectInput(inputId = "projectname", "Select Project", project_list$project, selected = TRUE, multiple = FALSE, width=220),
dateRangeInput(inputId = "projectdate", "Select Date Range for Shipping and Enrollment Report", Sys.Date()-365, Sys.Date()),
downloadButton("mybutton","Download Data")
)
server <- function(input, output) {map_data_filtered <- reactive({filter(map_data, projectname == input$projectname)})
map_table <- reactive({map_data_filtered() %>% select(location, sites, subjects)})
map_plot <- reactive({map_data_filtered() %>% select(-projectname)})
site_enroll_plot <- reactive({filter(site_enrollment, projectname == input$projectname) %>%
pivot_longer(totalenroll:currentenroll, names_to = "enrolltype", values_to = "quantity")})
kit_status_qry <- reactive({dbGetQuery(con, paste0("select kitssent::integer-kitsavailable::integer as kitsused, kitsavailable::integer
from projectkitstatus where projectname ='", input$projectname, "'"))})
kit_status <- reactive({pivot_longer(kit_status_qry(), kitsused:kitsavailable, names_to = "kitstatus", values_to = "quantity")})
patch_status_qry <- reactive({dbGetQuery(con, paste0("select available::integer as qtyavailable, activated::integer as qtyactive, returned::integer as qtyreturned, expunused::integer as qtyexpunused
from projectpatchstatus where projectname ='", input$projectname, "'"))})
patch_status <- reactive({pivot_longer(patch_status_qry(), qtyavailable:qtyexpunused, names_to = "patchstatus", values_to = "quantity")})
output$mybutton = downloadHandler(
filename = 'PMProjectDashboard.pptx',
content = function(file) {
out = render('PMProjectDashboard.Rmd')
file.rename(out, file) # move pdf to file for downloading
},
contentType = NA
)
}
shinyApp(ui, server)
Markdown 文件的代码
---
title: "`r input$projectname` Project Metrics"
date: "`r Sys.Date()`"
output:
powerpoint_presentation:
reference_doc: "template.pptx"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(
echo = FALSE,
message = FALSE,
warning = FALSE,
fig.width = 12,
fig.height = 7
)
```{r}
library(tidyverse)
library(gapminder)
library(glue)
library(scales)
library(gridExtra)
library(patchwork)
library(config)
library(shiny)
library(odbc)
conn_args <- config::get("dataconnection")
con <- dbConnect(odbc::odbc(),
Driver = conn_args$driver,
Server = conn_args$server,
UID = conn_args$uid,
PWD = conn_args$pwd,
Port = conn_args$port,
Database = conn_args$database
)
map_data <- dbGetQuery(con, "select * from sitesubjectprojecttotal")
bar2 <- site_enroll_plot() %>%
ggplot(aes(x=sitename, y=quantity, fill = enrolltype)) + geom_col()
tab <- map_table() %>%
transmute(
`Location` = location,
`Sites` = sites,
`Subjects` = subjects,
) %>%
tableGrob(theme = ttheme_minimal(), rows = NULL)
pie1 <- ggplot(kit_status(), aes(x="", y=quantity, fill = kitstatus)) +
geom_bar(width=1, color = "white", stat = "identity") + coord_polar("y", start =0) +
theme_minimal() + ggtitle("Kit Status") + theme(legend.position = "bottom",
legend.box = "horizontal",
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank(),
plot.title = element_text(hjust = 0.5, family="sans")) +
labs(fill = NULL) + guides(fill=guide_legend(ncol=1)) +
geom_text(aes(label = quantity), position = position_stack(vjust = 0.5)) +
scale_fill_manual(NULL, labels = c("kitsavailable" = "Available",
"kitsused" = "Used"),
values = c("kitsavailable" = "gold1",
"kitsused" = "darkgoldenrod3"))
pie2 <- patchstatuspie <- ggplot(patch_status(), aes(x="", y=quantity, fill = patchstatus)) +
geom_bar(width=1, color = "white", stat = "identity") + coord_polar("y", start =0) +
theme_minimal() + ggtitle("Patch Status") + theme(legend.position = "bottom",
legend.box = "horizontal",
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank(),
plot.title = element_text(family="sans", hjust = 0.5)) +
labs(fill = NULL) + guides(fill=guide_legend(ncol=1)) +
geom_text(aes(label = quantity), position = position_stack(vjust = 0.5)) +
scale_fill_manual(NULL,
limits = c("qtyavailable", "qtyactive", "qtyreturned", "qtyexpunused"),
labels = c("qtyavailable" = "Available", "qtyactive" = "Used",
"qtyexpunused" = "Unused and Expired", "qtyreturned" = "Returned"),
values = c("qtyactive" = "darkgoldenrod3",
"qtyreturned" = "orange1", "qtyexpunused" = "orange2", "qtyavailable" = "gold1"))
pies <- ggarrange(pie1, pie2, nrow = 1, common.legend = TRUE, legend = "right")
layout <- (tab) / (pies + bar2)
layout +
plot_annotation(
title = paste0(input$projectname, " Metrics"),
caption = "*Accuracy of enrollment information dependent
on accurate marker entry in Portal.",
theme = theme(plot.title = element_text(size = 20, hjust = 0.5, face = "bold"))
)
解决方案(使用wrap_elements
)已经在评论中给出了,不愧为采纳答案。但我想补充一点,为什么这会产生稍微令人困惑的结果,这不是很明显。
有趣的是,是否需要 wrap_elements
似乎取决于元素添加到拼凑布局的顺序。
这来自 linked example code 作品(最后一步)
layout <- (bar + tab) / line
class(bar)
[1] "gg" "ggplot"
从非 gg
对象(如问题中的 tab
开始)会产生错误。
layout <- (tab + bar) / line
Error in e1 + e2 + plot_layout(ncol = 1) :
non-numeric argument to binary operator
class(tab)
[1] "gtable" "gTree" "grob" "gDesc"
有了 wrap_elements
,一切又恢复正常了,正如评论中所建议和验证的那样。
layout <- (wrap_elements(tab) + bar) / line
我正在构建一个 Rshiny 应用程序,它接受用户输入并生成带有图表的 Rmd powerpoint 幻灯片。我基于我在 https://mattherman.info/blog/ppt-patchwork/ 找到的例子。当我尝试 运行 关闭 Matt Herman 博客的示例时,它会按预期生成 ppt。昨天,当我 运行 我的代码时,我不断收到错误消息“+ 中的错误:二元运算符的非数字参数”。我慢慢地将我的 graphs/charts/code 替换到示例代码中,并且能够生成没有错误的 ppt 幻灯片。我以为我没事了。
今天早上,我在打开和关闭 R 后再次尝试 运行 程序,现在我得到了与昨天相同的错误,尽管 Matt Herman 示例代码仍然 运行s完美。我认为这与拼凑包加载不正确有关,但我是 R 的新手,我不是 100% 确定。如果有人可以提供帮助,将不胜感激!这种不一致让我发疯。
(PS 我知道现在的代码有点草率——我在过去的尝试中添加了一些我可能不再需要的库,我正在写这篇文章并试图弄清楚这个拼凑的问题,所以对混乱表示歉意。)
闪亮应用代码:
library(config)
library(shiny)
library(dplyr)
library(DBI)
library(odbc)
library(ggplot2)
library(ggthemes)
library(convertr)
library(forcats)
library(gt)
library(gridExtra)
library(tidyr)
library(ggpubr)
library(plotly)
library(DT)
library(knitr)
library(rmarkdown)
library(tidyverse)
library(gapminder)
library(scales)
library(gridExtra)
library(patchwork)
conn_args <- config::get("dataconnection")
con <- dbConnect(odbc::odbc(),
Driver = conn_args$driver,
Server = conn_args$server,
UID = conn_args$uid,
PWD = conn_args$pwd,
Port = conn_args$port,
Database = conn_args$database
)
project_list <- dbGetQuery(con, "select projectname as project, report
from projectlist join project on project.id = projectlist.project
order by projectname")
map_data <- dbGetQuery(con, "select * from sitesubjectprojecttotal")
site_enrollment <- dbGetQuery(con, "select * from dashboard.all_enrollment_site_unlimited")
ui <- fluidPage(
selectInput(inputId = "projectname", "Select Project", project_list$project, selected = TRUE, multiple = FALSE, width=220),
dateRangeInput(inputId = "projectdate", "Select Date Range for Shipping and Enrollment Report", Sys.Date()-365, Sys.Date()),
downloadButton("mybutton","Download Data")
)
server <- function(input, output) {map_data_filtered <- reactive({filter(map_data, projectname == input$projectname)})
map_table <- reactive({map_data_filtered() %>% select(location, sites, subjects)})
map_plot <- reactive({map_data_filtered() %>% select(-projectname)})
site_enroll_plot <- reactive({filter(site_enrollment, projectname == input$projectname) %>%
pivot_longer(totalenroll:currentenroll, names_to = "enrolltype", values_to = "quantity")})
kit_status_qry <- reactive({dbGetQuery(con, paste0("select kitssent::integer-kitsavailable::integer as kitsused, kitsavailable::integer
from projectkitstatus where projectname ='", input$projectname, "'"))})
kit_status <- reactive({pivot_longer(kit_status_qry(), kitsused:kitsavailable, names_to = "kitstatus", values_to = "quantity")})
patch_status_qry <- reactive({dbGetQuery(con, paste0("select available::integer as qtyavailable, activated::integer as qtyactive, returned::integer as qtyreturned, expunused::integer as qtyexpunused
from projectpatchstatus where projectname ='", input$projectname, "'"))})
patch_status <- reactive({pivot_longer(patch_status_qry(), qtyavailable:qtyexpunused, names_to = "patchstatus", values_to = "quantity")})
output$mybutton = downloadHandler(
filename = 'PMProjectDashboard.pptx',
content = function(file) {
out = render('PMProjectDashboard.Rmd')
file.rename(out, file) # move pdf to file for downloading
},
contentType = NA
)
}
shinyApp(ui, server)
Markdown 文件的代码
---
title: "`r input$projectname` Project Metrics"
date: "`r Sys.Date()`"
output:
powerpoint_presentation:
reference_doc: "template.pptx"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(
echo = FALSE,
message = FALSE,
warning = FALSE,
fig.width = 12,
fig.height = 7
)
```{r}
library(tidyverse)
library(gapminder)
library(glue)
library(scales)
library(gridExtra)
library(patchwork)
library(config)
library(shiny)
library(odbc)
conn_args <- config::get("dataconnection")
con <- dbConnect(odbc::odbc(),
Driver = conn_args$driver,
Server = conn_args$server,
UID = conn_args$uid,
PWD = conn_args$pwd,
Port = conn_args$port,
Database = conn_args$database
)
map_data <- dbGetQuery(con, "select * from sitesubjectprojecttotal")
bar2 <- site_enroll_plot() %>%
ggplot(aes(x=sitename, y=quantity, fill = enrolltype)) + geom_col()
tab <- map_table() %>%
transmute(
`Location` = location,
`Sites` = sites,
`Subjects` = subjects,
) %>%
tableGrob(theme = ttheme_minimal(), rows = NULL)
pie1 <- ggplot(kit_status(), aes(x="", y=quantity, fill = kitstatus)) +
geom_bar(width=1, color = "white", stat = "identity") + coord_polar("y", start =0) +
theme_minimal() + ggtitle("Kit Status") + theme(legend.position = "bottom",
legend.box = "horizontal",
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank(),
plot.title = element_text(hjust = 0.5, family="sans")) +
labs(fill = NULL) + guides(fill=guide_legend(ncol=1)) +
geom_text(aes(label = quantity), position = position_stack(vjust = 0.5)) +
scale_fill_manual(NULL, labels = c("kitsavailable" = "Available",
"kitsused" = "Used"),
values = c("kitsavailable" = "gold1",
"kitsused" = "darkgoldenrod3"))
pie2 <- patchstatuspie <- ggplot(patch_status(), aes(x="", y=quantity, fill = patchstatus)) +
geom_bar(width=1, color = "white", stat = "identity") + coord_polar("y", start =0) +
theme_minimal() + ggtitle("Patch Status") + theme(legend.position = "bottom",
legend.box = "horizontal",
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank(),
plot.title = element_text(family="sans", hjust = 0.5)) +
labs(fill = NULL) + guides(fill=guide_legend(ncol=1)) +
geom_text(aes(label = quantity), position = position_stack(vjust = 0.5)) +
scale_fill_manual(NULL,
limits = c("qtyavailable", "qtyactive", "qtyreturned", "qtyexpunused"),
labels = c("qtyavailable" = "Available", "qtyactive" = "Used",
"qtyexpunused" = "Unused and Expired", "qtyreturned" = "Returned"),
values = c("qtyactive" = "darkgoldenrod3",
"qtyreturned" = "orange1", "qtyexpunused" = "orange2", "qtyavailable" = "gold1"))
pies <- ggarrange(pie1, pie2, nrow = 1, common.legend = TRUE, legend = "right")
layout <- (tab) / (pies + bar2)
layout +
plot_annotation(
title = paste0(input$projectname, " Metrics"),
caption = "*Accuracy of enrollment information dependent
on accurate marker entry in Portal.",
theme = theme(plot.title = element_text(size = 20, hjust = 0.5, face = "bold"))
)
解决方案(使用wrap_elements
)已经在评论中给出了,不愧为采纳答案。但我想补充一点,为什么这会产生稍微令人困惑的结果,这不是很明显。
有趣的是,是否需要 wrap_elements
似乎取决于元素添加到拼凑布局的顺序。
这来自 linked example code 作品(最后一步)
layout <- (bar + tab) / line
class(bar)
[1] "gg" "ggplot"
从非 gg
对象(如问题中的 tab
开始)会产生错误。
layout <- (tab + bar) / line
Error in e1 + e2 + plot_layout(ncol = 1) :
non-numeric argument to binary operator
class(tab)
[1] "gtable" "gTree" "grob" "gDesc"
有了 wrap_elements
,一切又恢复正常了,正如评论中所建议和验证的那样。
layout <- (wrap_elements(tab) + bar) / line