У меня есть программа, которая позволяет пользователям импортировать файл .csv и выбирать оси для построения графика из этого файла. Программа работает, когда данные содержат только числовые числа; однако, когда есть значения NULL, я получаю следующую ошибку: Невозможно объединить length
и colors
.
Ниже приведен пример данных, с которыми у меня возникли проблемы:
Если я удалю столбец цветов, программа будет работать нормально, поэтому я знаю, что программа будет работать, если будут только цифры. Я думаю, мне нужно будет использовать функцию replace().
library(shiny)#load and attach package shiny
library(shinythemes)
library(data.table)
library(ggplot2)
library(tidyverse)
not_sel <- "Not selected"
main_page <- tabPanel(#create a tab panel for main_page
title = "Data Plotter",#main_page tab titled Plot
titlePanel("Data Plotter"),#panel titled Plot
sidebarLayout( #create a layout with a sidebar and main area
sidebarPanel(#side panel = inputs
title = "Inputs",
fileInput("csv_input","Select CSV File",accept = ".csv"),#first parameter is ID to call in server, text that appears, condition to accept
selectInput("x_axis","Select x-axis",choices = c(not_sel)),#creates input in Inputs
selectInput("y_axis","Select y-axis",choices = c(not_sel), selected = not_sel, multiple = TRUE),
actionButton("run_button","Apply Changes",icon = icon("play")), #adds play icon
),
mainPanel(#main panel are outputs
tabsetPanel(#can divide output into separate viewable screens
tabPanel(#first screen called Plot
title = "Plot",
plotOutput("plot_1") #make Plot screen output image
)
)
)
)
)
about_page <- tabPanel(
title = "About",
titlePanel("About"),#create a panel containing an application title
"Created by NC",
br(),#new line
"June 2024"
)
ui <- navbarPage(#create a page with a top level navigation bar
title = "Data Plotter",
theme = shinytheme('sandstone'),
main_page,
about_page
)
server <- function(input, output){
options(shiny.maxRequestSize=100*1024^2)
data_input <- reactive({ #wraps following expression as reactive, meaning result changes over time
req(input$csv_input)#req ensures there is csv input, otherwise does not run
fread(input$csv_input$datapath)#fast reads input$csv$data path, which is file pathway
})
data_input_long <- reactive({
pivot_longer(setDF(data_input()), cols = -y, names_to = "Tag", values_to = "Values")
})
data_filtered <- eventReactive(input$run_button,{
filter(data_input_long(), Tag %in% input$y_axis)
})
observeEvent(data_input(),{#wraps code and allows it to run when specific reactive expression changes
choices <- c(not_sel,names(data_input()))#create variable "choices", with not_sel at top and the names of data table next
updateSelectInput(inputId = "x_axis", choices = choices)#updates the selectinput, which in turn changes the choices
updateSelectInput(inputId = "y_axis", choices = choices)
})
output$plot_1 <- renderPlot({
ggplot(data_filtered(), aes(x = .data[[input$x_axis]], y = Values, color = Tag))+
geom_point()
}) #assigns renderPlot to output, renders graph for plot_1
}
shinyApp(ui = ui, server = server)#creates Shiny application, user interface is layout of app, server is connection between input and output
Вы сможете сделать это с помощью ifelse()
и заменить значения NULL
на 0.
library(dplyr)
d <- tibble::tribble(
~length, ~y, ~time, ~colors,
5, 0, 30, NULL,
10, 1, 60, NULL,
15, 2, 90, NULL)
d <- as.data.frame(d)
d <- d %>%
rowwise() %>%
mutate(colors = ifelse(is.null(colors), 0, colors))
d
#> # A tibble: 3 × 4
#> # Rowwise:
#> length y time colors
#> <dbl> <dbl> <dbl> <dbl>
#> 1 5 0 30 0
#> 2 10 1 60 0
#> 3 15 2 90 0
Created on 2024-06-21 with reprex v2.1.0
В вашей реактивной функции data_input
вы можете заменить все значения NULL на 0 следующим образом:
data_input <- reactive({
req(input$csv_input) # req ensures there is csv input, otherwise does not run
dt <- fread(input$csv_input$datapath, na.strings = c("NULL", "")) # fast reads input$csv$data path, which is file pathway
dt[is.na(dt)] <- 0 # replace NA values (including "NULL" strings) with 0
dt
})
Здесь na.strings = c("NULL", "")
в fread
указывает, что и "NULL"
, и пустые строки следует рассматривать как NA
.
Затем строка dt[is.na(dt)] <- 0
заменяет все значения NA
в таблице данных на 0
.
На данный момент я не могу протестировать, но уверен, что это должно сработать
Подход с replace
transform(df, colors=replace(unlist(colors), is.null(unlist(colors)), 0))
length y time colors
1 5 0 30 0
2 10 1 60 0
3 15 2 90 0
Обратите внимание, что цвета — это список NULL
(поскольку вектор NULL уменьшается до NULL), поэтому для получения вектора используется unlist
.
Использование данных @DaveArmstrong
df <- structure(list(length = c(5, 10, 15), y = c(0, 1, 2), time = c(30,
60, 90), colors = list(NULL, NULL, NULL)), row.names = c(NA,
-3L), class = "data.frame")