Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Column Renaming for Selected Columns #9282

Merged
27 changes: 25 additions & 2 deletions instat/dlgName.vb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Public Class dlgName
Private clsStartwithFunction, clsRegexFunction, clsEndswithFunction, clsMatchesFunction, clsContainsFunction As New RFunction
Private WithEvents grdCurrentWorkSheet As Worksheet
Private dctRowsNewNameChanged As New Dictionary(Of Integer, String)
Private dctRowsCurrentName As New Dictionary(Of Integer, String)
Private dctRowsNewLabelChanged As New Dictionary(Of Integer, String)
Private dctNameRowsValues As New Dictionary(Of Integer, String)
Private dctCaseOptions As New Dictionary(Of String, String)
Expand Down Expand Up @@ -99,7 +100,7 @@ Public Class dlgName
ucrPnlCase.AddRadioButton(rdoAbbreviate, "abbreviate")
ucrPnlCase.AddRadioButton(rdoReplace, "stringr::str_replace")

ucrPnlSelectData.SetParameter(New RParameter("data", 0))

ucrPnlSelectData.AddRadioButton(rdoWholeDataFrame)
ucrPnlSelectData.AddRadioButton(rdoSelectedColumn)
ucrPnlSelectData.AddParameterValuesCondition(rdoWholeDataFrame, "checked", "whole")
Expand Down Expand Up @@ -189,6 +190,7 @@ Public Class dlgName
ucrSelectVariables.Reset()
dctRowsNewNameChanged.Clear()
dctRowsNewLabelChanged.Clear()
dctRowsCurrentName.Clear()
bCurrentCell = False
clsNewColNameDataframeFunction.SetRCommand("data.frame")

Expand Down Expand Up @@ -353,10 +355,14 @@ Public Class dlgName
If e.Range.Rows > 1 Then
For iRow As Integer = iStartRowIndex To grdCurrentWorkSheet.SelectionRange.EndRow
Dim strNewData As String = ValidateRVariable(grdCurrentWorkSheet.GetCellData(row:=iRow, col:=iColIndex), iColIndex)
Dim strOldData As String = grdCurrentWorkSheet.GetCellData(row:=iRow, col:=0)
GetOldNames(iRow, strOldData)
RenameColumns(strNewData, iRow, iColIndex)
Next
Else
Dim strNewData As String = ValidateRVariable(grdCurrentWorkSheet.GetCellData(row:=e.Range.Row, col:=iColIndex), iColIndex)
Dim strOldData As String = grdCurrentWorkSheet.GetCellData(row:=e.Range.Row, col:=0)
GetOldNames(e.Range.Row, strOldData)
RenameColumns(strNewData, iStartRowIndex, iColIndex)
End If
ValidateNamesFromDictionary(iColIndex)
Expand Down Expand Up @@ -406,18 +412,30 @@ Public Class dlgName
Private Sub grdCurrSheet_AfterCellEdit(sender As Object, e As CellAfterEditEventArgs) Handles grdCurrentWorkSheet.AfterCellEdit
Dim iCol As Integer = e.Cell.Column
Dim strNewData As String = ValidateRVariable(e.NewData, iCol)

Dim strFirstColumnData As String = grdCurrentWorkSheet(e.Cell.Row, 0).ToString()

GetOldNames(e.Cell.Row, strFirstColumnData)
RenameColumns(strNewData, e.Cell.Row, iCol)
ValidateNamesFromDictionary(iCol)
End Sub

Private Sub GetOldNames(iRow As Integer, strOldName As String)
If Not dctRowsCurrentName.ContainsKey(iRow) Then
dctRowsCurrentName.Add(iRow, strOldName)
Else
dctRowsCurrentName(iRow) = strOldName
End If
End Sub

Private Sub GetVariables(strNewData As String, iRowIndex As Integer, iColIndex As Integer)
If rdoMultiple.Checked Then
If iColIndex = 1 Then
If strNewData <> "" Then
AddChangedNewNameRows(iRowIndex, strNewData)

