Re: [R] [R Code] Split long names in format.ftable
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
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
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.