首页 > 解决方案 > 如何通过输入键在 Shiny 中加入两个反应数据帧?

问题描述

我有两个反应性数据框(出于解释目的,我正在创建模拟数据框),我需要使用输入字段作为键将它们加入闪亮。

library(shiny)
library(tidyverse)
df <- data.frame(key1=c(1:4),key2 = c(5:8),
                 left= c("l1", "l2", "l3", "l4"),
                 right = c("r1", "r2", "r3", "r4"))
left_df <- df[,1:3]
right_df <- df[,c(1:2,3)]

ui <- fluidPage(

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            selectInput("key_right", "Right Key", c("key1", "key2")),
            selectInput("key_left", "Right Key", c("key1", "key2"))
        ),

        mainPanel(
           tableOutput("final_data")
        )
    )
)


server <- function(input, output) {
    
    left_df2 <- reactive({
        left_df
    })
    
    rightt_df2 <- reactive({
        right_df
    })
    
     final_df <- reactive({
         left_df2() %>%
             left_join(right_df2(), by = c(input$key_right = input$key_left))
    })
     
     output$final_data <- reactive({
         final_df()
     })

}

我收到此错误:

Error in parse(file, keep.source = FALSE, srcfile = src, encoding = enc) : 
  /app.R:37:60: unexpected '='
36:          left_df2() %>%
37:              left_join(right_df2(), by = c(input$key_right =
Error in sourceUTF8(fullpath, envir = new.env(parent = sharedEnv)) : 

我需要通过 key1 或 key2 执行连接,这应该是用户输入,因为用户有可能上传文件并且可能有一个键或另一个键。

提前致谢!

标签: rshiny

解决方案


TL;博士

     final_df <- reactive({
         left_df2() %>%
             left_join(right_df2(), by = setNames(input$key_right, input$key_left))
     })

(我认为您的代码中的键颠倒了……第一帧的键名应该在 的左侧,而=不是您在示例中的右侧。这就是为什么在下面的示例中我用不同的方式演示的一个原因中的键名right_df。)

解释

input$key_right = ...实际上是重新分配操作(覆盖列表key_right属性的值input),而不是您想要的。

为了清楚地演示,我将 (1) 修复right_df以使其包含该right列,以及 (2) 将其key名称更改为不同。

right_df <- df[,c(1:2,4)]
names(right_df)[1:2] <- c("key3", "key4")
right_df
#   key3 key4 right
# 1    1    5    r1
# 2    2    6    r2
# 3    3    7    r3
# 4    4    8    r4

从这里开始,静态连接可以是:

left_join(left_df, right_df, by = c("key1" = "key3"))
#   key1 key2 left key4 right
# 1    1    5   l1    5    r1
# 2    2    6   l2    6    r2
# 3    3    7   l3    7    r3
# 4    4    8   l4    8    r4

"key1"将名称分配给字符串的等效方法"key3"是使用setNames

left_join(left_df, right_df, by = setNames("key3", "key1"))

此方法的一个优点是它允许您以编程方式从变量定义名称。


推荐阅读