Good afternoon, comrades. I am sure that no one helped me, tk. I just asked the question not very correctly earlier. I am trying to create a FlexDashcoard application. To understand how the program works, you need the sample data files that I have prepared. I apologize in advance for the Russian characters in the files, they are presented to you "as is".
Here is my code:
---
title: "AFEA of Russian enterprises"
output:
flexdashboard::flex_dashboard:
storyboard: true
orientation: rows
vertical_layout: fill
theme: simplex
runtime: shiny
---
```{r GlobalOptions}
options(knitr.duplicate.label = 'allow')
```
```{r setup, include=FALSE, echo=FALSE, message=FALSE}
### Library connection module ###
library("flexdashboard")
library("dygraphs")
library("shiny")
library("shinyFiles")
#options(shiny.trace=TRUE)
library("DT")
library("ggplot2")
library("dplyr")
library("here")
library("data.table")
library("plyr")
### ----------------------------- ###
```
Sidebar {.sidebar}
-------------------------------------
```{r}
roots <- c('C' = 'C:/', 'D' = 'D:/', '//' = '\\\\ns\\Public\\Power BI')
rv <- reactiveValues(txt_file = FALSE)
OKVEDselectInputСhoices<- reactiveValues(data = NULL)
renderUI({
shinyFilesButton("files_choose", "Select files", "",
multiple=TRUE,
buttonType = "default",
class = NULL,
icon = icon("list-alt"),
style = "background-image: linear-gradient(#D9230F, #D9230F 6%, #D9230F);
border-color: #A91B0C;
margin-top: 10px;
width: 100%;
float: left;
box-sizing: border-box;",
viewtype = "detail"
)
})
br()
renderUI({
actionButton(inputId = "apply",
label = "Apply",
icon = icon("play"),
style = "background-image:
linear-gradient(#D9230F, #D9230F 6%, #D9230F);
border-color: #A91B0C;
margin-top: 10px;
margin-bottom: 10px;
width: 100%;
float: left;
box-sizing: border-box;"
)
})
br()
renderUI({h6(inputId="sideBarText2", "Выбор ОКВЭД(ов):")})
renderUI({
selectInput("OKVEDlectInput",
label = NULL,
choices = OKVEDselectInputСhoices$data,
#selected = "Percent White")
multiple=TRUE
)
})
```
```{r}
shinyFileChoose(input, "files_choose",
roots=roots,
filetypes=c('csv'))
observeEvent(
input$apply,{
if (!is.null(input$files_choose))
{
myInputFile <- parseFilePaths(roots,input$files_choose)$datapath
all.files <- myInputFile
print(all.files)
a.vector <- grep("data\\-\\d+\\-structure\\-", all.files, ignore.case = TRUE)
print(a.vector)
all.files <- all.files[a.vector]
all.files<- sort(all.files)
n <- length(all.files)
print(n)
data = vector('list', n)
if (n>0) {
for (i in 2:(n+1)) {
#print(paste("Вот такой файл:" , all.files[i-1]))
data[i-1] <- lapply(all.files[i-1],
fread,
showProgress = TRUE,
sep = ";",
quote = "",
header = FALSE,
stringsAsFactors=TRUE,
select = c(1:124))
}
}
}
table <- rbindlist(data)
UN <- unique(table[[5]])
UN <- sort(UN)
OKVEDselectInputСhoices$data <- UN
rv$txt_file <- table
#View(rv$txt_file)
}
)
```
### Basic information
------------------------------------------------------------------------
```{r}
#View(rv$txt_file)
```
Some commentary about Frame 1.
### Secondary information
------------------------------------------------------------------------
Some commentary about Frame 2.
You can download the finished version of the code
My application first creates an interface, allows the user to select a file to import (or several), but with a specific name, and loads these data into the application.
In the future, I would like to build on the basis of this data contained in the global variable rv$txt_file
, output information to the table, build graphs, and also change data using the selectInput selection.
But here's a weird problem, when I try to just even call the data in the ### Basic information block
, I fail! I can't understand, because the variable is global ...
HELP!
Unfortunately, there was no one to help me and, after spending many hours, I managed to solve the problem. I sincerely hope that someone will find it useful someday.
My first mistake was using the observeEvent
. If you refer to the description on the official website, you can read the following information:
"Use observeEvent whenever you want to perform an action in response to an event. (Note that "recalculate a value" does not generally count as performing an action--see eventReactive for that.) The first argument is the event you want to respond to, and the second argument is a function that should be called whenever the event occurs.
Use eventReactive to create a calculated value that only updates in response to an event. This is just like a normal reactive expression except it ignores all the usual invalidations that come from its reactive dependencies; it only invalidates in response to the given event."
Thus, in my code, I need to replace observeEvent (input $ dir_choose, {
with rv_result <- eventReactive (input $ apply, {
. You will also need to make the assignment of the final result at the end of this function: rv_result <- rv$txt_file
In the block ### Basic information
, then it becomes possible to call a function and assign the result to a variable: dataset <- reactive({rv_result()})
. And this is the solution to the first part of the question, when after importing the values, it becomes possible to manipulate them.
The second part of the question was how to use selectInput
to control the output table with data.
Everything looks pretty complicated, but the bottom line is that selectInput
after selecting elements indicates a list of values and you can check and compare 2 lists. Accordingly, the code that manipulates the table looks like this:
renderDT(fillContainer = TRUE,{
data <- dataset()
print(class(data))
if (is.null(input$OKVEDlectInput)) {
data <- dataset()
}
else{
d1 <- as.list(input$OKVEDlectInput)
d2 <- as.list(as.vector(data$V5))
result <- which(!is.na(f(d2, d1,0,0)))
result <- as.vector(result)
data <- data[result,]
}
})
The f function compares 2 lists and returns the line numbers to be printed:
f <- function(verlist, list_for_ver, resulttyp=0,delna=1) {
listforreturn <- vector(mode = 'list', length=0)
if ((class(verlist)=='list') && (class(list_for_ver)=='list')){
if (delna==1){
listforreturn <- as.vector(na.omit(match(verlist,list_for_ver)))
}
else{
listforreturn <- as.vector(match(verlist,list_for_ver))
}
if (resulttyp==0){
listforreturn <- as.list(listforreturn)
}
else{
listforreturn<- as.list(list_for_ver[listforreturn])
}
}
return(listforreturn)
}
Everything worked as required.
Here is the complete code:
---
title: "AFEA of Russian enterprises"
output:
flexdashboard::flex_dashboard:
storyboard: true
orientation: rows
vertical_layout: fill
theme: simplex
runtime: shiny
---
```{r GlobalOptions}
options(knitr.duplicate.label = 'allow')
rv <- reactiveValues(txt_file = FALSE)
OKVEDselectInputChoices<- reactiveValues(data = NULL)
```
```{r setup, include=FALSE, echo=FALSE, message=FALSE}
### Library connection module ###
library("flexdashboard")
library("dygraphs")
library("shiny")
library("shinyFiles")
#options(shiny.trace=TRUE)
library("DT")
library("ggplot2")
library("dplyr")
library("here")
library("data.table")
library("plyr")
### ----------------------------- ###
```
Sidebar {.sidebar}
-------------------------------------
```{r}
roots <- c('C' = 'C:/', 'D' = 'D:/', '//' = '\\\\ns\\Public\\Power BI')
renderUI({
shinyFilesButton("files_choose", "Select files", "",
multiple=TRUE,
buttonType = "default",
class = NULL,
icon = icon("list-alt"),
style = "background-image: linear-gradient(#D9230F, #D9230F 6%, #D9230F);
border-color: #A91B0C;
margin-top: 10px;
width: 100%;
float: left;
box-sizing: border-box;",
viewtype = "detail"
)
})
br()
renderUI({
actionButton(inputId = "apply",
label = "Apply",
icon = icon("play"),
style = "background-image:
linear-gradient(#D9230F, #D9230F 6%, #D9230F);
border-color: #A91B0C;
margin-top: 10px;
margin-bottom: 10px;
width: 100%;
float: left;
box-sizing: border-box;"
)
})
br()
renderUI({h6(inputId="sideBarText2", "Выбор ОКВЭД(ов):")})
renderUI({
selectInput("OKVEDlectInput",
label = NULL,
choices = OKVEDselectInputChoices$data,
#selected = "Percent White")
multiple=TRUE
)
})
```
```{r}
shinyFileChoose(input, "files_choose",
roots=roots,
filetypes=c('csv'))
rv_result <- eventReactive(
input$apply,{
if (!is.null(input$files_choose))
{
myInputFile <- parseFilePaths(roots,input$files_choose)$datapath
all.files <- myInputFile
print(all.files)
a.vector <- grep("data\\-\\d+\\-structure\\-", all.files, ignore.case = TRUE)
print(a.vector)
all.files <- all.files[a.vector]
all.files<- sort(all.files)
n <- length(all.files)
print(n)
data = vector('list', n)
if (n>0) {
for (i in 2:(n+1)) {
#print(paste("Вот такой файл:" , all.files[i-1]))
data[i-1] <- lapply(all.files[i-1],
fread,
showProgress = TRUE,
sep = ";",
quote = "",
header = FALSE,
stringsAsFactors=TRUE,
select = c(1:124))
}
}
}
table <- rbindlist(data)
UN <- unique(table[[5]])
UN <- sort(UN)
OKVEDselectInputChoices$data <- UN
rv$txt_file <- table
rv_result <- rv$txt_file
#View(rv$txt_file)
}
)
```
### Basic information
```{r}
#renderTable({
# dataset <- rv_result()
# dataset
#})
f <- function(verlist, list_for_ver, resulttyp=0,delna=1) {
# verlist - массив, который требуется проверить на совпадение с элементами второго массива
# list_for_ver - проверочный массив, т.е. тот, с которым сравнимается
# resulttyp (0 - выводятся номера элементов list_for_ver, которые найдены);
# (1 - выводятся найденные значения)
# delna - (0 -если элемент не найде, то он не показывается)
# (1 -если элемент не найде, то указывается NA)
listforreturn <- vector(mode = 'list', length=0)
if ((class(verlist)=='list') && (class(list_for_ver)=='list')){
if (delna==1){
listforreturn <- as.vector(na.omit(match(verlist,list_for_ver)))
}
else{
listforreturn <- as.vector(match(verlist,list_for_ver))
}
if (resulttyp==0){
listforreturn <- as.list(listforreturn)
}
else{
listforreturn<- as.list(list_for_ver[listforreturn])
}
}
return(listforreturn)
}
dataset <- reactive({rv_result()})
renderDT(fillContainer = TRUE,{
data <- dataset()
print(class(data))
if (is.null(input$OKVEDlectInput)) {
data <- dataset()
}
else{
d1 <- as.list(input$OKVEDlectInput)
d2 <- as.list(as.vector(data$V5))
result <- which(!is.na(f(d2, d1,0,0)))
result <- as.vector(result)
data <- data[result,]
}
})
```
### Secondary information
Some commentary about Frame 2.