diff --git a/DESCRIPTION b/DESCRIPTION index e7b40ce..5446e97 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,15 +1,16 @@ Package: DataEditR -Title: Interactive Data Viewing, Entry and Editing -Version: 0.0.1 -Date: 2020-07-21 +Title: An Interactive Editor for Viewing, Entering & Editing Data +Version: 0.0.2 +Date: 2020-07-30 Authors@R: person(given = "Dillon", family = "Hammill", role = c("aut", "cre"), email = "Dillon.Hammill@anu.edu.au", comment = c(ORCID = "0000-0002-1407-7223")) -Description: Provides an interactive interface to view, enter or edit data - or tabular data files in R. +Description: An interactive editor built on rhandsontable to allow the + interactive viewing, entering and editing of data in R. + . URL: https://github.com/DillonHammill/DataEditR BugReports: https://github.com/DillonHammill/DataEditR/issues Depends: diff --git a/R/data_edit.R b/R/data_edit.R index 6e906fa..3a21244 100644 --- a/R/data_edit.R +++ b/R/data_edit.R @@ -21,15 +21,21 @@ # may be possible to handle this externally but this gets complicated when # columns are added or removed. -#' Interactively edit data.frames, matrices or tabular data files +#' An interactive editor for viewing, entering & editing data +#' +#' \code{data_edit} is a shiny application built on \code{rhandsontable} that is +#' designed to make it easy to interactively view, enter or edit data without +#' any coding. \code{data_edit} is also a wrapper for any reading or writing +#' function to make it easy to interactively update data saved to file. #' #' @param x a matrix, data.frame, data.table or the name of a csv file to #' edit.Tibble are also supported but will be coerced to data.frames. An empty #' table can be created by specifying the dimensions in a vector of the form #' \code{c(nrow, ncol)}. #' @param col_bind additional columns to add to the data prior to loading into -#' editor, can be either an array containing the new data or a vector -#' containing the new column names for empty columns. +#' editor, can be either an array containing the new data, a vector containing +#' the new column names for empty columns or a named list containing a vector +#' for each new column. #' @param col_edit logical indicating whether columns can be added or removed, #' set to TRUE by default. #' @param col_options named list containing the options for columns that use @@ -39,9 +45,12 @@ #' @param col_factor logical indicating whether character columns should be #' converted to factors prior to returning the edited data, set to FALSE by #' default. +#' @param col_names logical indicating whether column names can be edited, set +#' to TRUE by default. #' @param row_bind additional rows to add to the data prior to loading into -#' editor, can be either an array containing the new data or a vector -#' containing the new row names for empty rows. +#' editor, can be either an array containing the new data, a vector containing +#' the new row names for empty rows or a named list containing a vector for +#' each new column. #' @param row_edit logical indicating whether rows can be added or removed, set #' to TRUE by default. #' @param save_as name of a csv file to which the edited data should be saved. @@ -84,16 +93,15 @@ #' @author Dillon Hammill, \email{Dillon.Hammill@anu.edu.au} #' #' @examples -#' \dontrun{ -#' # Edit data.frame save to csv -#' data_edit(mtcars, -#' save_as = "mtcars-update.csv" -#' ) +#' if (interactive()) { +#' # Edit matrix & save to csv +#' data_edit(mtcars, +#' save_as = "mtcars-update.csv" +#' ) #' -#' # Edit csv file -#' data_edit("mtcars-update.csv") +#' # Edit csv file +#' data_edit("mtcars-update.csv") #' } -#' #' @export data_edit <- function(x, col_bind = NULL, @@ -101,6 +109,7 @@ data_edit <- function(x, col_options = NULL, col_stretch = FALSE, col_factor = FALSE, + col_names = TRUE, row_bind = NULL, row_edit = TRUE, save_as = NULL, @@ -119,10 +128,10 @@ data_edit <- function(x, # PREPARE DATA --------------------------------------------------------------- # EMPTY DATA - if(missing(x)) { + if (missing(x)) { x <- data.frame("V1" = "") } - + # READ IN DATA if (is.null(dim(x))) { # READ IN FILE @@ -139,8 +148,10 @@ data_edit <- function(x, read_args <- c(list(x), read_args) # EXTRA ARGUMENTS extra_args <- list(...) - read_args <- c(read_args, - extra_args[!names(extra_args) %in% names(read_args)]) + read_args <- c( + read_args, + extra_args[!names(extra_args) %in% names(read_args)] + ) # CALL FUNCTION x <- do.call(read_fun, read_args) # EMPTY MATRIX/DATA.FRAME @@ -155,36 +166,67 @@ data_edit <- function(x, # BIND ROWS if (!is.null(row_bind)) { - # NEW EMPTY ROWS + # NEW ROWS if (is.null(dim(row_bind))) { - x <- rbind(x, matrix(rep("", ncol(x) * length(row_bind)), - nrow = length(row_bind), - dimnames = list( - row_bind, - colnames(x) + # ROWS AS LIST + if (class(row_bind) == "list") { + # NAMES NOT NECESSARY + # LENGTHS + ind <- which(!unlist(lapply(row_bind, length)) == ncol(x)) + if (length(ind) > 0) { + for (z in ind) { + row_bind[[z]] <- rep(row_bind[[z]], ncol(x)) + } + } + # MATRIX + row_bind <- do.call("rbind", row_bind) + # ROW NAMES + } else { + row_bind <- matrix(rep("", ncol(x) * length(row_bind)), + nrow = length(row_bind), + dimnames = list( + row_bind, + colnames(x) + ) ) - )) - # NEW ROWS - } else { - x <- rbind(x, row_bind[, seq_len(ncol(x))]) + } } + # BIND NEW ROWS + x <- rbind(x, row_bind[, 1:ncol(x)]) } # BIND COLUMNS if (!is.null(col_bind)) { - # NEW EMPTY COLUMNS + # NEW COLUMNS if (is.null(dim(col_bind))) { - x <- cbind(x, matrix(rep("", nrow(x) * length(col_bind)), - ncol = length(col_bind), - dimnames = list( - rownames(x), - col_bind + # COLUMNS AS LIST + if (class(col_bind) == "list") { + # NAMES + if (is.null(names(col_bind))) { + names(col_bind) <- paste0("V", length(col_bind)) + } + # LENGTHS + ind <- which(!unlist(lapply(col_bind, length)) == nrow(x)) + if (length(ind) > 0) { + for (z in ind) { + col_bind[[z]] <- rep(col_bind[[z]], nrow(x)) + } + } + # MATRIX + col_bind <- do.call("cbind", col_bind) + # COLUMN NAMES + } else { + col_bind <- matrix(rep("", nrow(x) * length(col_bind)), + ncol = length(col_bind), + dimnames = list( + rownames(x), + col_bind + ) ) - )) - # NEW COLUMNS - } else { - x <- cbind(x, col_bind[seq_len(nrow(x)), , drop = FALSE]) + } } + # BIND NEW COLUMNS + x <- cbind(x, col_bind[1:nrow(x), , drop = FALSE]) } # COLUMN NAMES @@ -192,29 +234,29 @@ data_edit <- function(x, stop("Column names must be unique!") } - # COLUMN OPTIONS - LOGICAL - if(!is.null(col_options)){ - lapply(names(col_options), function(z){ + # COLUMN OPTIONS - LOGICAL + if (!is.null(col_options)) { + for (z in names(col_options)) { col_type <- type.convert(col_options[[z]], as.is = TRUE) # CHECKBOXES - if(is.logical(col_type)){ - if(!is.logical(x[, z])){ + if (is.logical(col_type)) { + if (!is.logical(x[, z])) { res <- type.convert(x[, z], as.is = TRUE) - if(!is.logical(res)){ + if (!is.logical(res)) { res <- rep(NA, nrow(x)) } - x[, z] <<- res + x[, z] <- res } - # DROPDOWN MENUS - }else{ + # DROPDOWN MENUS + } else { # NA TO EMPTY CHARACTERS - if(all(is.na(x[, z]))){ - x[, z] <<- rep("", nrow(x)) + if (all(is.na(x[, z]))) { + x[, z] <- rep("", nrow(x)) } } - }) + } } - + # CLASS data_class <- class(x) @@ -318,14 +360,14 @@ data_edit <- function(x, # COLUMN INDEX - COLUMNS CANNOT BE MOVED col_ind <- which(old_col_names != new_col_names) # CUSTOM COLUMNS - KEEP COLUMN TYPE - if(!is.null(names(col_options))){ - if(any(old_col_names[col_ind] %in% names(col_options))){ - lapply(col_ind, function(z){ - if(old_col_names[z] %in% names(col_options)){ + if (!is.null(names(col_options))) { + if (any(old_col_names[col_ind] %in% names(col_options))) { + for (z in col_ind) { + if (old_col_names[z] %in% names(col_options)) { ind <- match(old_col_names[z], names(col_options)) - names(col_options)[ind] <<- new_col_names[z] + names(col_options)[ind] <- new_col_names[z] } - }) + } } } # EMPTY COLUMN NAMES @@ -335,11 +377,14 @@ data_edit <- function(x, colnames(x_new) <- new_col_names values[["x"]] <- x_new # REVERT EMPTY COLUMN NAMES TO ORIGINAL - RE-RENDER - if(length(empty_col_names) > 0){ + if (length(empty_col_names) > 0) { colnames(x_new)[empty_col_names] <- old_col_names[empty_col_names] values[["x"]] <- x_new - # REVERT COLUMN NAME EDITS - }else if(col_names == FALSE){ + # REVERT COLUMN NAME EDITS + } else if (col_names == FALSE) { + if (quiet == FALSE) { + message("Column names cannot be edited.") + } colnames(x_new) <- old_col_names values[["x"]] <- x_new } @@ -502,7 +547,7 @@ data_edit <- function(x, if ("matrix" %in% data_class) { x <- as.matrix(x) } - + # ROW NAMES - FIRST COLUMN if (rn == "set") { new_row_names <- x[, 1] @@ -518,12 +563,12 @@ data_edit <- function(x, } else if (rn == "empty") { rownames(x) <- NULL } - + # ATTEMPT TO FIX CLASSES - EMPTY DATA - lapply(colnames(x), function(z){ - x[, z] <<- type.convert(x[,z], as.is = !col_factor) - }) - + for (z in colnames(x)) { + x[, z] <- type.convert(x[, z], as.is = !col_factor) + } + # SAVE EDITIED DATA if (!is.null(save_as)) { # FUNCTION @@ -538,12 +583,14 @@ data_edit <- function(x, write_args <- c(list(x, save_as), write_args) # EXTRA ARGUMENTS extra_args <- list(...) - write_args <- c(write_args, - extra_args[!names(extra_args) %in% names(write_args)]) + write_args <- c( + write_args, + extra_args[!names(extra_args) %in% names(write_args)] + ) # CALL FUNCTION do.call(write_fun, write_args) } - + # RETURN EDITIED DATA return(x) } diff --git a/README.md b/README.md index 0fa0562..22b5185 100644 --- a/README.md +++ b/README.md @@ -102,17 +102,17 @@ citation("DataEditR") #> #> To cite package 'DataEditR' in publications use: #> -#> Dillon Hammill (2020). DataEditR: Interactive Editor for Tabular -#> Data. R package version 0.0.1. +#> Dillon Hammill (2020). DataEditR: An Interactive Editor for Viewing, +#> Entering & Editing Data. R package version 0.0.2. #> https://github.com/DillonHammill/DataEditR #> #> A BibTeX entry for LaTeX users is #> #> @Manual{, -#> title = {DataEditR: Interactive Editor for Tabular Data}, +#> title = {DataEditR: An Interactive Editor for Viewing, Entering & Editing Data}, #> author = {Dillon Hammill}, #> year = {2020}, -#> note = {R package version 0.0.1}, +#> note = {R package version 0.0.2}, #> url = {https://github.com/DillonHammill/DataEditR}, #> } ``` diff --git a/docs/404.html b/docs/404.html index 0d8433f..bc73b8f 100644 --- a/docs/404.html +++ b/docs/404.html @@ -79,7 +79,7 @@ DataEditR - 0.0.1 + 0.0.2 diff --git a/docs/CODE_OF_CONDUCT.html b/docs/CODE_OF_CONDUCT.html index 2285de9..44e18af 100644 --- a/docs/CODE_OF_CONDUCT.html +++ b/docs/CODE_OF_CONDUCT.html @@ -79,7 +79,7 @@ DataEditR - 0.0.1 + 0.0.2 diff --git a/docs/articles/DataEditR.html b/docs/articles/DataEditR.html index 87605b5..3134ad4 100644 --- a/docs/articles/DataEditR.html +++ b/docs/articles/DataEditR.html @@ -38,7 +38,7 @@ DataEditR - 0.0.1 + 0.0.2 diff --git a/docs/articles/index.html b/docs/articles/index.html index 31e482a..82e3029 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -79,7 +79,7 @@ DataEditR - 0.0.1 + 0.0.2 diff --git a/docs/authors.html b/docs/authors.html index c7ce107..b1345e7 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -79,7 +79,7 @@ DataEditR - 0.0.1 + 0.0.2 diff --git a/docs/index.html b/docs/index.html index 6865da1..c807c84 100644 --- a/docs/index.html +++ b/docs/index.html @@ -5,7 +5,7 @@ -Interactive Data Viewing, Entry and Editing • DataEditR +An Interactive Editor for Viewing, Entering & Editing Data • DataEditR @@ -17,9 +17,10 @@ - - + + @@ -46,8 +46,11 @@ - - + + @@ -80,7 +83,7 @@ DataEditR - 0.0.1 + 0.0.2 @@ -122,13 +125,16 @@
-

