Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get length of string in R as it would be `cat()`d (tab handling)

Tags:

r

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.

like image 546
mathematical.coffee Avatar asked Nov 26 '25 20:11

mathematical.coffee


1 Answers

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
like image 169
Josh O'Brien Avatar answered Nov 29 '25 09:11

Josh O'Brien



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!