Re: [R] [R Code] Split long names in format.ftable

2021-09-17 Thread Leonard Mada via R-help

Dear List members,


I have uploaded an improved version on Github. The function is now fully 
functional:

- justify: left, right, cent...: TODO centre vs center;
- sep: separator when printing;
- pos: Top, Bottom; TODO: Middle;

see:
https://github.com/discoleo/R/blob/master/Stat/Tools.Data.

I will address some open questions in a separate post.


### Test
# Required:
# - all functions from Github / section "Formatting":
#   from space.builder() to ftable2();


### Data
mtcars$carbCtg = cut(mtcars$carb, c(1, 2, 4, 8), right=FALSE)
tbl = with(mtcars, table(cyl, hp, carbCtg, gear))
id = c(1,3,4);
xnm = c("Long\nname: ", "", "Extremely\nlong\nname: ")
xnm = paste0(xnm, names(dimnames(tbl))[id]);
names(dimnames(tbl))[id] = xnm;
ftbl = ftable(tbl, row.vars = id);

### FTABLE
ftable2(ftbl, sep="|"); # works nicely
ftable2(ftbl, sep=" ")
ftable2(ftbl, sep=" | ")
ftable2(ftbl, sep=" | ", justify="left")
ftable2(ftbl, sep=" | ", justify="cent") # TODO: center vs centre
ftable2(ftbl, sep=" | ", justify="left", justify.lvl="c")


Sincerely,


Leonard


On 9/15/2021 11:14 PM, Leonard Mada wrote:

Dear List members,


I have uploaded an improved version on Github:
- new option: align top vs bottom;

Functions:
split.names: splits and aligns the names;
merge.align: aligns 2 string matrices;
ftable2: enhanced version of format.ftable (proof of concept);
see:
https://github.com/discoleo/R/blob/master/Stat/Tools.Data.R


It makes sense to have such functionality in base R as well: it may be 
useful in various locations to format character output.



Sincerely,


Leonard


On 9/14/2021 8:18 PM, Leonard Mada wrote:

Dear List members,


I wrote some code to split long names in format.ftable. I hope it 
will be useful to others as well.



Ideally, this code should be implemented natively in R. I will 
provide in the 2nd part of the mail a concept how to actually 
implement the code in R. This may be interesting to R-devel as well.


[...]


C.) split.names Function

This function may be useful in other locations as well, particularly 
to split names/labels used in axes and legends in various plots. But 
I do not have much knowledge of the graphics engine in R.



Sincerely,


Leonard




__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


Re: [R] [R Code] Split long names in format.ftable

2021-09-15 Thread Leonard Mada via R-help

Dear List members,


I have uploaded an improved version on Github:
- new option: align top vs bottom;

Functions:
split.names: splits and aligns the names;
merge.align: aligns 2 string matrices;
ftable2: enhanced version of format.ftable (proof of concept);
see:
https://github.com/discoleo/R/blob/master/Stat/Tools.Data.R


It makes sense to have such functionality in base R as well: it may be 
useful in various locations to format character output.



Sincerely,


Leonard


On 9/14/2021 8:18 PM, Leonard Mada wrote:

Dear List members,


I wrote some code to split long names in format.ftable. I hope it will 
be useful to others as well.



Ideally, this code should be implemented natively in R. I will provide 
in the 2nd part of the mail a concept how to actually implement the 
code in R. This may be interesting to R-devel as well.



### Helper function

# Split the actual names

split.names = function(names, extend=0, justify="Right", 
blank.rm=FALSE, split.ch = "\n", detailed=TRUE) {
    justify = if(is.null(justify)) 0 else pmatch(justify, c("Left", 
"Right"));

    str = strsplit(names, split.ch);
    if(blank.rm) str = lapply(str, function(s) s[nchar(s) > 0]);
    nr  = max(sapply(str, function(s) length(s)));
    nch = lapply(str, function(s) max(nchar(s)));
    chf = function(nch) paste0(rep(" ", nch), collapse="");
    ch0 = sapply(nch, chf);
    mx  = matrix(rep(ch0, each=nr), nrow=nr, ncol=length(names));
    for(nc in seq(length(names))) {
        n = length(str[[nc]]);
        # Justifying
        s = sapply(seq(n), function(nr) paste0(rep(" ", nch[[nc]] - 
nchar(str[[nc]][nr])), collapse=""));
        s = if(justify == 2) paste0(s, str[[nc]]) else 
paste0(str[[nc]], s);

        mx[seq(nr + 1 - length(str[[nc]]), nr) , nc] = s;
    }
    if(extend > 0) {
        mx = cbind(mx, matrix("", nr=nr, ncol=extend));
    }
    if(detailed) attr(mx, "nchar") = unlist(nch);
    return(mx);
}

