IDEMSInternational / R-Instat

A statistics software package powered by R
http://r-instat.org/
GNU General Public License v3.0
38 stars 103 forks source link

Paste no longer works in the test version #9207

Open rdstern opened 5 days ago

rdstern commented 5 days ago

@N-thony so-far-so-good on the test version. I have been writing the help on your undo and it is working well.

Now I have found the first bug and that is that the paste operation no longer seems to work.

I tried in diamonds, and then survey, just copying 3 cells from a single column and pasting them lower down into the same column. By the way the warning may have to change, because (when it works) I assume and hope, when it works that it can now be undone>

image Anyway now I get this error:

image

So there is a problem now in the data_book$paste_from_clipboard function to be fixed!

I know this gives you new work, but in a way I'm quite pleased - this is what our testing is all about!!!

N-thony commented 4 days ago

@N-thony so-far-so-good on the test version. I have been writing the help on your undo and it is working well.

Now I have found the first bug and that is that the paste operation no longer seems to work.

I tried in diamonds, and then survey, just copying 3 cells from a single column and pasting them lower down into the same column. By the way the warning may have to change, because (when it works) I assume and hope, when it works that it can now be undone>

image Anyway now I get this error:

image

So there is a problem now in the data_book$paste_from_clipboard function to be fixed!

I know this gives you new work, but in a way I'm quite pleased - this is what our testing is all about!!!

@rdstern this bug was there for long. I check in version 0.7.17 and I get the same error. I guess @Patowhiz has worked on the paste_from_clipboard function. Can you have a look? image

N-thony commented 4 days ago

@Patowhiz I did a quick check on chatgpt and the issue arises in the loop where you're trying to replace values in the selected columns. Specifically, when you assign new_values <- clip_tbl[, index], new_values is a vector, and if you later use it directly in a conditional check, it will lead to the mentioned error. If you agree with code below, then someone in the team can update it?

Reads passed clipboard data and saves it to the selected data frame

DataSheet$set("public", "paste_from_clipboard", function(col_names, start_row_pos = 1, first_clip_row_is_header = FALSE, clip_board_text) {

Get the clipboard text contents as a data frame

clip_tbl <- clipr::read_clip_tbl(x = clip_board_text, header = first_clip_row_is_header)

Get the selected data frame

current_tbl <- self$get_data_frame(use_current_filter = FALSE)

Check if copied data rows are more than current data rows

if (nrow(clip_tbl) > nrow(current_tbl)) { stop(paste("Rows copied cannot be more than number of rows in the data frame.", "Current data frame rows:", nrow(current_tbl), ". Copied rows:", nrow(clip_tbl))) }

If column names are missing, then just add the clip data as new columns and quit function

if (missing(col_names)) {

Append missing values if rows are less than the selected data frame.

# New column rows should be equal to existing column rows
if (nrow(clip_tbl) < nrow(current_tbl)) {
  empty_values_df <- data.frame(data = matrix(data = NA, nrow = (nrow(current_tbl) - nrow(clip_tbl)), ncol = ncol(clip_tbl)))
  names(empty_values_df) <- names(clip_tbl)
  clip_tbl <- rbind(clip_tbl, empty_values_df)
}
new_col_names <- colnames(clip_tbl)
for (index in seq_along(new_col_names)) {
  self$add_columns_to_data(col_name = new_col_names[index], col_data = clip_tbl[, index])
}
return()

}

For existing column names

Check if the number of copied columns and selected columns are equal

if (ncol(clip_tbl) != length(col_names)) { stop(paste("Number of columns are not the same.", "Selected columns:", length(col_names), ". Copied columns:", ncol(clip_tbl))) }

Check copied data integrity

for (index in seq_along(col_names)) { col_data <- current_tbl[, col_names[index]]

Get column type of column from the current table using column name

col_type <- class(col_data)
# Check copied data integrity based on the data type expected
if (is.factor(col_data)) {
  # Get all the factor levels of the selected column in the current data frame
  expected_factor_levels <- levels(col_data)
  # Check if all copied data values are contained in the factor levels
  # If any invalid is found, exit function
  for (val in clip_tbl[, index]) {
    if (!is.na(val) && !is.element(val, expected_factor_levels)) {
      stop("Invalid column values. Level not found in factor")
    }
  } # End inner for loop
} else if (!(is.numeric(col_data) || is.logical(col_data) || is.character(col_data))) {
  # clipr support above column types only. So pasting to a column not recognized by clipr may result to unpredictable results 
  # If not in any of the above column types then exit function
  stop(paste("Cannot paste into columns of type:", col_type))
} # End if  

} # End outer for loop

Replace values in the selected columns

for (index in seq_along(col_names)) {

Set the row positions and the values

rows_to_replace <- start_row_pos:(start_row_pos + nrow(clip_tbl) - 1)
new_values <- clip_tbl[, index]

# Replace the old values with new values
for (i in seq_along(new_values)) {
  # Replace each value one by one
  self$replace_value_in_data(col_names = col_names[index], rows = rows_to_replace[i], new_value = new_values[i])
}

# Rename header if the first row of clip data is header
if (first_clip_row_is_header) {
  self$rename_column_in_data(curr_col_name = col_names[index], new_col_name = colnames(clip_tbl)[index]) 
}

} # End for loop }) # End function