From 71aa87694f8bd8e8420c4e77aa591238b82180af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Gustavo=20Schuck?= Date: Tue, 25 Feb 2025 21:37:20 -0300 Subject: [PATCH] News 2025.02.25-1 --- NEWS.md | 20 ++++++- R/calculate_cols_module.R | 46 ++++++++------- R/rename_cols_module.R | 117 +++++++++++++++++++++++++++++++++++--- R/spada.R | 2 + R/spada_themes.R | 24 +++++++- R/spada_ui.R | 21 +++---- R/utils.R | 11 ++-- docs/news/index.html | 73 ++++++++++++++---------- docs/pkgdown.yml | 2 +- 9 files changed, 240 insertions(+), 76 deletions(-) diff --git a/NEWS.md b/NEWS.md index 6b95bc0..4510c96 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,7 +6,7 @@ editor_options: # Spada 0.1.0.9000 (development version) -## TO DO +## 0.1.0 Milestone 1 - Allow filter multiple conditions @@ -20,6 +20,24 @@ editor_options: 6 - Models: linear model, logistic regression, Kmeans, Trees +## 2025.02.25-1 + +Highlights: + +### Improvements + +1 - **Calculate Cols** module: now allows to calculate with groupby + +2 - **Rename Cols** module: now allows to rename multiple variables together + +3 - **spada.R**: new dependencie: tools package + +4 - **spada_themes.R**: new css for startup screen + +5 - **spada_ui.R**: change startup screen css (now in spada_themes) and busyindicator options (now the spinner is 'bars2') + +6 - **utils.R**: removed Range function (because it returns 2 values), correct a typo in ceilling function (now ceiling) and update in get_help_file for better visual + ## 2025.02.19-1 Highlights: New **Calculate Cols** module, better internal control over changes in datasets and many small visual improvements diff --git a/R/calculate_cols_module.R b/R/calculate_cols_module.R index b28a5f4..48a1489 100644 --- a/R/calculate_cols_module.R +++ b/R/calculate_cols_module.R @@ -1,5 +1,4 @@ - # ui -------------------------------------------------------------------------- calculate_cols_ui <- function(id) { ns <- NS(id) @@ -8,8 +7,9 @@ calculate_cols_ui <- function(id) { card_header('Apply Function', class = 'mini-header'), card_body( uiOutput(ns('ui_var_sel')), - textInput(ns('txt_new_name'), 'New name'), - uiOutput(ns('ui_fun_sel')) + textInput(ns('txt_new_name'), 'New variable name'), + uiOutput(ns('ui_fun_sel')), + uiOutput(ns('ui_var_groupby')) ), card_footer(btn_task( ns('btn_apply_fun'), 'Apply', icon('check') @@ -35,6 +35,13 @@ calculate_cols_server <- function(id, input_df) { selectInput(ns('vars_sel'), 'Variable', c('', df_names())) }) + # render variables group ------------------------------------------------- + output$ui_var_groupby <- renderUI({ + selectizeInput(ns('vars_groupby'), 'Group by', c('None' = NULL, df_names()), + multiple = T, + options = list(plugins = list('remove_button', 'clear_button'))) + }) + # suggest name for new variable ------------------------------------------- observe({ req(input$vars_sel) @@ -48,24 +55,20 @@ calculate_cols_server <- function(id, input_df) { obj_type(df$df_active[[input$vars_sel]]) }) - output$ui_fun_sel <- renderUI({ req(input$vars_sel) - if (selected_var_type() == 'numeric') { - selectInput(ns('fun'), 'Choose a function', choices = math_funs) - } else if (selected_var_type() == 'char'){ - selectInput(ns('fun'), 'Choose a function', choices = char_funs) - } else if (selected_var_type() == 'date'){ - selectInput(ns('fun'), 'Choose a function', choices = date_funs) - } else if (selected_var_type() == 'logical'){ - selectInput(ns('fun'), 'Choose a function', choices = logical_funs) - } else if (selected_var_type() == 'factor'){ - selectInput(ns('fun'), 'Choose a function', choices = factor_funs) - } else if (selected_var_type() == 'complex'){ - selectInput(ns('fun'), 'Choose a function', choices = complex_funs) - } else { - selectInput(ns('fun'), 'Choose a function', choices = character(0)) - } + + selectInput(ns('fun'), 'Choose a function', choices = switch( + selected_var_type(), + "numeric" = math_funs, + "char" = char_funs, + "date" = date_funs, + "logical" = logical_funs, + "factor" = factor_funs, + "complex" = complex_funs, + character(0) + )) + }) observe({ @@ -78,10 +81,11 @@ calculate_cols_server <- function(id, input_df) { temp <- copy(df$df_active) - temp[, new_var := fun(var1), env = list( + temp[, new_var := fun(var1), by = groupby, env = list( new_var = input$txt_new_name, fun = input$fun, - var1 = input$vars_sel + var1 = input$vars_sel, + groupby = input$vars_groupby |> as.list() )] df$df_active <- copy(temp) diff --git a/R/rename_cols_module.R b/R/rename_cols_module.R index f5002d0..74a109f 100644 --- a/R/rename_cols_module.R +++ b/R/rename_cols_module.R @@ -3,13 +3,56 @@ rename_cols_ui <- function(id) { ns <- NS(id) - card( - card_header('Rename Columns', class = 'mini-header'), - card_body( - uiOutput(ns('ui_var_sel')), - textInput(ns('txt_new_name'), 'New name'), + layout_column_wrap( + card( + card_header('Rename Column', class = 'mini-header'), + card_body( + uiOutput(ns('ui_var_sel')), + textInput(ns('txt_new_name'), 'New name'), + ), + card_footer(btn_task(ns('btn_rename'), 'Rename Variable', icon('check'))) ), - card_footer(btn_task(ns('btn_rename'), 'Rename Variable', icon('check'))) + card( + card_header('Rename Multiple Columns', class = 'mini-header'), + card_body( + uiOutput(ns('ui_var_sel_multi')), + radioButtons(ns('rename_method'), 'Rename Method', + choices = c('Add Prefix/Suffix' = 'prefix_suffix', + 'Apply Function' = 'function', + 'Replace Part' = 'replace', + 'Remove Part' = 'remove')), + + conditionalPanel( + condition = sprintf("input['%s'] == 'prefix_suffix'", ns('rename_method')), + textInput(ns('txt_new_name_multi'), 'New name part'), + radioButtons(ns('part_position'), 'Part Position', + choices = c('Prefix' = 'prefix', 'Suffix' = 'suffix')), + radioButtons(ns('name_separator'), 'Separator', + choices = c('Underscore (_)' = '_', 'Dot (.)' = '.', 'None' = '')) + ), + + conditionalPanel( + condition = sprintf("input['%s'] == 'function'", ns('rename_method')), + selectInput(ns('name_function'), 'Function to Apply', + choices = c('Upper Case' = 'toupper', + 'Lower Case' = 'tolower', + 'Title Case' = 'toTitleCase')) + ), + + conditionalPanel( + condition = sprintf("input['%s'] == 'replace'", ns('rename_method')), + textInput(ns('txt_replace_part'), 'Part to Replace'), + textInput(ns('txt_replace_new_part'), 'New Part'), + ), + + conditionalPanel( + condition = sprintf("input['%s'] == 'remove'", ns('rename_method')), + textInput(ns('txt_remove_part'), 'Part to Remove') + ), + + ), + card_footer(btn_task(ns('btn_rename_multi'), 'Rename Variables', icon('check'))) + ) ) } @@ -26,6 +69,7 @@ rename_cols_server <- function(id, input_df) { df$df_active <- input_df() }) + # rename 1 variable ------------------------------------------------------ output$ui_var_sel <- renderUI({ selectInput(ns('vars_sel'), 'Variable', c('', df_names())) }) @@ -43,9 +87,10 @@ rename_cols_server <- function(id, input_df) { setnames(temp, input$vars_sel, input$txt_new_name) df$df_active <- copy(temp) - rm(temp) - msg('Rename columns: OK') + rm(temp) + + msg('Rename column: OK') } else { msg_error('New name is not valid or already in use') } @@ -53,6 +98,62 @@ rename_cols_server <- function(id, input_df) { } }) |> bindEvent(input$btn_rename) + # rename multiple veriables ----------------------------------------------- + output$ui_var_sel_multi <- renderUI({ + selectizeInput(ns('vars_sel_multi'), 'Variables', c('', df_names()), + multiple = T, + options = list(plugins = list('remove_button', 'clear_button'))) + }) + + observe({ + req(input$vars_sel_multi, df$df_active) + if(input$vars_sel_multi |> length() == 0){ + msg('Select at least one variable') + } else { + + temp <- copy(df$df_active) + new_names <- input$vars_sel_multi + + if (input$rename_method == 'prefix_suffix') { + req(input$txt_new_name_multi) + if (input$part_position == 'prefix') { + new_names <- paste0(input$txt_new_name_multi, + input$name_separator, new_names) + } else if (input$part_position == 'suffix'){ + new_names <- paste0(new_names, input$name_separator, + input$txt_new_name_multi) + } + } else if (input$rename_method == 'function') { + new_names <- sapply(new_names, match.fun(input$name_function)) + } else if (input$rename_method == 'replace') { + req(input$txt_replace_part, input$txt_replace_new_part) + new_names <- gsub(input$txt_replace_part, input$txt_replace_new_part, + new_names, fixed = TRUE) + } else if (input$rename_method == 'remove') { + req(input$txt_remove_part) + new_names <- gsub(input$txt_remove_part, '', new_names, fixed = TRUE) + } + + # Validação de nomes únicos e válidos -------------------------------- + if (is_valid_name(new_names) |> all()) { + + if(all(new_names %in% df_names())) { + msg('No changes to apply') + } else if (any(new_names %in% df_names())) { + msg_error('Some new names already in use') + } else { + setnames(temp, input$vars_sel_multi, new_names) + df$df_active <- copy(temp) + msg('Rename columns: OK') + rm(temp) + } + } else { + msg_error('New names are not valid') + } + } + }) |> bindEvent(input$btn_rename_multi) + + # return of module -------------------------------------------------------- return(list(df_rename_cols = reactive(df$df_active))) }) } diff --git a/R/spada.R b/R/spada.R index feba4b2..1d8e2a0 100644 --- a/R/spada.R +++ b/R/spada.R @@ -48,6 +48,8 @@ #' @importFrom stats cor lm sd var median rnorm IQR cor.test dnorm ks.test #' qnorm qqline qqnorm shapiro.test #' +#' @importFrom tools toTitleCase +#' #' @importFrom utils object.size head spada <- function(...) { diff --git a/R/spada_themes.R b/R/spada_themes.R index 7307051..0082924 100644 --- a/R/spada_themes.R +++ b/R/spada_themes.R @@ -6,6 +6,7 @@ bg_color <- '#f9f9f9' secondary <- '#0072B2' sucess <- '#009E73' +startup_text_color <- '#FFFFFF' # palettes -------------------------------------------------------------------- gray_palette <- c('#ffffff', '#585858', '#232323') blue_palette <- c('#ffffff', '#096691', '#134359') @@ -30,9 +31,30 @@ theme_basic_rules <- as_sass( grad5 = '#5fa3c2', grad6 = '#4e96b6', navbar_bg = '#007bb5', - stati_card_text = '#ffffff' + stati_card_text = '#ffffff', + startup_bg = main_color ), " + + .startup-screen { + background-color: $startup_bg; + width: 500000px; + height: 250px; + /*border-radius: 15px 50px 15px 50px; + border-style: dotted; + border-color: white;*/ + } + + .startup-screen h1 { + font-family: Times; + font-size: 150px; + } + + .startup-screen h3 { + font-family: Times; + font-size: 30px; + } + .navbar { background: $navbar_bg !important; height: 45px !important; diff --git a/R/spada_ui.R b/R/spada_ui.R index d462952..49ea366 100644 --- a/R/spada_ui.R +++ b/R/spada_ui.R @@ -2,19 +2,23 @@ # Function with the ui of spada.R spada_ui <- function(){ tagList( + + busyIndicatorOptions( + spinner_type = 'bars2', + spinner_color = main_color, + fade_opacity = '0.1' + ), + useBusyIndicators(), busy_start_up( - loader = spin_epic('orbit', color = '#FFFFFF'), + loader = spin_epic('orbit', color = startup_text_color), text = tagList( - h1('Spada', - style = "font-family: 'Times'; font-size: 120px;"), - h3('R > Shiny > You', - style = "font-family: 'Times'; font-size: 20px;") + div(class = 'startup-screen', h1('Spada'), h3('R > Shiny > You')) ), mode = 'auto', timeout = 1200, - color = '#FFFFFF', + color = startup_text_color, background = main_color ), @@ -94,10 +98,7 @@ spada_ui <- function(){ ), nav_panel( 'Rename', - layout_column_wrap( - rename_cols_ui('pE_rename_cols'), - card() - ) + rename_cols_ui('pE_rename_cols') ), nav_panel( 'Calculate', diff --git a/R/utils.R b/R/utils.R index 96f528f..7fab55c 100644 --- a/R/utils.R +++ b/R/utils.R @@ -14,7 +14,7 @@ math_funs <- c( 'First' = 'fina', 'Last' = 'lana', 'Lag' = 'shift', - 'Range' = 'range', + # 'Range' = 'range', 'IQR' = 'IQR', 'Skewness' = 'Skew', 'Kurtosis' = 'Kurt', @@ -27,7 +27,7 @@ math_funs <- c( 'Log' = 'log', 'Log2' = 'log2', 'Log10' = 'log10', - 'Ceilling' = 'ceilling', + 'Ceiling' = 'ceiling', 'Floor' = 'floor', 'Trunc' = 'trunc', 'Signif' = 'signif', @@ -306,8 +306,11 @@ ttip <- function(TRIGGER, ..., ID = NULL, PLACE = 'top'){ # get function help ----------------------------------------------------------- get_help_file <- function(pak, fun){ - utils::capture.output( - tools::Rd2HTML(tools::Rd_db(pak)[[paste0(fun, '.Rd')]]) + paste( + utils::capture.output( + tools::Rd2HTML(tools::Rd_db(pak)[[paste0(fun, '.Rd')]]) + ), + collapse = '\n' ) } diff --git a/docs/news/index.html b/docs/news/index.html index 1fbc8d7..389f52b 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -60,7 +60,7 @@