### ftable with name splitting
# - this code should be ideally integrated inside format.ftable;
ftable2 = function(ftbl, print=TRUE, quote=FALSE, ...) {
    ftbl2 = format(ftbl, quote=quote, ...);
    row.vars = names(attr(ftbl, "row.vars"))
    nr = length(row.vars);
    nms = split.names(row.vars, extend = ncol(ftbl2) - nr);
    ftbl2 = rbind(ftbl2[1,], nms, ftbl2[-c(1,2),]);
    # TODO: update width of factor labels;
    # - new width available in attr(nms, "nchar");
    if(print) {
        cat(t(ftbl2), sep = c(rep(" ", ncol(ftbl2) - 1), "\n"))
    }
    invisible(ftbl2);
}

I have uploaded this code also on Github:

https://github.com/discoleo/R/blob/master/Stat/Tools.Data.R


B.) Detailed Concept
# - I am ignoring any variants;
# - the splitting is actually done in format.ftable;
# - we set only an attribute in ftable;
ftable = function(..., split.ch="\n") {
   [...]
   attr(ftbl, "split.ch") = split.ch; # set an attribute "split.ch"
   return(ftbl);
}

format.ftable(ftbl, ..., split.ch) {
if(is.missing(split.ch)) {
   # check if the split.ch attribute is set and use it;
} else {
   # use the explicitly provided split.ch: if( ! is.null(split.ch))
}
   [...]
}


C.) split.names Function

This function may be useful in other locations as well, particularly 
to split names/labels used in axes and legends in various plots. But I 
do not have much knowledge of the graphics engine in R.



Sincerely,


Leonard




__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


[R] [R Code] Split long names in format.ftable

2021-09-14 Thread Leonard Mada via R-help

Dear List members,


I wrote some code to split long names in format.ftable. I hope it will 
be useful to others as well.



Ideally, this code should be implemented natively in R. I will provide 
in the 2nd part of the mail a concept how to actually implement the code 
in R. This may be interesting to R-devel as well.



### Helper function

# Split the actual names

split.names = function(names, extend=0, justify="Right", blank.rm=FALSE, 
split.ch = "\n", detailed=TRUE) {
    justify = if(is.null(justify)) 0 else pmatch(justify, c("Left", 
"Right"));

    str = strsplit(names, split.ch);
    if(blank.rm) str = lapply(str, function(s) s[nchar(s) > 0]);
    nr  = max(sapply(str, function(s) length(s)));
    nch = lapply(str, function(s) max(nchar(s)));
    chf = function(nch) paste0(rep(" ", nch), collapse="");
    ch0 = sapply(nch, chf);
    mx  = matrix(rep(ch0, each=nr), nrow=nr, ncol=length(names));
    for(nc in seq(length(names))) {
        n = length(str[[nc]]);
        # Justifying
        s = sapply(seq(n), function(nr) paste0(rep(" ", nch[[nc]] - 
nchar(str[[nc]][nr])), collapse=""));
        s = if(justify == 2) paste0(s, str[[nc]]) else 
paste0(str[[nc]], s);

        mx[seq(nr + 1 - length(str[[nc]]), nr) , nc] = s;
    }
    if(extend > 0) {
        mx = cbind(mx, matrix("", nr=nr, ncol=extend));
    }
    if(detailed) attr(mx, "nchar") = unlist(nch);
    return(mx);
}

### ftable with name splitting
# - this code should be ideally integrated inside format.ftable;
ftable2 = function(ftbl, print=TRUE, quote=FALSE, ...) {
    ftbl2 = format(ftbl, quote=quote, ...);
    row.vars = names(attr(ftbl, "row.vars"))
    nr = length(row.vars);
    nms = split.names(row.vars, extend = ncol(ftbl2) - nr);
    ftbl2 = rbind(ftbl2[1,], nms, ftbl2[-c(1,2),]);
    # TODO: update width of factor labels;
    # - new width available in attr(nms, "nchar");
    if(print) {
        cat(t(ftbl2), sep = c(rep(" ", ncol(ftbl2) - 1), "\n"))
    }
    invisible(ftbl2);
}

I have uploaded this code also on Github:

https://github.com/discoleo/R/blob/master/Stat/Tools.Data.R


B.) Detailed Concept
# - I am ignoring any variants;
# - the splitting is actually done in format.ftable;
# - we set only an attribute in ftable;
ftable = function(..., split.ch="\n") {
   [...]
   attr(ftbl, "split.ch") = split.ch; # set an attribute "split.ch"
   return(ftbl);
}

format.ftable(ftbl, ..., split.ch) {
if(is.missing(split.ch)) {
   # check if the split.ch attribute is set and use it;
} else {
   # use the explicitly provided split.ch: if( ! is.null(split.ch))
}
   [...]
}


C.) split.names Function

This function may be useful in other locations as well, particularly to 
split names/labels used in axes and legends in various plots. But I do 
not have much knowledge of the graphics engine in R.



Sincerely,


Leonard

__
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.