I have a string, and I want to know the number of columns it would take to print on the terminal. nchar(..., type='w') is supposed to do this (I think), but I am having problems with tabs.
x <- 'foo\tbar'
cat(x)
# foo bar
This cats with 'foo' (3 characters), 1 tab (which in this case is equivalent to 5 spaces), and 'bar' (3 characters), making for 11 "columns" to cat in total.
I would like to know how get this length 11 out. nchar(x) gives 7 ('foo' + 'bar' + the tab character), as expected. In ?nchar it mentions that type='w' gives "The number of columns ‘cat’ will use to print the string in a monospaced font. The same as ‘chars’ if this cannot be calculated. However, this returns 6 (!) not 7, so somehow the \t is 0-width.
nchar(x) # 7
nchar(x, type='w') # 6
How can I get the number of columns cat would need to print x in my fixed-width font terminal? I can't simply replace all \t with (say) 5 spaces, because depending on what column the \t is at, it will be of variable width. Using capture.output(...) captures the tab as a tab (rather than converting to space), so can't use that.
Interesting question.
I think you might just need to brute force this one, with something like the following. (It's based on the observations that: (1) tabs are displayed using at least one space; and (2) each tab-terminated substring is allocated a block of space that is the smallest multiple of 8 characters that's able to accommodate it.)
catLength <- function(x) {
xx <- strsplit(x, "(?<=\\t)", perl=TRUE)[[1]]
ii <- grepl("\\t", xx)
sum(ii * 8*ceiling((nchar(xx) + 1)/8)) + sum(!ii*(nchar(xx)))
}
catLength("\t\t")
# [1] 16
catLength("A")
# [1] 1
catLength("\tA")
# [1] 9
catLength("1234567\tA")
# [1] 9
catLength("12345678\tA")
# [1] 17
catLength("12345678\tAB")
# [1] 18
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With