clsNewColNameDataframeFunction.AddParameter("cols", GetValuesAsVector(dctRowsNewNameChanged), iPosition:=0)
clsNewColNameDataframeFunction.AddParameter("index", "c(" & String.Join(",", dctRowsNewNameChanged.Keys.ToArray) & ")", iPosition:=1)
clsNewColNameDataframeFunction.AddParameter("old_names", GetValuesAsVector(dctRowsCurrentName), iPosition:=1)
clsDefaultRFunction.AddParameter("new_column_names_df", clsRFunctionParameter:=clsNewColNameDataframeFunction, iPosition:=8)
Else
clsNewColNameDataframeFunction.RemoveParameterByName("cols")
Expand Down Expand Up @@ -602,7 +620,9 @@ Public Class dlgName
rdoReplace.Visible = rdoWholeDataFrame.Checked
If rdoWholeDataFrame.Checked Then
ucrReceiverColumns.Visible = False
clsDummyFunction.AddParameter("checked", "whole", iPosition:=1)
Else
clsDummyFunction.AddParameter("checked", "selected", iPosition:=1)
ucrReceiverColumns.SetMeAsReceiver()
If rdoReplace.Checked Then
rdoMakeCleanNames.Checked = True
Expand Down Expand Up @@ -681,6 +701,8 @@ Public Class dlgName
Dim parsedValue As Boolean
Dim strNewData As String = ValidateRVariable(e.Text, iCol)
If Not strNewData.ToLower.Equals("t") AndAlso Not strNewData.ToLower.Equals("f") AndAlso Not IsNumeric(strNewData) AndAlso Not Boolean.TryParse(strNewData, parsedValue) Then
Dim strFirstColumnData As String = grdCurrentWorkSheet(e.Cell.Row, 0).ToString()
GetOldNames(e.Cell.Row, strFirstColumnData)
RenameColumns(strNewData, e.Cell.Row, iCol)
ValidateNamesFromDictionary(iCol)
End If
Expand Down Expand Up @@ -713,6 +735,7 @@ Public Class dlgName
clsDefaultRFunction.AddParameter(".cols", clsRFunctionParameter:=clsContainsFunction, iPosition:=3)
clsDefaultRFunction.AddParameter(".fn", "stringr::str_replace_all", iPosition:=2)
End Select

Else
clsDefaultRFunction.RemoveParameterByName("replacement")
clsDefaultRFunction.RemoveParameterByName(".cols")
Expand Down
6 changes: 6 additions & 0 deletions instat/dlgSelect.vb
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ Public Class dlgSelect
End Sub

Private Sub cmdDefineNewSelect_Click(sender As Object, e As EventArgs) Handles cmdDefineNewSelect.Click
If frmMain.IsColumnSelectionApplied Then
Dim clsRemoveCurrentSelection As New RFunction
clsRemoveCurrentSelection.SetRCommand(frmMain.clsRLink.strInstatDataObject & "$remove_current_column_selection")
clsRemoveCurrentSelection.AddParameter("data_name", Chr(34) & ucrSelectorForSelectColumns.strCurrentDataFrame & Chr(34))
frmMain.clsRLink.RunScript(clsRemoveCurrentSelection.ToScript, strComment:="Remove current selection")
End If
dlgSelectColumns.SetDefaultDataFrame(ucrSelectorForSelectColumns.ucrAvailableDataFrames.strCurrDataFrame)
dlgSelectColumns.ShowDialog()
ucrSelectorForSelectColumns.LoadList()
Expand Down
4 changes: 4 additions & 0 deletions instat/frmMain.vb
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,10 @@ Public Class frmMain
ucrDataViewer.UseColumnSelectionInDataView(bUseColumnSelecion)
End Sub

Public Function IsColumnSelectionApplied() As Boolean
Return ucrDataViewer.IsColumnSelectionApplied
End Function

Public Sub SetCurrentDataFrame(strDataName As String)
ucrDataViewer.SetCurrentDataFrame(strDataName)
ucrColumnMeta.SetCurrentDataFrame(strDataName)
Expand Down
69 changes: 65 additions & 4 deletions instat/static/InstatObject/R/data_object_R6.R
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,36 @@ DataSheet$set("public", "cor", function(x_col_names, y_col_name, use = "everythi
}
)

DataSheet$set("public", "update_selection", function(new_values, column_selection_name = NULL) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you set it to be an error if column_selection_name = NULL, then you can just set column_selection_name here, and run it like you have run new_values (i.e., with if(missing(column_selection_name)) ... - unless I'm missing something?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

if (missing(new_values)) stop("new_values is required")
if (missing(column_selection_name)) stop("column_selection_name is required")

column_selection_obj <- private$column_selections[[column_selection_name]]

if (is.null(column_selection_obj)) {
stop("No column selection found with the name: ", column_selection_name)
}

# Update conditions in the column selection with new values
updated_conditions <- lapply(column_selection_obj$conditions, function(condition) {
# Check if the parameters exist and replace them with new values
if ("parameters" %in% names(condition)) {
condition$parameters$x <- new_values
}
return(condition)
})

# Update the column selection object with the new conditions
column_selection_obj$conditions <- updated_conditions
private$column_selections[[column_selection_name]] <- column_selection_obj

# Optionally, mark data as changed
self$data_changed <- TRUE

message("Column selection '", column_selection_name, "' updated successfully with new values.")
})


