代码之家  ›  专栏  ›  技术社区  ›  DeltaIV

创建可清晰区分的变量对线图

  •  0
  • DeltaIV  · 技术社区  · 6 年前

    我有以下数据框:

    library(dplyr)
    library(tidyr)
    library(ggplot2)
    
    foobar <- structure(list(month = structure(c(1477872000, 1480464000, 1483142400, 
    1485820800, 1488240000, 1490918400, 1493510400, 1496188800, 1498780800, 
    1501459200, 1504137600, 1506729600, 1509408000, 1.512e+09, 1514678400, 
    1517356800, 1519776000, 1522454400, 1525046400, 1527724800, 1530316800
    ), class = c("POSIXct", "POSIXt"), tzone = "UTC"), r = c(283L, 
    298L, 277L, 231L, 276L, 323L, 242L, 255L, 208L, 289L, 284L, 263L, 
    280L, 278L, 269L, 288L, 255L, 324L, 339L, 355L, 300L), r_unanswered = c(133L, 
    139L, 106L, 85L, 132L, 141L, 89L, 110L, 80L, 142L, 174L, 159L, 
    146L, 162L, 153L, 161L, 142L, 174L, 211L, 208L, 194L), regression = c(260L, 
    278L, 249L, 242L, 301L, 349L, 249L, 309L, 256L, 280L, 326L, 276L, 
    299L, 322L, 235L, 281L, 256L, 293L, 356L, 307L, 279L), regression_unanswered = c(102L, 
    119L, 92L, 107L, 119L, 126L, 108L, 132L, 89L, 141L, 199L, 148L, 
    161L, 160L, 125L, 159L, 137L, 139L, 208L, 177L, 162L), machine_learning = c(208L, 
    190L, 176L, 208L, 221L, 265L, 204L, 215L, 251L, 283L, 314L, 257L, 
    250L, 290L, 240L, 290L, 275L, 295L, 292L, 316L, 324L), machine_learning_unanswered = c(64L, 
    67L, 62L, 86L, 78L, 76L, 67L, 67L, 90L, 128L, 155L, 106L, 125L, 
    132L, 125L, 143L, 132L, 159L, 159L, 158L, 191L)), row.names = c(NA, 
    -21L), class = c("tbl_df", "tbl", "data.frame"))
    > glimpse(foobar)
    Observations: 21
    Variables: 7
    $ month                       <dttm> 2016-10-31, 2016-11-30, 2016-12-31, 2...
    $ r                           <int> 283, 298, 277, 231, 276, 323, 242, 255...
    $ r_unanswered                <int> 133, 139, 106, 85, 132, 141, 89, 110, ...
    $ regression                  <int> 260, 278, 249, 242, 301, 349, 249, 309...
    $ regression_unanswered       <int> 102, 119, 92, 107, 119, 126, 108, 132,...
    $ machine_learning            <int> 208, 190, 176, 208, 221, 265, 204, 215...
    $ machine_learning_unanswered <int> 64, 67, 62, 86, 78, 76, 67, 67, 90, 12...
    

    我想把所有非- month 成对变量(例如, r r_unanswered )在同一时间绘制它们 列。我想实现三个目标:

    1. 对必须易于区分,即,必须易于区分对应于对的两条线 未回答 ,从对应于 regression regression_unanswered (二)
    2. 在每一对里面,必须很容易通过眼睛辨别 unanswered 与另一个不同。
    3. 该方法必须扩展到更多对。在这个简单的例子中,我有3对:在我的实际案例中,我可能有10对或更多。

    我想通过对每一对使用相同的颜色,在每一对内部,通过绘制 未答复 变量作为虚线,但我愿意接受其他建议,如果你认为它们更具视觉吸引力的话。不管怎样,我的问题是我甚至不能实现这个简单的想法。我试过了

    tall_unanswered <- foobar %>% select(ends_with("unanswered"), month) %>% 
      gather(key = tag, value = count, -month)
    tall_total <- foobar %>% select(-ends_with("unanswered")) %>% 
      gather(key = tag, value = count, -month)
    p <- ggplot(tall_total, aes(x = month, y = count, color = tag)) +
      geom_line() +
      geom_line(data = tall_unanswered, linetype = "dashed")
    

    但它不起作用:每一对的颜色都不一样,所以我无法达到目标1(每一对必须很容易与其他人区分开来)。

    enter image description here

    1 回复  |  直到 6 年前
        1
  •  3
  •   aosmith    6 年前

    我将通过将所有列收集为长格式,然后基于这些列名创建变量来映射到 color linetype 是的。你可以用 tidyr::separate() 是的。

    我发现你的特殊情况有点困难,因为有些标记名包含下划线,而不是那些直接在“未答复”之前。所以我第一次换了 "_unanswered" 具有 ".unanswered" 所以我可以在句号上分开“tag”而不是下划线。这将生成两个新列,一个用于颜色(基于标记名),一个用于线型(基于已应答vs未应答)。回答的问题没有信息表明它们已被回答,所以我添加了一个 ifelse() 陈述。

    下面是数据操作:

    foolong = foobar %>%
        gather(tag, count, -month) %>%
        mutate(tag = sub("_unanswered", ".unanswered", tag)) %>%
        separate(tag, into = c("name", "answered"), sep = "\\.", 
                 remove = FALSE, fill = "right") %>%
        mutate(answered = ifelse(!is.na(answered), "unanswered", "answered"))
    

    然后,可以通过将颜色和线型映射到新变量来进行打印。

    ggplot(foolong, aes(x = month, y = count, 
                        color = name) +
        geom_line( aes(linetype = answered))
    

    enter image description here

    您可以根据需要删除或更改图例以满足您的目的。

    通过separate()进行拆分的更复杂方法

    正如@henrik所指出的,您可以使用look ahead via regex来分割“unanswered”一词前面的下划线。这避免了我的工作 sub() 并节省了一步。

    代码的那部分看起来像:

    foobar %>%
         gather(tag, count, -month) %>%
         separate(tag, into = c("name", "answered"), sep = "_(?=[unanswered])", 
                  remove = FALSE, fill = "right")