list of values for selectInput - user-interface

I want to create a "selectInput" widget for which the choices of values are the names of columns in a dataset imported by a "fileInput" widget.
I tried to "tableOutput" the names of the dataset, as an argument to the "choices" parameters of the "selectInput" widget, but it doesn't work. The only choices I get in the widget are "name", "id" and "class".
Here's the code I used:
library(shiny)
ui <- fluidPage(
# Widget for loading data set
fileInput("file", label = h4("Input csv data set")),
# Widget for selecting the variable among names of columns of the data set
selectInput("select.variable", label = h4("Select variable from data set"),
choices = tableOutput("list.var"), selected = 1) # This approach doesn't work
)
server <- function(input, output) {
# The goal was to get the list of names of columns to use it as "choices"
# in the "selectInput" widget
output$list.var <- renderTable({
inFile <- input$file
if (is.null(inFile)) # To avoid error messages when the file is not yet loaded
return(NULL)
# After the file is loaded
data.fr <- read.csv(inFile$datapath)
list.var <- names(data.fr[1,]) # Get the names of the columns of the dataset
})
}
shinyApp(ui = ui, server = server)
Is there a way to use the names of columns of an imported dataset as choices for a "selectInput" widget?

Something like this should do the trick. I used renderUI to create the slider widget from your dataset
library(shiny)
ui <- fluidPage(
# Widget for loading data set
fileInput("file", label = h4("Input csv data set")),
uiOutput("myslider")
)
server <- function(input, output) {
# The goal was to get the list of names of columns to use it as "choices"
# in the "selectInput" widget
output$myslider <- renderUI({
# Widget for selecting the variable among names of columns of the data set
selectInput("select.variable", label = h4("Select variable from data set"),
choices = names(mydata()), selected = 1) # This approach doesn't work
})
mydata <- reactive({
inFile <- input$file
if (is.null(inFile)) # To avoid error messages when the file is not yet loaded
return(NULL)
# After the file is loaded
data.fr <- read.csv(inFile$datapath)
names(data.fr[1,]) # Get the names of the columns of the dataset
})
output$list.var <- renderTable({
mydata()
})
}
shinyApp(ui = ui, server = server)

Related

How to store data for use in multiple data validation using GAS?

I have a script running on Google Sheets, which brings data from another spreadsheet/file as an array and sets one of its column's data as a data validation into a cell. Then, as the user picks one option of this data validation, the script goes back to that file and brings its related data and sets it in an adjacent column and this repeats about 3 times, making the process slow.
I was wondering if that would be possible to store the first data collection into the document property and set the data validations by grabbing related information from that data set, instead of going to the other file everytime.
Here's an update, with a working version:
function listaCategorias() {
let listaGeral = sheetBDCadProd.getRange(2, 1, sheetBDCadProd.getLastRow(), 45).getValues();//Gets all values
//Extracts a column of interest for this first data validation setting
let categorias = [];
for (let a = 0; a < listaGeral.length; a++) {
categorias.push(listaGeral[a][17])
}
let uniqueCat = [...new Set(categorias)]; //Gets a list of unique values. Not sure how I'd do that within new Set, so I did a for loop before
//Sets the data validation
const cell = sheetVendSobEnc.getRange('B5');
const validationCat = SpreadsheetApp.newDataValidation().requireValueInList(uniqueCat).setAllowInvalid(false).build();
cell.clearContent();
cell.clearDataValidations();
cell.setDataValidation(validationCat);
//Saves the data into the document property for usage in the next script/data validation
listaGeral = JSON.stringify(listaGeral)
PropertiesService.getDocumentProperties().setProperty('listaGeral', listaGeral);
}
//This is getting one of the columns, based on the option picked..the one generated by the data validation above.
function listaDescricao() {
const categoria = sheetVendSobEnc.getRange('B5').getValue();
const dadosCadProd = PropertiesService.getDocumentProperties().getProperty('listaGeral')
let cadGeral = JSON.parse(dadosCadProd);
//Filters the elements matching the option picked
let filteredNomeSobEnc = cadGeral.filter(function (o) { return o[17] === categoria });
//Filters unique values
let listToApply = filteredNomeSobEnc.map(function (o) { return o[7] }).sort().reverse();
let descUnica = listToApply.filter((v, i, a) => a.indexOf(v) === i);
Logger.log('Descrição Única: ' + descUnica)
}
It's working, but I'd like to know the rooms for improvement here.
Thanks.

