Я создаю блестящее приложение, часть которого вычисляет модель линейной регрессии на основе данных, загруженных и измененных пользователем. Я делаю все шаг за шагом, поэтому здесь я покажу вам только код тестового приложения, касающийся основной проблемы. Идея такова:Изменение и объединение реактивной части данных, загруженной пользователем в блестящем приложении
- добавление пользователя данные из файла .csv с помощью
fileInput
в блестящих - данных показывает вверх, а затем, после проверки его, пользователь может изменить переменные по своему выбору
- Каждого отобранным и модифицирован переменный показывает со старым переменными как новым реактивным DataTable - мне удалось получить через него с помощью этого: Add values to a reactive table in shiny
Теперь, все это прекрасно работает на код ниже, если указан начальный набор данных:
test_df <- data.frame(a = seq(1000, 21000, 1000), b = seq(1:21), c = seq(100, 300, 10))
library(shiny)
runApp(list(
ui=pageWithSidebar(headerPanel("Adding entries to table"),
sidebarPanel(uiOutput("select1"),
selectInput("select2", "Choose modification",
choices = c("log", "different"),
selected = NULL, multiple = F),
actionButton("update", "Update Table")),
mainPanel(tableOutput("table1"))),
server=function(input, output, session) {
values <- reactiveValues()
### specifing the dataset ###
values$df <- data.frame(test_df)
nr <<- nrow(test_df)
### this will contain the modified values ###
values$d <- data.frame(1:nr)
### selecting a variable to modify ###
output$select1 <- renderUI({
nc <- ncol(values$df)
nam <- colnames(values$df)
selectInput("var", label = "Select var:",
choices = c(nam), multiple = F,
selected = nam[1])
})
### calculations needed for modifactions ###
newEntry <- observeEvent(input$update, {
if(input$select2 == "log") {
newCol <- isolate(
c(log(values$df[input$var]))
)
newCol <- as.data.frame(newCol)
colnames(newCol) <- paste0("Log of ", input$var)
}
else if(input$select2 == "different") {
newCol <- isolate(
c(1-exp(-(values$df[input$var]/100)))
)
newCol <- as.data.frame(newCol)
colnames(newCol) <- paste0(input$var, "Diff of", input$dr1)
}
### adding new modified columns to the dataframe ###
isolate(
values$d <- dplyr::bind_cols(values$d, newCol)
)
})
output$table1 <- renderTable({
d1 <- values$d
nc <- ncol(d1)
### printing the whole dataframe (initial+modified) - skipping ###
### the first column of modified values, as it doesn't contain our data ###
if(input$update == 0) {
print(data.frame(test_df))
} else {
data.frame(values$df, d1[2:nc])
}
})
}))
Однако, когда я хочу, чтобы включить первый шаг, который означает загрузку набора данных ПОСЛЕ запуска приложения, то приложение не запускается, так как теперь я имею в виду реактивный контент, которого, вероятно, не существует. Вот обновленный код, с характеристикой загрузки данных из собственного источника:
library(shiny)
runApp(list(
ui=pageWithSidebar(headerPanel("Adding entries to table"),
sidebarPanel(fileInput("file1", "Choose file to upload", accept = c("text/csv", "text/comma-separated-values", "text/tab-separated-values", "text/plain", ".csv",".tsv")),
checkboxInput("header", "Header", TRUE),
radioButtons("sep", "Separator",c(Comma=",",Semicolon=";",Tab="\t"),","),
radioButtons("dec", "Decimal",c(Comma=",",Dot="."),","),
actionButton("Load", "Load the File"),
uiOutput("select1"),
selectInput("select2", "Choose modification",
choices = c("log", "different"),
selected = NULL, multiple = F),
actionButton("update", "Update Table")),
mainPanel(tableOutput("table1"))),
server=function(input, output, session) {
values <- reactiveValues()
### uploading data from external source ###
data1 <- reactive({
if(input$Load == 0){return()}
inFile <- input$file1
if (is.null(inFile)){return(NULL)}
isolate({
input$Load
my_data <- read.csv(inFile$datapath, header = input$header, sep = input$sep, stringsAsFactors = FALSE, dec = input$dec)
})
my_data
})
### specifing the dataset ###
values$df <- data.frame(data1())
nr <<- nrow(data1())
### this will contain the modified values ###
values$d <- data.frame(1:nr)
### selecting a variable to modify ###
output$select1 <- renderUI({
nc <- ncol(values$df)
nam <- colnames(values$df)
selectInput("var", label = "Select var:",
choices = c(nam), multiple = F,
selected = nam[1])
})
### calculations needed for modifactions ###
newEntry <- observeEvent(input$update, {
if(input$select2 == "log") {
newCol <- isolate(
c(log(values$df[input$var]))
)
newCol <- as.data.frame(newCol)
colnames(newCol) <- paste0("Log of ", input$var)
}
else if(input$select2 == "different") {
newCol <- isolate(
c(1-exp(-(values$df[input$var]/100)))
)
newCol <- as.data.frame(newCol)
colnames(newCol) <- paste0(input$var, "Diff of", input$dr1)
}
### adding new modified columns to the dataframe ###
isolate(
values$d <- dplyr::bind_cols(values$d, newCol)
)
})
output$table1 <- renderTable({
d1 <- values$d
nc <- ncol(d1)
### printing the whole dataframe (initial+modified) - skipping the first ###
### column of modified values, as it doesn't contain our data ###
if(input$update == 0) {
print(data.frame(test_df))
} else {
data.frame(values$df, d1[2:nc])
}
})
}))
Я получаю ошибку:
Ошибка в .getReactiveEnvironment() $ currentContext: Операция не допускается> без активный активный контекст. (Вы пытались сделать что-то, что только можно> сделать внутри реактивным выражения или наблюдателя.)
Конечно, я кое-что о реакционной глянцеватых не хватает, но я тщательно читал много разных статей, вопросы и т. д., и не может найти ответ на этот вопрос. Это не проблема с загрузкой самого файла, потому что этот блок кода отлично работает в другом приложении, когда я пишу реактивный набор данных к нормальной переменной, прежде чем ссылаться на его содержимое. Но как я могу это сделать здесь, когда записываю данные в values$...
? Или, может быть, есть другое решение для работы с реактивными данными из внешнего источника, таким образом? Надеюсь, я все понял.
Помогает ли вам вставить 'req (input $ file1)' в начале 'data1'' реактивный'? –
@JohnPaul Нет, это не так, приложение отключается с той же ошибкой. –
Попытайтесь поместить свои 'значения $ xxx' внутри наблюдателя, когда они заметят в реактивном контексте, например' наблюдать ({значения $ df <- data1()}) '. Здесь 'data1()' является реактивным, поэтому ваш код не работает. –