r语言 - 闪亮的弹性仪表板中的facet_grid给出错误"Faceting variables must have at least one value"



我在为评估系统获取ggplot2facet_grid图时遇到一些问题。该图渲染良好,但我在浏览器和控制台中收到以下错误:

中的错误:Faceting变量必须至少有一个值

每当我基于输入input$brand切换品牌条目时,就会发生这种情况。应用程序没有崩溃,但错误消息令人讨厌。

我准备了这个可复制的例子:

---
title: "Power ranking for mtcars"
runtime: shiny
output:
flexdashboard::flex_dashboard:
orientation: rows
source_code: embed
---

```{r rows.print = 25}
library(dplyr)
library(ggplot2)
mtcars_tidy <- mtcars %>% 
tibble::rownames_to_column() %>% 
rename(model = rowname) %>% 
mutate(brand = gsub( " .*$", "", model )) %>% 
mutate(model = model) %>% 
select(brand, model,  everything())  %>% 
tidyr::gather(key = 'measure', value = "value", mpg:carb) %>%
mutate(ranking = as.factor(sample(x = c(1, 2, 3), size = n(), replace = TRUE))) %>%
mutate(power = case_when(
.$measure == "hp" & value > 200 | (.$measure == "cyl" & value == 8) ~ "high",
.$measure == "hp" & value < 200 | (.$measure == "cyl" & value == 8) ~ "medium",
.$measure == "hp" & value > 100 | (.$measure == "cyl" & value == 6) ~ "high",
.$measure == "hp" & value < 100 | (.$measure == "cyl" & value == 6) ~ "medium",
.$measure == "hp" & value > 50  | (.$measure == "cyl" & value == 6) ~ "high",
.$measure == "hp" & value < 50  | (.$measure == "cyl" & value == 6) ~ "medium",
.$measure == "hp" & value > 200 | (.$measure == "carb" & value >  4) ~ "high",
.$measure == "hp" & value < 200 | (.$measure == "carb" & value <= 4) ~ "medium",
.$measure == "hp" & value > 100 | (.$measure == "carb" & value >  2.8) ~ "high",
.$measure == "hp" & value < 100 | (.$measure == "carb" & value <= 2.8) ~ "medium",
.$measure == "hp" & value > 50  | (.$measure == "carb" & value > 2) ~ "high",
.$measure == "hp" & value < 50  | (.$measure == "carb" & value <= 2) ~ "medium",
TRUE ~ "low"
)) 
```
# Sidebar {.sidebar data-width="350"}
```{r}
selectInput("brand", "Brand of the car", 
choices = unique(mtcars_tidy$brand))
renderUI({
selectInput("model", "Car model",
choices = mtcars_tidy$model[mtcars_tidy$brand == levels(mtcars_tidy$brand)[1]])
})
br()
observe({
brand <- input$brand
updateSelectInput(session, "model", 
choices = mtcars_tidy$model[mtcars_tidy$brand == brand])
})    

# when switching the brand of the car, input$brand this error pops up:
# Error in : Faceting variables must have at least one value
```

# Main
##
### Plot power ranking for each measure
```{r}
nameorder <- make.unique(mtcars_tidy$measure[order(mtcars_tidy$power, mtcars_tidy$ranking)])
mtcars_tidy$measure <- factor(mtcars_tidy$measure, levels=nameorder, 
ordered = TRUE)
dataset <- reactive({
subset(mtcars_tidy, brand == input$brand & model == input$model) 
})

renderPlot({
ggplot(dataset(), aes(x = ranking, y = measure)) +
geom_segment(aes(yend = measure), xend=0, color = "grey50") +
geom_point(size = 3, aes(colour = power)) +
scale_colour_brewer(palette="Set1", limits = c("high","medium", "low")) +
theme_bw() +
theme(panel.grid.major.y = element_blank()) +   # No horizontal grid lines
facet_grid(power ~ ., scales="free_y", space="free_y") +
ggtitle(paste0("Brand: ", input$brand, ", Model: " , input$model))
})    
```

编辑1:我将facet_grid更改为facet_wrap,但错误仍然存在。

编辑2:根据建议,我切换到facet_wrap,公式为:p <- p + facet_wrap(power ~ .)。还是同样的错误。我也试过其他配方p <- p + facet_wrap(power ~ ranking)。错误仍然存在。

EDIT 3:在facet_wrap函数上,我也尝试了以下公式:

  • facet_wrap(~power )
  • facet_wrap(vars(power ))
  • CCD_ 11

错误仍然相同(完全相同(。无变化(Error in : Faceting variables must have at least one value(。

EDIT 4:如果我尝试使用facet_wrap(power),错误会更严重,因为Shiny会因为这个口而崩溃:

Error: Column `function (lambda = 1) n{n    if (!is.numeric(lambda) || is.na(lambda)) n        stop("invalid argument 'lambda'")n    if (lambda <= 0) n        return(make.link("log"))n    if (lambda == 1) n        return(make.link("identity"))n    linkfun <- function(mu) mu^lambdan    linkinv <- function(eta) pmax(eta^(1/lambda), .Machine$double.eps)n    mu.eta <- function(eta) pmax((1/lambda) * eta^(1/lambda - n        1), .Machine$double.eps)n    valideta <- function(eta) all(is.finite(eta)) && all(eta > n        0)n    link <- paste0("mu^", round(lambda, 3))n    structure(list(linkfun = linkfun, linkinv = linkinv, mu.eta = mu.eta, n        valideta = valideta, name = link), class = "link-glm")n}` must be a 1d atomic vector or a list

dataset()中没有行时会发生此错误。当我运行您的代码(当前版本的facet_grid(power ~ .,(时,它实际上工作得很好。当我选择一个新品牌时,在input$model列表更新时,它会显示此错误。一旦这样做,并且brandmodel的组合返回行,绘图就会很好地显示出来。

可以使用req推迟渲染绘图,直到满足某些要求,以防止出现此间隙。只需在renderPlot的顶部插入以下代码

req(nrow(dataset()) > 0)

如果dataset()不包含至少一行,这将阻止renderPlot运行。在这种情况下,绘图将是空白的(删除可怕的错误消息(,直到数据可以使用为止。加上这一行,你的应用程序似乎运行得很好(顺便说一句,看起来也很好(。


您可以通过在shiny上下文之外测试代码来查看错误消息的来源。以下是您的绘图的一个最小示例:

ggplot(dataset, aes(x = ranking, y = measure)) +
geom_segment(aes(yend = measure), xend=0, color = "grey50") +
geom_point(size = 3, aes(colour = power)) +
facet_grid(power ~ ., scales="free_y", space="free_y")

当我使用这个调用进行dataset时:

dataset <- subset(mtcars_tidy, brand == 'Honda' & model == 'Honda Civic')

绘图渲染正确。当我使用不返回任何行的subset时:

dataset <- subset(mtcars_tidy, brand == 'Honda' & model == 'Civic')

我得到了你同样的错误:

Error: Faceting variables must have at least one value

最新更新