2

我有以下可重现的系数图。

library(tidyverse)
tribble(~term, ~estimate, ~lower, ~upper, ~text,
        "a", .25, .2, .3 , "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet orci vel dolor luctus auctor sed non lacus. Cras malesuada, tortor ac mattis rutrum, dui erat aliquam ipsum, id.",
        "b", -.25, -.3, -.2, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet orci vel dolor luctus auctor sed non lacus. Cras malesuada, tortor ac mattis rutrum, dui erat aliquam ipsum, id.",
        "intercept",0, -.1, .1, NA) %>% 
  ggplot(aes(y = term, x = estimate, label = text)) +
  geom_point() +
  ggrepel::geom_text_repel(size = 2, label.size = 0.1) +
  geom_errorbarh(aes(xmin = lower, xmax = upper), height = 0) +
  geom_vline(aes(xintercept = 0), linetype = "dashed") +
  theme_classic()

在此处输入图像描述

我希望标签在点之上并限制在更小的 xlim aka 宽度。有没有办法包装文本或在其中生成某种文本框ggplot2ggrepel使此功能成为可能?

4

2 回答 2

2

这是一个自定义函数,您可以使用它在字符后插入换行符N(最近的空格将被换行符替换):

library(stringr)

wrap_text <- function(string, n) {
  spaces <- str_locate_all(string, " ")[[1]][,1]
  chars  <- nchar(string)
  for(i in 1:floor(chars/n)) {
    s <- spaces[which.min(abs(spaces - n*i))]
    substring(string, s, s) <- "\n "
  }
  return(string)
}

tribble(~term, ~estimate, ~lower, ~upper, ~text,
        "a", .25, .2, .3 , "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet orci vel dolor luctus auctor sed non lacus. Cras malesuada, tortor ac mattis rutrum, dui erat aliquam ipsum, id.",
        "b", -.25, -.3, -.2, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet orci vel dolor luctus auctor sed non lacus. Cras malesuada, tortor ac mattis rutrum, dui erat aliquam ipsum, id.",
        "intercept",0, -.1, .1, NA) %>% 
  ggplot(aes(y = term, x = estimate, label = I(wrap_text(text, nw = 30)))) +
  geom_point() +
  ggrepel::geom_text_repel(size = 2, label.size = 0.1) +
  geom_errorbarh(aes(xmin = lower, xmax = upper), height = 0) +
  geom_vline(aes(xintercept = 0), linetype = "dashed") +
  theme_classic()
于 2018-04-10T15:01:32.177 回答
1

\n您可以使用这个用每个50字符替换空格的虚拟函数。

library(tidyverse)
data <- tribble(~term, ~estimate, ~lower, ~upper, ~text,
        "a", .25, .2, .3 , "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet orci vel dolor luctus auctor sed non lacus. Cras malesuada, tortor ac mattis rutrum, dui erat aliquam ipsum, id.",
        "b", -.25, -.3, -.2, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet orci vel dolor luctus auctor sed non lacus. Cras malesuada, tortor ac mattis rutrum, dui erat aliquam ipsum, id.",
        "intercept",0, -.1, .1, "Lorem impsum")

data$textBreaks <- sapply(strsplit(data$text, " "), function(x) {
    spacePosition <- cumsum(nchar(x))
    placeBreak <- spacePosition[which(diff(spacePosition %/% 50) == 1)] + 1
    result <- paste(x, collapse = " ")
    for(i in placeBreak) {
        substring(result, i, i) <- "\n"
    }
    result
})
ggplot(data, aes(estimate, term,label = textBreaks)) +
    geom_point() +
    ggrepel::geom_text_repel(size = 2) +
    geom_errorbarh(aes(xmin = lower, xmax = upper), height = 0) +
    geom_vline(aes(xintercept = 0), linetype = "dashed") +
    theme_classic()

在此处输入图像描述

PS.:如果只有一个长词(> 50 个字符),它将不起作用。

于 2018-04-10T14:59:37.543 回答