Chris Ruehlemann
Chris Ruehlemann

Reputation: 21440

Dotchart (in base R) or equivalent in ggplot2 with grouped data

I'm unable to find a way to plot data by group in a dotchart (or any equivalent plot type in ggplot2). The sample data looks like this, with the grouping variable being Turn_no:

df
# A tibble: 8 × 4
# Groups:   Turn_no [4]
  c5    Turn_no Word       RelPosition
  <chr>   <int> <chr>            <dbl>
1 NN1         9 daddy            0.111
2 NN2         9 apartments       0.778
3 NN1        13 job              1    
4 NN1        15 bit              0.167
5 NP0        15 mark             0.667
6 NP0        16 michael          0.222
7 NN1        16 gel              0.778
8 NN1        16 morning          1  

What I want to do is plot RelPosition values grouped by Turn_no so that there are as many dots per line as there are RelPosition values per Turn_no group.

My attempt at combining dplyr syntax with (base R) dotchart fails:

libtary(tidyverse)
df %>%
  group_by(Turn_no) %>%
  dotchart(RelPosition)
Error in dotchart(., RelPosition) : 
  'x' must be a numeric vector or matrix

All I can do is this, which however puts each RelPosition value on its own line irrespective of its group:

dotchart(df$RelPosition)

How can the grouped dot plot be achieved, either in base R or, perhaps better still, in ggplot2 (geom_dotplot doesn't seem to be equivalent to dotchart)?

Data:

df <- structure(list(c5 = c("NN1", "NN2", "NN1", "NN1", "NP0", "NP0", 
                            "NN1", "NN1"), Turn_no = c(9L, 9L, 13L, 15L, 15L, 16L, 16L, 16L
                            ), Word = c("daddy", "apartments", "job", "bit", "mark", "michael", 
                                        "gel", "morning"), RelPosition = c(0.111111111111111, 0.777777777777778, 
                                                                           1, 0.166666666666667, 0.666666666666667, 0.222222222222222, 0.777777777777778, 
                                                                           1)), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, 
                                                                                                                                                      -8L), groups = structure(list(Turn_no = c(9L, 13L, 15L, 16L), 
                                                                                                                                                                                    .rows = structure(list(1:2, 3L, 4:5, 6:8), ptype = integer(0), class = c("vctrs_list_of", 
                                                                                                                                                                                                                                                             "vctrs_vctr", "list"))), row.names = c(NA, -4L), class = c("tbl_df", 
                                                                                                                                                                                                                                                                                                                        "tbl", "data.frame"), .drop = TRUE))

Upvotes: 2

Views: 212

Answers (3)

Quinten
Quinten

Reputation: 41601

Another option using the base R function dotchart with groups like this:

dotchart(df$RelPosition, groups = df$Turn_no, labels = df$Turn_no)

Created on 2023-01-07 with reprex v2.0.2

Upvotes: 2

Allan Cameron
Allan Cameron

Reputation: 174576

A close approximation to the base R version, but grouped according to Turn_no would be:

ggplot(df, aes(RelPosition, factor(Turn_no))) +
  geom_hline(aes(yintercept = factor(Turn_no)), linetype = 3) +
  geom_point(shape = 21, size = 4, fill = "white") +
  theme_classic(base_size = 16) +
  labs(x = "Relative position", y = "Turn Number") +
  theme(panel.border = element_rect(fill = NA, linewidth = 1.5),
        axis.line = element_blank())

enter image description here

Upvotes: 2

danlooo
danlooo

Reputation: 10637

Something like this?

library(ggplot2)

df <- structure(list(c5 = c(
  "NN1", "NN2", "NN1", "NN1", "NP0", "NP0",
  "NN1", "NN1"
), Turn_no = c(9L, 9L, 13L, 15L, 15L, 16L, 16L, 16L), Word = c(
  "daddy", "apartments", "job", "bit", "mark", "michael",
  "gel", "morning"
), RelPosition = c(
  0.111111111111111, 0.777777777777778,
  1, 0.166666666666667, 0.666666666666667, 0.222222222222222, 0.777777777777778,
  1
)), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(
  NA,
  -8L
), groups = structure(list(
  Turn_no = c(9L, 13L, 15L, 16L),
  .rows = structure(list(1:2, 3L, 4:5, 6:8), ptype = integer(0), class = c(
    "vctrs_list_of",
    "vctrs_vctr", "list"
  ))
), row.names = c(NA, -4L), class = c(
  "tbl_df",
  "tbl", "data.frame"
), .drop = TRUE))



df |>
  ggplot(aes(y = Turn_no, x = RelPosition, group = Turn_no)) +
  geom_line() +
  geom_point(size = 4)

Created on 2023-01-07 by the reprex package (v2.0.1)

Upvotes: 2

Related Questions