Karolis Koncevičius
Karolis Koncevičius

Reputation: 9656

R: Wrap a long text so that each line has the same length

I am trying to add a long text to a plot. The goal is to wrap the text so that each line is equal in length. I looked through several functions: strwrap, format, text. But none of these seem to have an option for making the lines equal.

I imagine the solution should adding spaces between words in shorter lines to make up for missing characters. Maybe there is a function/argument that I missed?

Below is my current wrapping (without equal lengths):

txt <- paste(sample(LETTERS, 1000, replace=TRUE), collapse="")
txt <- strsplit(txt, "A|I|O|E|U")
txt <- paste(txt[[1]], collapse=" ")

plot(NA, xlim=c(0,1), ylim=c(0,1))
text(0.0, 0.5, paste(strwrap(txt, width=50), collapse="\n"), pos=4, cex=0.7)

textplot

Upvotes: 0

Views: 1712

Answers (1)

Karolis Koncevičius
Karolis Koncevičius

Reputation: 9656

Here is a one hack to achieve it.

1) Define a function that expands a string to desired length by adding spaces between words.

expandWidth <- function(str, width) {
  nmiss <- max(0, width-nchar(str))
  words <- unlist(strsplit(str, " "))
  ngaps <- length(words)-1
  addToAll   <- nmiss %/% ngaps
  addToStart <- nmiss %% ngaps
  nSpaces    <- rep(addToAll, ngaps)
  nSpaces[0:addToStart] <- nSpaces[0:addToStart] + 1
  spaces <- sapply(Map(rep, " ", nSpaces+1), paste, collapse="")
  paste(apply(rbind(c("", spaces), words), 2, paste, collapse=""), collapse="")
}

2) Deal with text.

txt <- paste(sample(LETTERS, 1000, replace=TRUE), collapse="")
txt <- strsplit(txt, "A|I|O|E|U")
txt <- paste(txt[[1]], collapse=" ")

# Add spaces
txt <- sapply(strwrap(txt, width=50), expandWidth, 50)

3) Use font with equal character sizes ( as noted by @rawr )

plot(NA, xlim=c(0,1), ylim=c(0,1))
text(0.0, 0.5, paste(txt, collapse="\n"), pos=4, cex=0.7, family="mono")

Result:

resultPic

Upvotes: 2

Related Questions