我有以下数据框:
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
),并与month
同时绘制所有变量柱。我想实现三个目标:
r
和{对应的两条线中辨别与r_unanswered
和regression
对对应的两条线{1}}; regression_unanswered
变量与另一对变量。我正在考虑通过在每对中使用相同的颜色,并在每对内部使用unanswered
变量绘制为虚线来实现此目的,但是我愿意接受其他建议,如果您认为它们的话可能在视觉上更具吸引力。无论如何,我的问题是我什至无法实现这个简单的想法。我尝试过
unanswered
但是它不起作用:每对颜色都不相同,因此我无法实现目标1(每对颜色必须易于与其他颜色区分开)。
答案 0 :(得分:3)
我将通过将所有列收集为长格式,然后基于这些列名称创建变量以映射到color
和linetype
来做到这一点。您可以使用tidyr::separate()
完成后一项任务。
我发现您的特殊情况要困难一些,因为某些标记名称包含下划线,而不仅仅是“未答复”之前的标记。因此,我首先用"_unanswered"
替换了".unanswered"
,以便可以在句点而不是下划线上分隔“标记”。这将创建两个新列,一列用于颜色(基于标记名称),一列用于线型(基于已回答或未回答)。回答的问题没有信息说明已回答,因此我在声明中添加了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))
您可以根据需要删除或更改图例。
更复杂的通过split()进行拆分的方法
正如@Henrik指出的那样,您可以通过正则表达式使用预读功能仅对下划线加上“ unanswered”一词进行拆分。这避免了我的解决方法sub()
,并节省了一个步骤。
那部分代码如下:
foobar %>%
gather(tag, count, -month) %>%
separate(tag, into = c("name", "answered"), sep = "_(?=[unanswered])",
remove = FALSE, fill = "right")