【问题标题】:R Shiny Object not found - Evaluating a strings as codeR Shiny Object not found - 将字符串评估为代码
【发布时间】:2021-04-15 18:43:24
【问题描述】:

我正在尝试创建一个闪亮的应用程序,该应用程序在数据帧的列中获取字符串,这些字符串是 R 代码片段,并根据应用程序中生成的数据帧评估这些字符串。下面是闪亮应用程序 outside 代码的工作表示:

## create df with eval expressions
code_df <- data.frame(desired_outcome = c("this should be true", 
                                          "this should be false", 
                                          "this will be true or false"),
                      code_string = c('nrow(random_df) > 0', 
                                      'nrow(random_df) == 0', 
                                      'nrow(random_df) >= 100'),
                      stringsAsFactors = F)

# generate a dataframe with 1-150 rows
random_df <- data.frame(rand_binary = sample(0:1,sample(1:150, 1),rep=TRUE))

## helper function for sapply
eval_parse <- function(x){
  eval(parse(text = x))
}

## evaluate code strings
tf_vector <- sapply(code_df$code_string, eval_parse)

## add data to original df
code_df$nrow <- nrow(random_df)
code_df$tf <- tf_vector

code_df

如果您运行上面的代码,它将生成一个包含 1-150 行的“random_df”,然后评估来自 code_df 的代码字符串。此代码按预期工作。

当我尝试以闪亮的方式实现它时出现问题(下面的代码),当单击操作按钮时,实现返回“错误:对象'random_df'未找到”。

另一个问题:如果你先运行非闪亮的reprex代码,并且在运行闪亮的应用程序之前不清理环境,应用程序将返回表格,但它会评估代码基于非闪亮“random_df”的字符串,而不是闪亮应用程序中新随机生成的字符串。您可以根据“nrow”列的值会发生变化而“tf”不会发生变化这一事实来看到这一点。

服务器.R

library(shiny)

code_df <- data.frame(desired_outcome = c("this should be true", "this should be false", "this will be true or false"),
                      code_string = c('nrow(random_df) > 0', 'nrow(random_df) == 0', 'nrow(random_df) >= 100'),
                      stringsAsFactors = F)

## helper function for sapply
eval_parse <- function(x){
  
  eval(parse(text = x))
}


# Define server logic required to draw a histogram
shinyServer(function(input, output) {

  
  new_code_df <- eventReactive(input$newDF,{
    
    # create data.frame
    random_df <- data.frame(rand_binary = sample(0:1,sample(1:150, 1),rep=TRUE))
    
    ##
    tf_vector <- sapply(code_df$code_string, eval_parse)
    
    code_df$nrow <- nrow(random_df)
    code_df$tf <- tf_vector
    code_df
    
  })
  
  output$randomdf <- renderTable({new_code_df()})

})

ui.R

#
# This is the user-interface definition of a Shiny web application. You can
# run the application by clicking 'Run App' above.
#
# Find out more about building applications with Shiny here:
#
#    http://shiny.rstudio.com/
#

library(shiny)

# Define UI for application that draws a histogram
shinyUI(fluidPage(

    # Application title
    titlePanel("Eval Code from Data Frame"),
    
    sidebarLayout(
      sidebarPanel(
        actionButton("newDF","Generate New Dataframe")
        
      ),
      
      mainPanel(
        tableOutput('randomdf')
      )
      
    )
    
))

【问题讨论】:

  • 您必须将环境(您的 df 所在的位置)提供给 eval 的 envir 参数

标签: r shiny


【解决方案1】:

R 中的函数(因此是闪亮的)是词法范围的。这意味着函数只能看到在定义它们自己的环境中定义的变量。您在全局环境中定义eval_parse,但random_df 是在闪亮的服务器函数中定义的。前者看不到后者,因为random_df 不像您的非闪亮示例那样处于全局环境中。

如果您想让所有服务器变量都可用于您的表达式,您可以为eval() 指定一个环境。首先更改助手,以便您可以传递环境

eval_parse <- function(x, env=parent.frame()){
  eval(parse(text = x), envir=env)
}

然后更改您的服务器代码以传递函数环境

tf_vector <- sapply(code_df$code_string, eval_parse, env=environment())

【讨论】:

  • 效果很好!感谢您的解释,我知道我缺少有关 R 如何执行此操作的基本信息,但我的 google foo 在这方面失败了。
猜你喜欢
  • 2017-05-26
  • 2014-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-06
  • 2022-01-19
  • 1970-01-01
相关资源
最近更新 更多