Changelog

-

TO DO

+

0.1.0 Milestone

1 - Allow filter multiple conditions

2 - Allow create and calculate variables

3 - Functionalities to detect and treat duplicates

@@ -69,10 +69,23 @@

TO DO +

2025.02.25-1

+

Highlights:

+
+

Improvements

+

1 - Calculate Cols module: now allows to calculate with groupby

+

2 - Rename Cols module: now allows to rename multiple variables together

+

3 - spada.R: new dependencie: tools package

+

4 - spada_themes.R: new css for startup screen

+

5 - spada_ui.R: change startup screen css (now in spada_themes) and busyindicator options (now the spinner is ‘bars2’)

+

6 - utils.R: removed Range function (because it returns 2 values), correct a typo in ceilling function (now ceiling) and update in get_help_file for better visual

+
+

+

2025.02.19-1

Highlights: New Calculate Cols module, better internal control over changes in datasets and many small visual improvements

-

Improvements

+

Improvements

1 - New Calculate Cols module: allow create new variable by applying a function

2 - Convert Cols, Data Overview, Filter Rows, Order Cols, Order Rows, Rename Cols and Select Cols modules and spada_server.R: now uses data.table::copy to return changes in dataset properly and maintaining the correct update in reactives (problem probably caused by changes by reference in data.table). Removed all triggers (df_trigger reactiValues) used before.

