首页 > 解决方案 > 函数/应用程序在 RStudio 本地工作,但不在 shinyapps.io 上工作

问题描述

我正在尝试创建一个闪亮的应用程序,可以使用 Saint Lague 方法将选票转换为席位。可以在此处找到有关确切过程的说明(https://www.bundeswahlleiter.de/en/service/glossar/s/sainte-lague-schepers.html)。为此,我创建了自己的函数saint_lague来进行这种转换。当我在 RStudio 中本地运行应用程序时,按下按钮后我得到正确的转换Calculate并且数据表正确显示。但是,当我在 上运行应用程序时shinyapps.io,我收到以下错误消息:

Warning: Error in : Problem with `mutate()` column `seats`.
ℹ `seats = saint_lague(votes = votes, seats_tar = first(seats_state))`.
✖ Missing values where TRUE/FALSE needed
[No stack trace available]

我已经将应用程序减少到最低限度,以便能够尽可能地限制错误。可以找到一个可重复的示例。

我使用的包:

library(DT)
library(shiny)
library(tidyverse)

我使用的自定义函数:

# function for exact rounding
round_pre <- function(x) {
        posneg = sign(x)
        z = abs(x) * 10 ^ 0
        z = z + 0.5 + sqrt(.Machine$double.eps)
        z = trunc(z)
        z = z / 10 ^ 0
        z * posneg
    }

# finding a new divisor from a span
new_div <- function(div_range, descen) {
    divis <-
        Rfast::nth(
            x = div_range,
            k = 2,
            num.of.nths = 2,
            descending = descen
        ) %>%
        as.vector() %>%
        sort()
    
    divis_med <- median(divis)
    
    digit <- -6
    divis_r <- round(x = divis_med, digits = digit)
    new_div <- NULL
    
    while (is.null(new_div)) {
        if (divis_r > divis[1] & divis_r <= divis[2]) {
            new_div <- divis_r
        } else{
            digit <- digit + 1
            divis_r <- round(x = divis_med, digits = digit)
        }
    }
    
    return(new_div)
}

# saint lague function (calculation from votes to seats)
saint_lague <- function(votes, seats_tar) {
    divisor <- sum(votes, na.rm = TRUE) / seats_tar
    
    seats <- round_pre(votes / divisor)
    
    while (sum(seats) > seats_tar) {
        divisor_0.5 <- votes / (seats - 0.5)
        divisor_1.5 <- votes / (seats - 1.5)
        divisor_0.5 <- ifelse(divisor_0.5 < 0, NA, divisor_0.5)
        divisor_1.5 <- ifelse(divisor_1.5 < 0, NA, divisor_1.5)
        divisor <-
            new_div(div_range = c(divisor_0.5, divisor_1.5),
                    descen = FALSE)
        seats <- round_pre(votes / divisor)
    }
    
    while (sum(seats) < seats_tar) {
        divisor_0.5 <- votes / (seats + 0.5)
        divisor_1.5 <- votes / (seats + 1.5)
        divisor_0.5 <- ifelse(divisor_0.5 < 0, NA, divisor_0.5)
        divisor_1.5 <- ifelse(divisor_1.5 < 0, NA, divisor_1.5)
        divisor <-
            new_div(div_range = c(divisor_0.5, divisor_1.5),
                    descen = TRUE)
        seats <- round_pre(votes / divisor)
    }
    
    return(seats)
}

我使用的数据:

df <-
    tibble(
        votes = c(119566, 388399, 64238, 220039, 322763, 494055, 55578),
        seats_state = 22
    )

闪亮的应用程序:

# ui
ui <-
    fluidPage(sidebarLayout(sidebarPanel(
        actionButton(inputId = "calc", label = "Calculate")
    ), mainPanel(DTOutput(outputId = "seats"))))

# server
server <- function(input, output) {
    observeEvent(input$calc, {
        df_out <-
            df %>%
            mutate(seats = saint_lague(votes = votes, seats_tar = first(seats_state)))
        output$seats <- renderDT(df_out)
    })
    
}

# Run the application
shinyApp(ui = ui, server = server)

标签: rshinyshinyapps

解决方案


推荐阅读