How to do a fct_drop within a function (using tidy eval)?

Using the diamonds dataset...
Trying to create a function that will allow me to plot either cut or color on the x-axis...
...but first I want to filter the selected column to show only a certain number of levels.
I've got the filter working but the levels are still present... and they will show up in the chart. I need to do a fct_drop() on the selected column
Please see the code below for a reproducible example:
library(tidyverse)
diamonds <- diamonds %>%
mutate(cut = factor(cut),
color = factor(color))
reduce_for_plot <- function(data, column, how_many_levels) {
column2 <- enquo(column)
of_interest <- unique(data[[deparse(substitute(column))]])[1:how_many_levels]
data %>%
filter(!! column2 %in% of_interest)
# here is where I then do some kind of mutate... to fct_drop the selected column
# this line seems to work
# value_to_put_in <- fct_drop(data[[deparse(substitute(column))]])
# but this line doesn't
# data <- data %>%
# mutate(!! column = value_to_put_in)
}
diamonds %>%
reduce_for_plot(color, 1)
You were almost there! The problem in your code is that R doesn't allow ! on the LHS of =. So you need to use the fake operator := instead.
reduce_for_plot <- function(data, column, how_many_levels) {
col_expr <- enquo(column)
col_name <- rlang::as_name(col_expr)
of_interest <- unique(data[[col_name]])[1:how_many_levels]
data <- data %>%
filter(!!col_expr %in% of_interest)
value_to_put_in <- fct_drop(data[[col_name]][of_interest])
data %>%
mutate(!!col_name := value_to_put_in)
}
As you can see I have replaced all deparse(substitute(column)) by as_name(enquo(column)). However you can avoid these entirely by doing the computations in data context, which I think yields nicer code:
reduce_for_plot <- function(data, column, how_many_levels) {
column <- enquo(column)
data %>%
filter(!!column %in% unique(!!column)[1:how_many_levels]) %>%
mutate(!!column := fct_drop(!!column))
}

Is there a way to copy only unique rows in an Excel worksheet column to another sheet?

I use a CSV file as $AgencyMaster with two columns, AgencyID and AgencyName. I currently manually input these from another file, $Excel_File_Path, but I would like to automatically generate $AgencyMaster if possible.
$Excel_File_Path has three worksheets: Sheet1, Sheet2 and Template. Sheet1 and Sheet2 are full of data, while Template is used as a graphical representation of said data which populates based on the AgencyID. I have a script that opens $Excel_File_Path, inputs AgencyID into a specific cell, saves it, then converts it to a PDF. It does this for each AgencyID in $AgencyMaster, which is currently over 200.
In $Excel_File_Path, columns B and C in Sheet1 and Sheet2 contain all of the AgencyIDs and AgencyNames, but there are a bunch of duplicates. I can't delete any of the rows because while they are duplicates in column B and C, columns D, E, F, etc have different data used in Template. So I need to be able to take each unique AgencyID and AgencyName which may appear in Sheet1 or Sheet2 and export them to a CSV to use as $AgencyMaster.
Example:
(https://i.imgur.com/j8UIZqp.jpg)
Column B contains the AgencyID and Column C contains the AgencyName. I'd like to export unique values of each from Sheet1 and Sheet2 to CSV $AgencyMaster
I've found how to export it to a different worksheet within the same workbook, just not a separate workbook alltogether. I'd also like to save it as a .CSV with leading 0's in cell A.
# Checking that $AgencyMaster Exists, and importing the data if it does
If (Test-Path $AgencyMaster) {
$AgencyData = Import-CSV -Path $AgencyMaster
# Taking data from $AgencyMaster and assigning it to each variable
ForEach ($Agency in $AgencyData) {
$AgencyID = $Agency.AgencyID
$AgencyName = $Agency.AgencyName
# Insert agency code into cell D9 on Template worksheet
$ExcelWS.Cells.Item(9,4) = $AgencyID
$ExcelWB.Save()
# Copy-Item Properties
$Destination_File_Path = "$Xlsx_Destination\$AgencyID -
$AgencyName - $company $month $year.xlsx"
$CI_Props = #{
'Path' = $Excel_File_Path;
'Destination' = $Destination_File_Path;
'PassThru' = $true;
} # Close $CI_Props
# Copy & Rename file
Copy-Item #CI_Props
} # Close ForEach
} # Close IF
I would recommend using either Sort-Object -Unique or Group-Object.

