R shiny gvisTable with columns selected by user in defined order - r

I have an R shiny webpage where I currently use gvisTable to show a selection of columns from a data.frame. The rows are dynamically selected by the user with the sidebarPanel, but right now the columns are hard-coded inside the gvisTable call.
I would like to allow the user to dynamically select the columns from a drop-down menu (see snapshot of a similar system from a non-shiny webpage). The key feature I want is to allow resorting of the columns.
Any ideas how to pass this sorted selection of columns in shiny?
I don't mind using something else instead of gvisTable if it does the job.
EDIT: Thanks for showing a solution using the sortable answer. It works both for my old and new versions of shiny. Yet, this does not seem to remember the order upon hitting "Refresh", which would be really nice to have.
So, can it save the last chosen order as a browser cookie or a similar way? The server is authenticated, and I've been told I could put the variable order in a list with the user id as the key. An example of that would be great.

In Shiny you would have to use multiple selectInput's. However, you could install ShinySky by ZJ (https://github.com/AnalytixWare/ShinySky) and use his select2 binding which allows sorting. Alternatively, you could modify the sortable binding at https://github.com/mostly-harmless/sortable.
Edit: I don't know about cookies. I use sortable in a larger app. There I have an action button to save the order selected by the user. See Data > Transform > Reorder columns. In the app data is stored in a reactiveValue. To save the data order I use values[[input$datasets]] <- values[[input$datasets]][,input$tr_reorder_cols] where input$datasets is the active dataset, input$tr_reorder_cols is the users selected variable ordering, and values is the reactiveValue that contains the data.
The source for the app is on Github: https://github.com/mostly-harmless/radiant
As an alternative, you could also save the order of the variables in a reactiveValue. See the Shiny documentation for details.
Edit:
In global.R define a reactiveValue:
savedOrder <- reactiveValues()
When a user changes the order (this assumes you have userid available as a variable in R):
if(!is.null(input$sortable)) {
savedOrder[[userid]] <- input$sortable
}
Also, you could pass the id-value to returnOrder in case of a refresh:
if(!is.null(savedOrder[[userid]])) {
returnOrder("sortable",savedOrder[[userid]])
} else {
returnOrder("sortable",colnames(dat))
}

Related

Is there a way to slow down the input update from a numericInput ui object

So as the title say I'm looking for a way to slow down the input update form a numericInput ui object.
As a little preface, I am developing an application where I have dynamically built numeric inputs using a map function based on a drop down choice selection of numbers 1-8. So based on how many numeric inputs the user wants to compare the server will dynamically build them. And, in order to display some descriptive statistics, I had to add a actionButton that updates tables built from reactive values.
The problem arises from when I'm looking to type values into the numeric input fields. I only have about 1 second from the initial number click to finish my typing my value until I get kicked out of the numeric input field. In order to finish the number I wish to type I have to click back into the field once or twice to finish typing out the number. Once I have the number typed, I can then hit my action button to update the tables.
How do I make the numeric input fields "sleep" until the button press pulls the values for the reactive tables. I've had to do several odd workarounds due to the nature of the dynamically built numeric inputs and reactive tables/plots. Any input is very welcome.
It's hard to help without some code...
You can do something like that:
go <- reactiveVal(FALSE)
observeEvent(input[["button"]], {
go(TRUE)
})
output[["table"]] <- renderTable({
req(go())
something using the numeric inputs...
})
Does it help?

Deleting always the first row in a shiny CRUD app only after adding preexsitent data

I am stuck and need help.
I am working with this gist https://gist.github.com/gluc/d39cea3d11f03542970b
Basically in a shiny app it provides the possibility to make CRUD maneuvers and it works perfect.
I now managed to store the data on googlesheets and also to load the data in with:
read_sheet function from googlesheets4 package.
The issue is if I want to delete the last row of the table within the shiny app the first row is deleted after pressing the delete button.
This problem occurs only if I load in preexistend data (in my case from googlesheets).
I have encountered the problem: The id is not updating when I click the rows in the shiny app table.
I have used browser() and went through each function but I can't find the problem.
If I click on first row and delete the first row everything works perfect, but clicking the second or any other row except the first, always the first row is deleted.
Update:
I think the main issue is that after reading in the data from gogglesheets the disabled Id field is not navigating with the table, see picture.
If I click row 3 then the Id field should be 3 but it stays at 1 all the time. Therefore any action (for example deleting) on the table removes row one.
I can't get the link between the dataframe that is loaded at the beginning in the environment and the data that is defined by the CRUD application. The idea of akrun is perfect and should work but it does not:
I assign at the beginning of the code the read_sheet(...) table to responses like:
df_id_read_sheet <- read_sheet("......")
responses <- df_id_read_sheet
After one night without sleep. I found the solution. And it was as simple as I thought. Following one of the first advice by dear #akrun I checked with str the structure of the loaded googlesheet.
The sheet is imported as tibble after transforming it to data.frame and assigning to responses the complete code worked as expected. The isssue arised because of the rownames.
Using browser() immediately after assigning the sheet to responses I was able to see and check the structure within the shiny app on my console.
I really love debuging with broswer() as it enables me to see what is going on in shiny apps also.
Here is the simple yet hard discovered solution: At the beginning of your shiny app code:
library(magritter)
df_id_read_sheet <- read_sheet("put your sheet id here")
responses <- df_id_read_sheet
responses %<>%
as.data.frame()

