Dear R developers,

It would be great if you could implement the two minor code changes suggested 
below, which would help processing large objects in R.


Jens Oehlschlägel


# Wish no. 1: let [.AsIs return the class AFTER subsetting, not the class of 
the original object
# Wish no. 2: adjust write.csv and write.csv2 for multiple calls in chunked 
writing

# Rationale no. 1: a couple of packages will return a different class than 
SomeClass when subsetting with [.SomeClass 
# and still need to keep the AsIs property
# Examples for classes returning different classes on subscipting are in 
packages 'bit', 'ff', 'bigmemory'
# For classes where [.SomeClass will return class SomeClass, such a change will 
not hurt

# Code suggestion no. 1: please use 
"[.AsIs" <- function (x, i, ...){
      ret <- NextMethod("[")
      oldClass(ret) <- c("AsIs", oldClass(ret))
      ret
}
# instead of
"[.AsIs" <- function (x, i, ...)
structure(NextMethod("["), class = class(x))


# Rationale no. 2: write.csv and write.csv2 currently enforce that a header 
must be written, even with append=TRUE
# This prevents a csv file being written in chunks.
# If argument append=TRUE is used, a header should not be enforced (may be even 
be forbidden)

# Code suggestion no. 2: please use
write.csv <-
function (...)
{
    Call <- match.call(write.table, expand.dots = TRUE)
    for (argname in c("col.names", "sep", "dec", "qmethod")) if 
(!is.null(Call[[argname]]))
        warning(gettextf("attempt to set '%s' ignored", argname),
            domain = NA)
    rn <- eval.parent(Call$row.names)
    ap <- eval.parent(Call$append)
    Call$col.names <- if (is.logical(ap) && ap) FALSE else {if (is.logical(rn) 
&& !rn) TRUE else NA}
    Call$sep <- ","
    Call$dec <- "."
    Call$qmethod <- "double"
    Call[[1L]] <- as.name("write.table")
    eval.parent(Call)
}
write.csv2 <-
function (...)
{
    Call <- match.call(write.table, expand.dots = TRUE)
    for (argname in c("col.names", "sep", "dec", "qmethod")) if 
(!is.null(Call[[argname]]))
        warning(gettextf("attempt to set '%s' ignored", argname),
            domain = NA)
    rn <- eval.parent(Call$row.names)
    ap <- eval.parent(Call$append)
    Call$col.names <- if (is.logical(ap) && ap) FALSE else {if (is.logical(rn) 
&& !rn) TRUE else NA}
    Call$sep <- ";"
    Call$dec <- ","
    Call$qmethod <- "double"
    Call[[1L]] <- as.name("write.table")
    eval.parent(Call)
}
# instead of
write.csv <- function (...) 
{
    Call <- match.call(expand.dots = TRUE)
    for (argname in c("col.names", "sep", "dec", "qmethod")) if 
(!is.null(Call[[argname]])) 
        warning(gettextf("attempt to set '%s' ignored", argname), 
            domain = NA)
    rn <- eval.parent(Call$row.names)
    Call$col.names <- if (is.logical(rn) && !rn) 
        TRUE
    else NA
    Call$sep <- ","
    Call$dec <- "."
    Call$qmethod <- "double"
    Call[[1L]] <- as.name("write.table")
    eval.parent(Call)
}
write.csv2 <- 
function (...) 
{
    Call <- match.call(expand.dots = TRUE)
    for (argname in c("col.names", "sep", "dec", "qmethod")) if 
(!is.null(Call[[argname]])) 
        warning(gettextf("attempt to set '%s' ignored", argname), 
            domain = NA)
    rn <- eval.parent(Call$row.names)
    Call$col.names <- if (is.logical(rn) && !rn) 
        TRUE
    else NA
    Call$sep <- ";"
    Call$dec <- ","
    Call$qmethod <- "double"
    Call[[1L]] <- as.name("write.table")
    eval.parent(Call)
}

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to