【问题标题】:R Shiny "non-numeric argument to binary operator" errorR Shiny“二进制运算符的非数字参数”错误
【发布时间】:2020-09-15 02:51:38
【问题描述】:

我正在制作一个简单的 Shiny 应用程序,它输入玩家的姓名和统计数据,然后返回玩家在该统计数据中的百分位数。我目前遇到“统计”小部件导致错误的问题(见标题)。

以下是我正在使用的包和数据示例:

library(shiny)
library(dplyr)
library(mosaic)

player <- c("John", "Mike", "Devon", "Greg", "Bruce", "Zachary", "Jack", "Graham", "Jordan", "Sandy")
team <- c("A", "B", "A", "B", "A", "B", "A", "B", "A", "B")
wins <- c(1:10)
losses <- c(10:1)

sampledata <- data.frame(player, team, wins, losses)

在应用程序上,有三个小部件:(1) 输入玩家姓名,(2) 选择统计数据,以及 (3) 执行选择。
输出是单行文本。
这是ui.r:

ui <- fluidPage(
  titlePanel("Percentile Generator"),
    sidebarLayout(
        sidebarPanel(
            textInput("playerfind",
                      "Player:",
                      value = "Devon"),
            selectInput("stat1", "Select Statistic:",
                        choices = list("wins", "losses", "ties"),
                        selected = "wins"),
            actionButton("action", label = "Generate Percentile!")
    ),
        mainPanel(
           textOutput("percentmachine")
        ))
    )

服务器有点复杂。第 1 步过滤 sample data 并根据输入生成一个 1x3 数据帧。第 2 步从矩阵中提取必要的值并将其存储。最后,第 3 步从第 2 步获取输入并生成一个百分位数。

server <- function(input, output) {
    step1 <- reactive({sampledata %>%
        transmute(player, stat = zscore(input$stat1)) %>%
        filter(player == input$playerfind)})

    step2 <- reactive({step1()[1,2]})

    step3 <- reactive({round(pnorm(step2())*100, digits = 1)})

    output$percentmachine <- renderText ({
        input$action
        isolate(paste(input$playerfind, 
                      "had more",
                      input$stat1,
                      "than",
                      step3(),
                      "percent of players."))})
}

我相信错误来自步骤 1 中的 input$stat1。如果我将此输入替换为特定的统计信息,例如“wins”,那么虽然无法更改统计信息,但闪亮的应用程序运行良好。我已经为此苦苦挣扎了一段时间,所以我想我会在这里问。

提前致谢! xD

【问题讨论】:

  • 您将character 值(input$stat1) 输入zscore,该函数需要numeric 输入。如果你尝试zscore("A"),你会得到同样的错误。
  • 此外,因为zscore 正在寻找数据分布以确定每个数据的 z 分数,也许您应该首先使用sampledata$z &lt;- zscore(sampledata$wins) 之类的东西计算您的 z 分数。 *耸耸肩*
  • 我无法想象zscore(some_strings) 的任何实例都可以工作,看看它的来源。也许您的 R 脚本正在提供不同的变量?您是否打算从数据中获取input$stat1 column 并将其放入其中?也许你的意思是zscore(sampledata[,input$stat1])? (除了框架没有"ties" 列...)
  • 我认为我正在从数据中访问该列,因为 sample data 已通过管道转换,尽管我没有!感谢您的澄清,如果您将该评论写为答案,我会将其标记为已解决:)

标签: r shiny reactive


【解决方案1】:

您将character 值输入到采用numeric 的函数中。

我将在闪亮/反应性环境之外进行模拟。

input <- list(playerfind="Devon", stat1="wins")
# I don't have mosaic installed
zscore <- function( x, na.rm=getOption("na.rm", FALSE) ) ( x - mean(x, na.rm=na.rm)) / sd(x, na.rm=na.rm)
sampledata %>%
  transmute(player, stat = zscore(input$stat1))
# Warning in mean.default(x, na.rm = na.rm) :
#   argument is not numeric or logical: returning NA
# Error in x - mean(x, na.rm = na.rm) (from #1) : 
#   non-numeric argument to binary operator

可以使用get 来解决这个问题:

sampledata %>%
  transmute(player, stat = zscore(get(input$stat1)))
#     player       stat
# 1     John -1.4863011
# 2     Mike -1.1560120
# 3    Devon -0.8257228
# 4     Greg -0.4954337
# 5    Bruce -0.1651446
# 6  Zachary  0.1651446
# 7     Jack  0.4954337
# 8   Graham  0.8257228
# 9   Jordan  1.1560120
# 10   Sandy  1.4863011

### which is effectively this
zscore(sampledata$wins)
#  [1] -1.4863011 -1.1560120 -0.8257228 -0.4954337 -0.1651446  0.1651446
#  [7]  0.4954337  0.8257228  1.1560120  1.4863011

(然后根据需要filter)。

解决此问题的另一种方法可能是矫枉过正,但如果它可以深入了解您项目中的其他操作,我们可以将数据从宽调整为长。由于我们已经在使用dplyr,我将包括tidyr

library(tidyr)

### this is just a demo of reshaping from wide to long
sampledata %>%
  pivot_longer(c(-player, -team), names_to = "winlose", values_to = "val")
# # A tibble: 20 x 4
#    player  team  winlose   val
#    <fct>   <fct> <chr>   <int>
#  1 John    A     wins        1
#  2 John    A     losses     10
#  3 Mike    B     wins        2
#  4 Mike    B     losses      9
#  5 Devon   A     wins        3
#  6 Devon   A     losses      8
#  7 Greg    B     wins        4
#  8 Greg    B     losses      7
#  9 Bruce   A     wins        5
# 10 Bruce   A     losses      6
# 11 Zachary B     wins        6
# 12 Zachary B     losses      5
# 13 Jack    A     wins        7
# 14 Jack    A     losses      4
# 15 Graham  B     wins        8
# 16 Graham  B     losses      3
# 17 Jordan  A     wins        9
# 18 Jordan  A     losses      2
# 19 Sandy   B     wins       10
# 20 Sandy   B     losses      1


### this is the actual work
sampledata %>%
  pivot_longer(c(-player, -team), names_to = "winlose", values_to = "val") %>%
  filter(winlose == input$stat1) %>%
  mutate(z = zscore(val))
# # A tibble: 10 x 5
#    player  team  winlose   val      z
#    <fct>   <fct> <chr>   <int>  <dbl>
#  1 John    A     wins        1 -1.49 
#  2 Mike    B     wins        2 -1.16 
#  3 Devon   A     wins        3 -0.826
#  4 Greg    B     wins        4 -0.495
#  5 Bruce   A     wins        5 -0.165
#  6 Zachary B     wins        6  0.165
#  7 Jack    A     wins        7  0.495
#  8 Graham  B     wins        8  0.826
#  9 Jordan  A     wins        9  1.16 
# 10 Sandy   B     wins       10  1.49 

【讨论】:

    【解决方案2】:

    根据this pagezscore 第一个参数(x)是一个数值向量。

    input$stat1 是字符。

    【讨论】:

    • 感谢您的及时回复。关于如何修复代码以产生所需输出的任何建议?卡在这个问题上很长一段时间了。
    猜你喜欢
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-16
    • 2015-10-09
    • 1970-01-01
    • 2016-07-23
    • 2016-11-15
    相关资源
    最近更新 更多