Shiny dashboard. Hide checkboxes but retain their default value

I have a shinydashboard that I hope to use as a template across several projects. In the side panel I have filters so the user can create a subset of the data, eg gender. I wish to be able to hide certain filters on some projects but still have the output to pass to functions.
For example in ui.r I have
uiOutput("genderGroup")
which I need hiding from view in the dashboard.
In server.r I have
output$genderGroup <- renderUI({
checkboxGroupInput("genderFilter",label=h5("Filter by Gender"),
choices =c("Male"= 1, "Female"= 2),
selected =c(1, 2)
)
})
I still need to capture the output from the genderGroup checkboxes as several reactive functions require the filter as an argument. I've tried hiding the uiOutput with hidden(uiOutput("genderGroup")) in ui.r but the dashboard hangs when trying to look for the value for output$genderFilter.
Note: I'm using the dashboard as a template. I do not want to rewrite functions excluding certain filters on a project by project basis. As data across all projects will contain the same filtered fields, I just want to go in and hide those filters that the project does not need for subsetting. When hidden, the default selected values will be passed to the function.
Thanks
Andrew

Assigning Shiny Input Variable to Gloval Environment/Data

I'm converting some code/script to function on a shiny server.
I need to scrape html data tables from a url, and currently, to choose the id number that changes in the url I have a function.
Get_ID<-function()[readline("Please choose a number:>>> ")}
num.id<-GET_ID()
It works quite well, it prompts to write the number in by keyboard in the console, and I can run the scrape easily for that URL identified (the value is pasted into the middle of a URL to use in further code).
I'm now trying to provide a list of numbers in a drop-down list on the ui.r file.
I have a dataframe (call it df) with these values (pre-planned url ID's)
NAME number
seta 20001
setb 20002
setc 20003
setd 20004
sete 20005
I'd like for the 'NAME' to appear in the drop-down list and the corresponding value in "number" to be used and assigned to the variable "num.id" so that the rest of the script will execute with the current value chosen by the user.
For the ui side, I have something along the lines of:
selectInput("ChooseName", "df", choices=NAME),
actionButton("submit", "SUBMIT CHOICE")
and I'm stuck on the server side. I've played a bit with creating an observer for the submit button, but I can't figure out a way to have the values exist in my global environment, specifically assigned to the value "num.id" - what I was using above. I would like the choice to be unique for every user. I.e., if User A chooses "setb", this won't disrupt User B who is viewing "setd".
For background, the url scrapes a table full of numbers, for which I manipulate and match to several dataframes and then output a final graph using ggplot2. Theoretically, you may recommend I pass the reactive input's from the drop-down list into the ggplot2 code directly, but there's a lot of reformatting that happens prior to use in the plot, so I'd like to keep the steps separated.
Thanks!

shiny: How to update a reactiveValues object?

I have a pair of auxiliary inputs that allows user to choose combinations from a set of choices. Also, it is convenient one to be able to remove an item that was created before.
For this task, a named list, in the form of reactiveValues object, listN <- reactiveValues(), will be in charge to store these information.
The function to ADD items is working like a charm, but when I try to REMOVE items from listN, its item names persists forever!
My strategy was make use of reactiveValuesToList(), manipulate its items and replace listN with a brand new instance of reactiveValues() (or do.call(reactiveValues, listN_as_list).
I stored a reproducible app at Gist. I hope it is sufficient to you guys help me out. Please insist in more clarification if needed.
URL:
gist.github.com/d43e72959c4576d27535
Code to run on console:
shiny::runGist('d43e72959c4576d27535')
Thanks in advance!
Answer from Joe Cheng at Shiny Google Groups:
Yeah, you can't replace an entire reactiveValues instance like that
and expect anything that's bound to the previous reactiveValues
instance to instantly know about the new one. The slots on the
reactiveValues instance itself are reactive, but its own variable is
not.
I think the real issue here is that, unlike lists and envs, you can't
remove values from reactiveValues, only set them to NULL.
There are two easy workarounds I can think of:
1) In addition to the reactiveValues instance's slots being reactive, also make the variable
reactive, using makeReactiveBinding.
2) You could also use reactiveValues
as normal, but keep a list IN the reactiveValues that holds the
combinations, not having the reactiveValues itself hold the values. In
other words, values <- reactiveValues(combos = list()), and when
something new gets added, values$combos[[x]] <- y.
In trying out fix
number 1 above, I found that updateSelectInput doesn't work properly when choices is a length-0 vector. Instead of sending a 0-length vector to
the client, it doesn't send anything for choices at all, so the
choices never change.
I've forked your gist and added two revisions: one that implements
workaround #1 (along with some other problems I found), and one that
works around the updateSelectInput issue by using renderUI.
https://gist.github.com/jcheng5/eaedfed5095d37217fca/revisions

Resources