R Shiny中如何创建格式化renderTable输出数字的函数?自定义格式化函数失效问题排查
问题分析与解决方案
嘿,我一眼就看出问题所在了——你的formatDF1函数没有返回处理后的数据对象,而且调用函数时也没有将结果赋值给目标变量,导致格式化逻辑完全没生效。下面是具体的修复步骤:
1. 修复formatDF1函数的返回值
R函数默认会返回最后一个表达式的结果,而你的函数最后一行是给rownames(x)赋值的操作,这个操作返回的是你设置的行名向量,不是修改后的x数据框。我们需要在函数末尾明确返回处理后的x:
formatDF1 <- function(x){ dfA <- format(x[1,],nsmall=0) dfB <- format(x[2,],nsmall=0) dfC <- paste(format(x[3,],nsmall=2),'%') dfD <- paste(format(x[4,],nsmall=2),'%') x <- rbind(x[0,],dfA,dfB,dfC,dfD) n <- dim(x)[2] colnames(x) <- paste("Series", 1:n) rownames(x) <- matrix3Headers() x # 或者用return(x),效果完全一致 }
2. 正确调用格式化函数
你之前只是写了formatDF1(df),这只会运行函数但不会把处理后的结果存回df变量里,必须把函数返回值赋值给df才能覆盖原数据:
df <- formatDF1(df)
修正后的完整代码
把上面的修复点应用到你的MWE中,完整代码如下:
library(shiny) library(shinyMatrix) library(shinyjs) # 修复后的格式化函数 formatDF1 <- function(x){ dfA <- format(x[1,],nsmall=0) dfB <- format(x[2,],nsmall=0) dfC <- paste(format(x[3,],nsmall=2),'%') dfD <- paste(format(x[4,],nsmall=2),'%') x <- rbind(x[0,],dfA,dfB,dfC,dfD) n <- dim(x)[2] colnames(x) <- paste("Series", 1:n) rownames(x) <- matrix3Headers() x # 返回处理后的数据框 } matrix3Headers <- function(){ c('Issuance period', 'Scheduled amort period', '3m average XS trigger', 'Percentage of capital')} # Assigns default values to first column of input matrix grid matrix3Default <- matrix( c( # Below are default values for table1 1, 24, 0, 100 ), # close concatenate 4, # specify default number of matrix rows 1, # specify default number of matrix columns dimnames=list(matrix3Headers(), NULL) ) # close matrix function # Automatically assigns names to column headers colnames(matrix3Default) <- paste0("Series ",1:ncol(matrix3Default)) # Matrix input function matrix3Input <- function(x, matrix3Default){ matrixInput(x, label = 'Input series terms into below grid:', value = matrix3Default, rows = list(extend=FALSE,names=TRUE), cols = list(extend=TRUE,names=TRUE,editableNames=FALSE,delete=TRUE), class = 'numeric' ) # close matrix input } # close function ui <- fluidPage( useShinyjs(), titlePanel('Inputs'), fluidRow(actionButton('modify','Modify'), tableOutput('table1')) ) # close fluid page server <- function(input, output, session){ rv <- reactiveValues( mat3=matrix3Input('matrix3',matrix3Default), input=matrix3Default, colHeader = colnames(input) ) # close reactive values observeEvent(input$modify,{ showModal(modalDialog( rv$mat3 )) # close shown modal and modal dialog }) # close observe event output$table1 <- renderTable({ if(!isTruthy(input$modify)){ # << Generates default table when first invoking the App df <- matrix3Default df <- formatDF1(df) # 正确赋值处理后的数据 } else { # << Generates table after user clicks "Modify" action button req(input$matrix3) rv$mat3 <- matrix3Input('matrix3',input$matrix3) df <- input$matrix3 df <- formatDF1(df) # 正确赋值处理后的数据 rv$input <- df } # close else df },rownames=TRUE, colnames=TRUE) # close output$table1 } # close server shinyApp(ui, server)
这样修改后,无论是初始加载还是点击Modify按钮后的表格,都会正确应用你想要的数值格式化,同时也彻底消除了代码重复的问题。
内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072
相关产品推荐
相关产品推荐

