R MarkdownでPDFをしたとき、print関数で出力された文字列が横幅を超えてしまう場合があります。
このときの対処法としては、文字の大きさを小さくする方法などがありますが、対応としては限界があります。
そこで、文字列の行を指定した幅で強制的に折り返す関数を作成しましたので、お伝えします。

さっそくですが、強制的に行を折り返す関数を以下に記載します。
内容を簡単にご説明すると、出力する文字列を一時ファイルに内容を保存してから、その一時ファイルを行ごとに読み込んで、その行を指定の幅で分割したうえで、出力しております。

引数の意味は、以下のようになっております。

引数 意味
x print関数に渡す変数、または引数funに渡す変数
fun 関数
width 文字列の幅。文字数でないことにご注意ください
trim 一時ファイルに出力された各行の文頭・文末の空白を削除するかどうか

print_wrap <- function(x,
                       fun = NULL,
                       width = 80,
                       trim = TRUE) {
  filename = tempfile()
  
  sink(filename)
  if (is.null(fun))
    print(x)
  else
    fun(x)
  sink()
  
  con <- file(filename, "r")
  s.lines <- readLines(con)
  close(con)
  file.remove(filename)
  
  c.lines <- c()
  for (l in s.lines) {
    lt <- l
    if (trim) {
      lt <- trimws(lt)
    }
    s <- 1
    w <- 0
    tn <- nchar(lt)
    for (i in 1:tn) {
      n <- nchar(substr(lt, i, i), type = "width")
      if (width < w + n) {
        c.lines <- c(c.lines, substr(lt, s, i - 1))
        s <- i
        w <- 0
      }
      w <- w + n
    }
    if (s < tn)
      c.lines <- c(c.lines, substr(lt, s, tn))
  }
  cat(paste0(c.lines, sep = "", collapse = "\n"))
}

この関数は、R Markdownだけでなくコンソールでも問題なく動作しますので、コンソール上で試した結果を以下に記載します。
文字列を適当に作成して、print関数で表示してみます。


> x <- c(x, paste0(rep("0123456789", 3), sep = "", collapse = ""))
> x <- c(x, paste0(rep("0a1b2c3d4e5f6g7h8i9j", 5), sep = "", collapse = ""))
> print(x)
[1] "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"                                                  
[2] "012345678901234567890123456789"                                                                                          
[3] "0a1b2c3d4e5f6g7h8i9j0a1b2c3d4e5f6g7h8i9j0a1b2c3d4e5f6g7h8i9j0a1b2c3d4e5f6g7h8i9j0a1b2c3d4e5f6g7h8i9j"

次に、強制的に行を折り返す関数を使用してみます。
まずはprint関数で出力した結果を幅10で揃えた結果が次になります。


> print_wrap(x, width = 10)
[1] "01234
5678901234
5678901234
5678901234
5678901234
5678901234
5678901234
5678901234
5678901234
5678901234
56789"
[2] "01
23456
78901
23456
78901
23456
789"
[3] "0a1
b2c3d4e
5f6g7h
8i9j0a
1b2c3d
4e5f6g
7h8i9j
0a1b2c
3d4e5f
6g7h8i
9j0a1b
2c3d4e
5f6g7h
8i9j0a
1b2c3d
4e5f6g
7h8i9j"

今度は、cat関数で出力した結果を幅15で揃えた結果が次になります。


> print_wrap(
+     x,
+     fun = function(x) {
+         cat(paste(x, sep = "", collapse = "\n"))
+         cat("\n")
+     },
+     width = 15
+ )
012345678901234
567890123456789
012345678901234
567890123456789
012345678901234
567890123456789
0123456789
0123456
7890123
4567890
1234567
89
0a1b2c3d4e
5f6g7h8i9j
0a1b2c3d4e
5f6g7h8i9j
0a1b2c3d4e
5f6g7h8i9j
0a1b2c3d4e
5f6g7h8i9j
0a1b2c3d4e
5f6g7h8i9j
R 文字列の行を指定した幅で強制的に折り返す方法