Interactively edit data.frames, matrices or tabular data files

+

data_edit is a shiny application built on rhandsontable that is +designed to make it easy to interactively view, enter or edit data without +any coding. data_edit is also a wrapper for any reading or writing +function to make it easy to interactively update data saved to file.

data_edit(
@@ -138,6 +144,7 @@ 

Interactively edit data.frames, matrices or tabular data files

col_options = NULL, col_stretch = FALSE, col_factor = FALSE, + col_names = TRUE, row_bind = NULL, row_edit = TRUE, save_as = NULL, @@ -167,8 +174,9 @@

Arg col_bind

additional columns to add to the data prior to loading into -editor, can be either an array containing the new data or a vector -containing the new column names for empty columns.

+editor, can be either an array containing the new data, a vector containing +the new column names for empty columns or a named list containing a vector +for each new column.

col_edit @@ -190,12 +198,18 @@

Arg

logical indicating whether character columns should be converted to factors prior to returning the edited data, set to FALSE by default.

+ + + col_names +

logical indicating whether column names can be edited, set +to TRUE by default.

row_bind

additional rows to add to the data prior to loading into -editor, can be either an array containing the new data or a vector -containing the new row names for empty rows.

+editor, can be either an array containing the new data, a vector containing +the new row names for empty rows or a named list containing a vector for +each new column.

row_edit @@ -271,14 +285,14 @@

Value

edited matrix-like object.

Examples

-
if (FALSE) { -# Edit data.frame save to csv -data_edit(mtcars, - save_as = "mtcars-update.csv" -) - -# Edit csv file -data_edit("mtcars-update.csv") +
if (interactive()) { + # Edit matrix & save to csv + data_edit(mtcars, + save_as = "mtcars-update.csv" + ) + + # Edit csv file + data_edit("mtcars-update.csv") }
@@ -149,7 +149,7 @@

data_edit()

-

Interactively edit data.frames, matrices or tabular data files

+

An interactive editor for viewing, entering & editing data

diff --git a/man/data_edit.Rd b/man/data_edit.Rd index f51991d..2b334cf 100644 --- a/man/data_edit.Rd +++ b/man/data_edit.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/data_edit.R \name{data_edit} \alias{data_edit} -\title{Interactively edit data.frames, matrices or tabular data files} +\title{An interactive editor for viewing, entering & editing data} \usage{ data_edit( x, @@ -11,6 +11,7 @@ data_edit( col_options = NULL, col_stretch = FALSE, col_factor = FALSE, + col_names = TRUE, row_bind = NULL, row_edit = TRUE, save_as = NULL, @@ -34,8 +35,9 @@ table can be created by specifying the dimensions in a vector of the form \code{c(nrow, ncol)}.} \item{col_bind}{additional columns to add to the data prior to loading into -editor, can be either an array containing the new data or a vector -containing the new column names for empty columns.} +editor, can be either an array containing the new data, a vector containing +the new column names for empty columns or a named list containing a vector +for each new column.} \item{col_edit}{logical indicating whether columns can be added or removed, set to TRUE by default.} @@ -50,9 +52,13 @@ fill the full width of the display, set to FALSE by default.} converted to factors prior to returning the edited data, set to FALSE by default.} +\item{col_names}{logical indicating whether column names can be edited, set +to TRUE by default.} + \item{row_bind}{additional rows to add to the data prior to loading into -editor, can be either an array containing the new data or a vector -containing the new row names for empty rows.} +editor, can be either an array containing the new data, a vector containing +the new row names for empty rows or a named list containing a vector for +each new column.} \item{row_edit}{logical indicating whether rows can be added or removed, set to TRUE by default.} @@ -99,19 +105,21 @@ example, this becomes particularly important when specifying edited matrix-like object. } \description{ -Interactively edit data.frames, matrices or tabular data files +\code{data_edit} is a shiny application built on \code{rhandsontable} that is +designed to make it easy to interactively view, enter or edit data without +any coding. \code{data_edit} is also a wrapper for any reading or writing +function to make it easy to interactively update data saved to file. } \examples{ -\dontrun{ -# Edit data.frame save to csv -data_edit(mtcars, - save_as = "mtcars-update.csv" -) - -# Edit csv file -data_edit("mtcars-update.csv") +if (interactive()) { + # Edit matrix & save to csv + data_edit(mtcars, + save_as = "mtcars-update.csv" + ) + + # Edit csv file + data_edit("mtcars-update.csv") } - } \author{ Dillon Hammill, \email{Dillon.Hammill@anu.edu.au}