r语言 - 重命名旧列名和新列名都是闪亮输入的列?



和标题差不多。当用户通过selectInput选择了要重命名的列和新名称时,如何重命名响应数据框架的列?

下面是被破坏的代码:

library(shiny)
library(dplyr)
library(DT)
ui <- fluidPage(
br(),
sidebarPanel(
#sliders
uiOutput("old_column"),
uiOutput("new_column")
),
mainPanel(
#display df
DT::dataTableOutput("table")
)
)
server <- function(input, output) {
#init reactives
cars <- reactiveVal(as.data.frame(mpg))
#display data
output$table <- DT::renderDataTable({
datatable(cars(),
selection = 'single',
options = list(autoWidth = TRUE,
scrollX = TRUE,
searching = FALSE,
lengthChange = FALSE))
})
##creating dropdowns
observe({
output$old_column <- renderUI({
selectizeInput("old_column",
"Which column do you want to rename?",
c(names(cars())), selected = NULL)
})
})
observe({
output$new_column <- renderUI({
names <- c("red", "blue", "green", "orange")
selectizeInput("new_column",
"What would you like to name it?",
names, selected = NULL)
})
})
#rename column
observe({
req(input$new_column)
req(input$old_column)
#this is the bad line!!!
cars(cars() %>%
dplyr::rename(input$new_column = input$old_column))
})
}
shinyApp(ui, server)

我已经尝试了一堆像!!as.name(input$new_column) := input$old_column这样的东西,但是我不能让它工作。

这是一个可能会有帮助的演示。

  • 首先,我将cars重命名为my_cars,因为cars是一个数据集(也使用mtcars而不是mpg方便)
  • 我删除了输出不需要的observe
  • 包含observeEvent,这样当选择新列名时列名将更改(按钮或其他ui策略也可以工作)
  • 在重命名时,我使用!!(bang-bang操作符)对变量名进行编程访问,这需要:=进行赋值

还要注意可能出现重复列名的问题。此外,由于selectizeInput是在server中生成的,因此默认的列名(在本例中是第一个列名)将被更改(observeEvent在启动时触发)。

library(shiny)
library(dplyr)
library(DT)
ui <- fluidPage(
br(),
sidebarPanel(
#sliders
uiOutput("old_column"),
uiOutput("new_column")
),
mainPanel(
#display df
DT::dataTableOutput("table")
)
)
server <- function(input, output) {

#init reactives
my_cars <- reactiveVal(mtcars)

#display data
output$table <- DT::renderDataTable({
datatable(my_cars(),
selection = 'single',
options = list(autoWidth = TRUE,
scrollX = TRUE,
searching = FALSE,
lengthChange = FALSE))
})

##creating dropdowns
output$old_column <- renderUI({
selectizeInput("old_column",
"Which column do you want to rename?",
names(my_cars()), 
selected = NULL)
})

output$new_column <- renderUI({
names <- c("red", "blue", "green", "orange")
selectizeInput("new_column",
"What would you like to name it?",
names, 
selected = NULL)
})

#rename column
observeEvent(input$new_column, {

req(input$new_column)
req(input$old_column)

my_cars(
my_cars() %>%
rename(!!input$new_column := !!input$old_column)
)

})
}
shinyApp(ui, server)

使用dplyr::rename_with()

下面是一个小表达式:

old <- 'mpg'
new <- 'gpm'
colnames(mtcars)
#>  [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
#> [11] "carb"
mtcars |> 
dplyr::rename_with(
.fn = ~ new, 
.cols = dplyr::all_of(old)
) |> 
colnames()
#>  [1] "gpm"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
#> [11] "carb"

你可以这样写:

# ...
# rename column
observe({
req(input$new_column)
req(input$old_column)

x <- cars() %>%
dplyr::rename_with(
.fn = ~ input$new_column,
.cols = dplyr::all_of(input$old_column)
)
# then do whatever you wish with `x`
# for example:
print(head(x))
})
# ...