How to remove or hide the data value not required from table in birt tool

How do I remove or hide the data value not required from table in birt tool?
I tried with the values it works in some places but now in groups which has multiple values.
I need to filter some of the values which should not be displayed in the data tab of the table.
I have a column which does not have any value that I need to filter out (But its not an empty value because when I check I got to know that it has some blank spaces). It should display only the columns with non-blank value.
How can I remove those columns from the data set.
You can of course try scripting the data source query but you can also run a script on the table when it is created to hide the empty column.
Try this script in the table's onCreate event:
var mycolumnCount = this.getRowData().getColumnCount();
var DisNull = false;
for(i=1;i<mycolumnCount;i++) {
var temp = this.getRowData().getColumnValue(i)
if(this.getRowData().getColumnValue(i) == "") {
DisNull = true;
}else{
DisNull = false;
i = mycolumnCount+1;
}
}
if(DisNull == true) {
this.getStyle().display = "none"
}

Get all rows not filtered from jqGrid

I have local data in a grid. How can I get all of the rows or IDs that are not removed after a user uses the filter toolbar? I need to get all filtered rows, regardless of pagination.
For example, say I begin with 50 rows in the grid. The user uses the filter toolbar and the set of rows decreases to 10 rows. How can I get those ten rows?
There are no direct way to get the information which you need. Internally jqGrid uses $.jgrid.from to filter local data. The main code which uses $.jgrid.from in inside of addLocalData. To get results which you need without studying all the code I suggest to use the fact that all filtered data will be returned by select method of $.jgrid.from (see the line of code). My suggestion is to catch the data before the data will be cut to the page size.
To do this I suggest to use sub-classing: overwriting of the method select method of $.jgrid.from. I demonstrate the technique in the examples created for the answer and this one.
In your case the code will be
var oldFrom = $.jgrid.from,
lastSelected;
$.jgrid.from = function (source, initalQuery) {
var result = oldFrom.call(this, source, initalQuery),
old_select = result.select;
result.select = function (f) {
lastSelected = old_select.call(this, f);
return lastSelected;
};
return result;
};
Now the variable lastSelected will save the array of elements which are results of the last sorting or filtering operation. Because $.jgrid.from is global the data are not connected to the grid. If you have more as one grid on the page it will be uncomfortable. One can fix the small disadvantage with the following line in the code of loadComplate of every grid:
loadComplete: function () {
this.p.lastSelected = lastSelected; // set this.p.lastSelected
}
In the way we introduce new jqGrid parameter lastSelected which will have close structure as data parameter, but will hold only last filtered data.
The following code will display the ids of filtered data in alert message
$("#getIds").click(function () {
var filteredData = $grid.jqGrid('getGridParam', 'lastSelected'), i, n, ids = [],
idName = $grid.jqGrid('getGridParam', 'localReader').id;
if (filteredData) {
for (i = 0, n = filteredData.length; i < n; i++) {
ids.push(filteredData[i][idName]);
}
alert("tolal number of filtered data: " + n + "\n" +
"ids of filtered data:\n" + ids.join(', '));
}
});
I used localReader.id parameter because property name used for local data are typically id or _id_. The _id_ will be used in case of data loaded from the server if one uses loadonce: true option.
The demo demonstrate the approach. If one filter for example only the data from FedEx and then clicks on "Show Ids" button one will see information about all filtered and not only about the data displayed on the current page:
UPDATED: free jqGrid provides new lastSelectedData option. See the demo in the list of demos.
You colud use afterSearch option of the search toolbar:
var filteredIDs = new Array(); //Global variable
$("#"+gridId).jqGrid("filterToolbar", { stringResult:true, searchOnEnter:false,
afterSearch:function(){
filteredIDs = $("#"+gridId).getDataIDs();
}
});
If you want to get the filtered rows instead the filtered IDs, use getRowData() instead of getDataIDs().
All, I found another answer which is far easier to include
loadComplete: function (gridData) {
var isSearchPerformed = $grid.getGridParam("postData")._search;
if (isSearchPerformed) {
$("#spanFilterTotal").text(gridData.records);
}
All you want is below:
$.each($grid.getRowData(), function( index, value ) {
a.push(value["COLUMN_NAME"]); //Get the selected data you want
});

Resources