2016-10-26 3 views
2

Я пытаюсь отобразить некоторые данные, где мне нужно не только отображать точку с помощью geom_point, но и проследить за ней линию от оси. Я решил, что могу сделать это с geom_segment, но вместо этого хочу отобразить последовательность дискретных точек.ggplot display geom_segment как последовательность точек

Скажем, у меня есть данные, как это:

df2 <- data_frame(x = c("a", "b", "c" ,"d"), y = c(3:6)) 

# A tibble: 4 × 2 
     x  y 
    <chr> <int> 
1  a  3 
2  b  4 
3  c  5 
4  d  6 

То, что я хочу получить, как на графике ниже, только имея точку в каждом из 4-х переменных между 0 и их значение (с искомых точек, отмеченных вручную красным цветом):

ggplot(df2, aes(x=x)) + geom_point(aes(y=y)) + geom_point(aes(y=0)) 

enter image description here

+0

Вариации на тему: 'библиотека (dplyr); df2%>% group_by (x)%>% do (data.frame (y = 0 :.$ y))%>% mutate (c = y% in% range (y))%>% ggplot (aes (x, y, color = c)) + geom_point (show.legend = FALSE) + scale_colour_manual (значения = c ('red', 'black')) ' – alistaire

+0

или в базе' ggplot (do.call (rbind, lapply (apply (df2, 1, function (r) {data.frame (x = r [1], y = 0: r [2])}), функция (d) {cbind (d, c = d $ y% в% range (d $ y))})), aes (x, y, color = c)) + geom_point (show.legend = FALSE) + scale_colour_manual (значения = c ('red', 'black')) ' – alistaire

ответ

1

Это работает ... вы можете обернуть его в функции, чтобы сделать его более обобщенным, если это необходимо.

Сначала мы используем expand.grid, чтобы создать все комбинации x и 1:(max(y) - 1), присоедините их к исходным данным и отфильтруйте ненужные.

library(dplyr) 
df3 = left_join(expand.grid(x = unique(df2$x), i = 1:max(df2$y - 1)), 
      df2) %>% 
    filter(i < y) 

После того как данные достроено, зарисовки легко:

ggplot(df2, aes(x=x)) + 
    geom_point(aes(y=y)) + 
    geom_point(y = 0) + 
    geom_point(data = df3, aes(y = i), color = "red") + 
    expand_limits(y = 0) 

enter image description here

Я не уверен, если вы на самом деле хотите многоточие быть красным - если вы хотите, чтобы они все выглядят одинаково, тогда вы можете использовать 1:max(df2$y) (опустите -1) и используйте <= в фильтре, а затем используйте только полученный результирующий фрейм данных.

1

Если вы хотите использовать data.table подход, используя аналогичную методологию расширения можно использовать:

dt <- setDT(df2) 
dt_expand<-dt[rep(seq(nrow(dt)),dt$y),] 
dt_expand[,y2:=(1:.N),by=.(x)] 
ggplot(dt_expand, aes(x=x)) + geom_point(aes(y=y2)) + geom_point(aes(y=0)) 

Примечание я не включал красную окраску, но это легко сделать, если вы хотите

enter image description here

1

Здесь решение в базе R. идея заключается в том, чтобы создать 2 различных наборов данных, один для красных точек:

dat1 <- do.call(rbind,Map(function(x,y)data.frame(x=x,y=seq(0,y)),df2$x,df2$y)) 

И еще для черных точек

dat2 <- do.call(rbind,Map(function(x,y)data.frame(x=x,y=c(0,y)),df2$x,df2$y)) 

Тогда сюжет просто juxtopsition из 2-х слоев одного и того же сюжета, но с разными DATAS:

library(ggplot2) 

ggplot(data=dat1,aes(x=x,y=y)) + 
    geom_point(col="red") + 
    geom_point(data=dat2) 

enter image description here

0

Еще один который похож на @ Gregor's, поскольку он создает новый вектор данных.

d <- data.frame(x = c("a", "b", "c" ,"d"), y = c(3:6)) 

new_points <- mapply(seq, 0, d$y) 
new <- data.frame(new = unlist(lapply(new_points, as.data.frame)), 
        x = rep(letters[1:4], d$y + 1), 
        group = 1) 

d <- merge(d, new, by = "x") 
d$group <- as.factor(ifelse(d$y == d$new|d$new == 0, 2, d$group)) 

ggplot(d, aes(x, new, color = group)) + 
    geom_point() + 
    scale_color_manual(values = c("red", "black")) + 
    theme(legend.position = "none") 

enter image description here

Смежные вопросы