DataSheet$set("public", "rename_column_in_data", function(curr_col_name = "", new_col_name = "", label = "", type = "single", .fn, .cols = everything(), new_column_names_df, new_labels_df, ...) {
curr_data <- self$get_data_frame(use_current_filter = FALSE, use_column_selection = FALSE)

Expand Down Expand Up @@ -954,8 +984,18 @@ DataSheet$set("public", "rename_column_in_data", function(curr_col_name = "", ne
purrr::map(.x = keys_to_delete, .f = ~self$remove_key(key_name = names(active_keys[.x])))
}
}
if(self$column_selection_applied()) self$remove_current_column_selection()
# Need to use private$data here because changing names of data field
names(private$data)[names(curr_data) == curr_col_name] <- new_col_name

column_names <- self$get_column_names()

if (anyNA(column_names)) {
column_names[is.na(column_names)] <- new_col_name
} else {
column_names <- new_col_name
}

self$update_selection(column_names, private$.current_column_selection$name)
if(any(c("sfc", "sfc_MULTIPOLYGON") %in% class(private$data[[curr_col_name]]))){
# Update the geometry column reference
sf::st_geometry(private$data) <- new_col_name
Expand All @@ -976,11 +1016,22 @@ DataSheet$set("public", "rename_column_in_data", function(curr_col_name = "", ne
} else if (type == "multiple") {
if (!missing(new_column_names_df)) {
new_col_names <- new_column_names_df[, 1]
cols_changed_index <- new_column_names_df[, 2]
cols_changed_index <- which(names(private$data) %in% new_column_names_df[, 2])
curr_col_names <- names(private$data)
curr_col_names[cols_changed_index] <- new_col_names
if(any(duplicated(curr_col_names))) stop("Cannot rename columns. Column names must be unique.")
if(self$column_selection_applied()) self$remove_current_column_selection()
names(private$data)[cols_changed_index] <- new_col_names

column_names <- self$get_column_names()

if (anyNA(column_names)) {
column_names[is.na(column_names)] <- new_col_names
} else {
column_names <- new_col_names
}

self$update_selection(column_names, private$.current_column_selection$name)

if(any(c("sfc", "sfc_MULTIPOLYGON") %in% class(private$dataprivate$data)[cols_changed_index])){
# Update the geometry column reference
sf::st_geometry(private$data) <- new_col_names
Expand All @@ -1005,19 +1056,29 @@ DataSheet$set("public", "rename_column_in_data", function(curr_col_name = "", ne
} else if (type == "rename_with") {
if (missing(.fn)) stop(.fn, "is missing with no default.")
curr_col_names <- names(curr_data)
column_names <- self$get_column_names()
private$data <- curr_data |>
dplyr::rename_with(
.fn = .fn,
.cols = {{ .cols }}, ...
)

if(self$column_selection_applied()) self$remove_current_column_selection()
new_col_names <- names(private$data)
if (!all(new_col_names %in% curr_col_names)) {
new_col_names <- new_col_names[!(new_col_names %in% curr_col_names)]
for (i in seq_along(new_col_names)) {
self$append_to_variables_metadata(new_col_names[i], name_label, new_col_names[i])
}

column_names <- self$get_column_names()
if (anyNA(column_names)) {
column_names[is.na(column_names)] <- new_col_names
} else {
column_names <- new_col_names
}

self$update_selection(column_names, private$.current_column_selection$name)

self$data_changed <- TRUE
self$variables_metadata_changed <- TRUE
}
Expand Down
4 changes: 4 additions & 0 deletions instat/ucrDataView.vb
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,10 @@ Public Class ucrDataView
End If
End Sub

Public Function IsColumnSelectionApplied() As Boolean
Return GetCurrentDataFrameFocus().clsFilterOrColumnSelection.bColumnSelectionApplied
End Function

Private Function GetSelectedColumns() As List(Of clsColumnHeaderDisplay)
Return _grid.GetSelectedColumns()
End Function
Expand Down
Loading