3 - Data Overview, Navbar_df_info and Sidebar modules: removed stylling code (passed to spada_themes).

@@ -85,7 +98,7 @@

Improvements2025.02.16-1

Highlights: New Darkly theme and new dependencie: sass package.

-

Improvements

+

Improvements

1 - Correlation, Descriptive Stats, Normality Test, Sidebar, Spada UI, Z Test modules: changes in visual parameters and elements (e.g. sidebar now has class) for usage of bs_theme

2 - Export File module: now downloadButton has class and correct icon

3 - Filter Rows module: new Number of Rows filter

@@ -97,7 +110,7 @@

Improvements2025.02.13-1

Highlights: Use of selectizeInput with close and clear button for multiple selections

-

Improvements

+

Improvements

1 - Convert Cols, Descriptive Stats, Order Cols, Order Rows and Select Cols modules: now usage of selectizeInput with close and clear button for multiple selections

2 - utils.R: filter_rows function now with env = list(var1) in data.table instead of get(var)

3 - spada.R: now usage of importFrom for data.table package

@@ -107,7 +120,7 @@

Improvements2025.02.11-1

Highlights: New filter options in Filter Rows Module

-

Improvements

+

Improvements

1 - Filter Rows module: new options to filter: compare two variables and sample

2 - Config Page module: Inicial hex color now in caps

3 - utils.R: new function filter_rows_2vars for compare two variables and col_type

@@ -121,7 +134,7 @@

Bug Fixes1 - Analysis > Scatter: warning if two Factors variables: fixed, now requires numeric variables (#18)

-

Improvements

+

Improvements

1 - Descriptive Stats module: added geometric mean, harmonic mean, skewness and kurtosis from DescTools package.

2 - Normality test module: new test, Shapiro-Francia from DescTools package.

3 - Exploratory module: bug fix in scatter. (#18)

@@ -135,7 +148,7 @@

Bug Fixes1 - Data > Import: check for already used name not working: the names were not beeing passed as reactive to File Import module. Fixed. (#17)

-

Improvements

+

Improvements

1 - Import file module: now csv has a number of lines to read parameter and can read sav (SPSS) files

2 - Z Test module: now has a plot with test results

3 - utils.R: plot_z_test function

@@ -150,7 +163,7 @@

Bug Fixes1 - Analysis > Descriptive Stats: error in round for factors: now f_num function only format numeric values (#16)

-

Improvements

+

Improvements

1 - navbar_df_info and sidebar modules: now number of rows with 1 decimal value (function f_num) for better look (solve side effect after use of nsmall in previous release)

2 - New Rename Cols module: new module for rename variables of active dataset

@@ -159,7 +172,7 @@

Improvements2025.02.01-1

Only visual and formatting changes.

-

Improvements

+

Improvements

1 - Convert Cols, Data Overview and Sidebar modules: background color receive object bg_color

2 - Correlation, Normality Test and Z Test modules: sidebars color now with bg_color object and stati_card with blue color

3 - Descriptive Stats module: gain digits input and f_num for format values

@@ -176,7 +189,7 @@

Bug Fixes1 - Analysis > Normality Test > Shapiro: error if all values are equal: Shapiro does not accept all equal values. Now with check and msg_error (#15)

-

Improvements

+

Improvements

1 - Correlation module: chane name of Alternatives and chance card header title to Correlation Test

2 - Export file module: now writes Sav (haven package) and uses checkbox to compress RDS

3 - Normality Test module: better names and better checks for Shapiro-Wilk Test (#15)

@@ -190,7 +203,7 @@

Improvements

2025.01.28-1

-

Improvements

+

Improvements

1 - New Z Test module: new module for Z test (DescTools::ZTest)

@@ -202,7 +215,7 @@

Bug Fixes2 - Analysis > Correlation: not enough finite observations: stats::cor.test for Pearson demands at least 3 valid values (Spearman and Kendal a least 2 valid values). New check throughs a error message if less than 3 valid values for all methods. (#14)

-

Improvements

+

Improvements

1 - Correlation module: now check if Standard Deviation of any informed variable is zero, avoiding warning. Also fixed (#14).

2 - Exploratory module: now with req (for main variable and variable 2) in render_plot (output$gt_dist)

3 - Stats table module: align columns, use ‘-’ for sub_missing becasue the long dash is not an ASCII and could not be replicated in sub_values (devtools::check). Also fixed (#13)

@@ -218,7 +231,7 @@

Bug Fixes2 - Exploratory Page > Stats table: Mode NA for numeric, date, logical and complex var: the gt table was receiving tha NA value as character and the function sub_missing() does not have effect on those values. Now the Mode is passed as character only if it is not NA. (#12)

-

Improvements

+

Improvements

1 - Descriptive Stats module: now Mode returns NA (not as character) and only paste/collapse values if Mode exists. Inserted sub_missing() in gt_stats for better look and consistency with other views

2 - Stats table module: now Mode returns NA (not as character) and only paste/collapse values if Mode exists

3 - Exploratory module: now the Variable 2 can not be float in Boxplot by Groups, because does not seam reasonable to have an infinite number of groups. Related to (#11)

@@ -231,7 +244,7 @@

Bug Fixes1 - Filter rows: operators NA and not NA requires a value to apply the filter: fixed, filter_rows_module.R refactored, now with much more robust check for filters, operators and values (#10)

-

Improvements

+

Improvements

1 - New dependencie: package DescTools

2 - Descriptive Stats module: now with Mode (DescTools package) for numeri, character and factor variables

3 - Filter Rows module: refactored to check operators and values. New operators: Outlier (and Not Outlier) and Logical (TRUE and FALSE)

@@ -242,7 +255,7 @@

Improvements

2025.01.22-1

-

Improvements

+

Improvements

1 - Correlation module: parameters in card sidebar for better use of space

2 - df_info function: new test file and now returns empty data.frame (accepted by gt_info) in case of no columns in the entry data.frame

3 - Normality test module: now Ks and Shapiro-wilk tests have gt table, save button and statiCards

@@ -252,7 +265,7 @@

Improvements

2025.01.21-1

-

Improvements

+

Improvements

1 - Correlation module: new layout, new table with test results, help button (help documentation), save table button and statiCards (shnywidgets) with Correlation and p value.

2 - Descriptive Stats module: now with variable selected by default

3 - Normality test module: new Help button in Ks test and Shapiro-Wilk test

@@ -263,7 +276,7 @@

Improvements

2025.01.20-1

-

Improvements

+

Improvements

1 - Startup page: now with startup page with shinybusy package (new dependencie)

2 - radioGroupButtons: change some radioButtons (shiny) for radioGroupButtons (shinyWidgets) in data_overview_module and exploratory_module for better look

3 - Page config module: colorPickr now with ‘save’ mode for better reset of values and other visual changes fo better look

@@ -276,7 +289,7 @@

Improvements

2025.01.17-1

-

Improvements

+

Improvements

1 - New module: Filter Rows

2 - Convert module: always align right the preview table

3 - Descriptive Stats module: now all options inicially as TRUE

@@ -291,7 +304,7 @@

Improvements

2025.01.14-1

-

Improvements

+

Improvements

1 - New module: Normality test

2 - Module Correlation > Scatter Plot now has a button to render plot

3 - Module Descriptive Stats now has a button to render table

@@ -305,7 +318,7 @@

Bug Fixes1 - Edit > Filter: Factor var - no levels after choose operator: fixed (inserted req(operator)). Now the levels are shown when a factor var and an operator are selected. (#9)

-

Improvements

+

Improvements

1 - testthat: create structure to run tests (test-fina.R as initial test)

2 - New modules: Order Rows, Convert Cols and Exploratory

3 - Correlation module: insert req in scatter plot

@@ -320,7 +333,7 @@

Improvements

2025.01.12-1

-

Improvements

+

Improvements

1 - New modules: Sidebar and Navbar Df Info

2 - New function filter_rows in utils.R

3 - New reactives: df_active_ncol, df_active_resume_data and df$df_trigger (to use for updates)

@@ -346,7 +359,7 @@

Bug Fixes1 - Analysis > Exploratory: error ins stats table when percentile out of range 0-100: now test the range and if the input isTruphy (#8)

-

Improvements

+

Improvements

1 - Stats table now is a module

2 - new module Correlation

3 - new module Descriptive Stats

@@ -364,7 +377,7 @@

Bug Fixes4 - Edit > Filter: accept blank value: now the value must have length 1 or bigger (#7)

-

Improvements

+

Improvements

1 - utils functions

2 - page_config_module: correction of a typo

3 - spada function

@@ -380,7 +393,7 @@

Bug Fixes1 - Data Overview - after Edit only refresh if updat in rows or sample: fixed with insertion of buttons inside output$pD_over_gt. (#3)

-

Improvements

+

Improvements

1 - export_file_module: separator order now semicolon as default

2 - new import_file_module: allows input csv and RDS files

3 - page_config_module: new visual and size of input file as parameter

@@ -404,7 +417,7 @@

Bug Fixes2 - Metadata - Error in zeros count: now df_info function uses suna(x == 0) instead of length(x[x == 0]) (#2)

-

Improvements

+

Improvements

1 - utils functions