Как соединить сгруппированные точки в ggplot внутри групп?

У меня есть набор данных с двумя группами - Experimental и Control. Каждый участник вносит два ответа на группу, которые представляют разные стили обучения. Они представлены на диаграммах с дрожанием ниже. Я хотел бы соединить два ответа каждого участника линиями, используя ggplot (чтобы каждая красная линия в контрольной группе соответствовала каждой бирюзовой строке в контрольной группе), однако я не могу понять, как это сделать в условиях. Может кто-нибудь помочь? Я новичок в R и мне действительно нужно руководство.

Затем мне нужно изменить цвет линий в условиях на черный, если увеличение = ИСТИНА, и на красный, если увеличение = ЛОЖЬ.

В идеале мне нужно, чтобы это выглядело как пример Джона здесь, но с черными или красными линиями в зависимости от True или False: Соединение сгруппированных точек линиями в ggplot

Данные и ggplot выглядят так:

d <- data.frame (
  Subject = c("1", "2", "3", "4"),
  Group  = c("Exp", "Exp", "Control", "Control"),
  Tr = c("14", "11", "4", "23"),
  Sr = c("56", "78", "12", "10"),
  Increase = c("TRUE", "TRUE", "TRUE", "FALSE")
)

# put the data in long format
d <- d %>%
  gather(key = "Strategy", value = "raw", Tr, Sr)

d %>%
  ggplot(aes(x = Group, y = raw, color = Strategy)) +
  geom_boxplot(width = 0.5, lwd = 0.5) +
  geom_jitter(width = 0.15) +
  geom_line(aes(group = raw),
            color = "grey",
            arrow = arrow(type = "closed",
                          length = unit(0.075, "inches"))) 

Пожалуйста, поделитесь образцами данных в виде кода для копирования/вставки с допустимым синтаксисом R, а не в виде снимка экрана таблицы. dput() — отличная команда для этого, dput(data[1:12, ]) выдаст версию для копирования/вставки первых 12 строк данных, включая всю информацию о классах и структурах.

Gregor Thomas 12.05.2022 15:42

Из картинки ваших данных не понятно, какие точки должны соединяться. Есть ли столбец идентификатора или что-то еще, чтобы указать, какие пары точек идут вместе?

Gregor Thomas 12.05.2022 15:42

Спасибо, Грегор. Я только что добавил копируемый/вставляемый код — так лучше?

EllaM 12.05.2022 15:59

Точки, которые необходимо соединить, - это Tr и Sr для каждого субъекта в каждой группе Exp и Ctr. Итак, для первого точки, которые необходимо соединить в группе Exp, - это 14 и 23.

EllaM 12.05.2022 16:00

Это намного яснее. position_jitterdodge хорошо работает для точечных и блочных диаграмм согласно этому ответу, но и с линиями, я думаю, единственный вариант — это дрожание вручную — добавление шума в виде столбцов в ваши данные. У меня нет времени написать ответ сейчас, но сегодня вечером, если никто не ответил, я постараюсь взглянуть.

Gregor Thomas 12.05.2022 18:02

Спасибо, Грегор. Я посмотрел на приведенный выше пример, и position_jitterdodge работал хорошо, однако я все еще не могу заставить его соединить два значения для каждого субъекта в каждой группе Ctr и Exp. Я не уверен, что вы имеете в виду, добавляя шум в виде столбцов в данные, не могли бы вы уточнить или добавить пример, пожалуйста?

EllaM 13.05.2022 08:23
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вдохновленный ответом, на который вы ссылаетесь, - @ Ответ Джона

Есть несколько ключевых вещей, чтобы понять решение

  1. Поскольку вам нужно, чтобы точки и линии были соединены, вам нужно, чтобы они оба применяли один и тот же случайный джиттер, или лучше всего дрожать данные, прежде чем они попадут в график, что я и сделал.
  2. Поскольку переменная, к которой применяется дрожание, не является числом, полезно отметить, что R отображает вектор символов Group как фактор, интерпретируемый как числа 1,2,3,.. соответствующие уровням факторов. Следовательно, мы создаем числовой вектор group_jit со значениями около 1 и 2 со смещениями, основанными на цветовой переменной Strategy, чтобы немного сместиться влево и вправо вокруг 1 и 2.
  3. Поскольку у вас есть две независимые цветовые шкалы, лучше всего, чтобы группы были представлены как fill, а линии - как colour, чтобы избежать одной легенды с 4 вещами на ней.

Вот код -

library(tidyverse)

# Load data
d <- data.frame (
  Subject = c("1", "2", "3", "4"),
  Group  = c("Exp", "Exp", "Control", "Control"),
  Tr = c("14", "11", "4", "23"),
  Sr = c("56", "78", "12", "10"),
  Increase = c("TRUE", "TRUE", "TRUE", "FALSE")
)

width_jitter <- 0.2 # 1 means full width between points

# put the data in long format
d_jit <- d %>%
  gather(key = "Strategy", value = "raw", Tr, Sr) %>% 
  
  # type conversions
  mutate(across(c(Group, Strategy), as_factor)) %>% # convert to factors
  mutate(raw = as.numeric(raw)) %>% # make raw as numbers
  
  # position on x axis is based on combination of Group and jittered Strategy. Mix to taste.
  mutate(group_jit = as.numeric(Group) + jitter(as.numeric(Strategy) - 1.5) * width_jitter * 2,
         grouping = interaction(Subject, Strategy))

# plotting
d_jit %>%
  ggplot(aes(x = Group, y = raw, fill = Strategy)) +
  geom_boxplot(width = 0.5, lwd = 0.5, alpha = 0.05, show.legend = FALSE) +
  geom_point(aes(x = group_jit), size = 3, shape = 21) +
  
  geom_line(aes(x = group_jit,
                group = Subject,
                colour = Increase),
            alpha = 0.5,
            arrow = arrow(type = "closed",
                          length = unit(0.075, "inches"))
            ) + 
  scale_colour_manual(values = c('red', 'black'))

Created on 2022-05-14 by the reprex package (v2.0.1)

Для полноты картины другой и более элегантный способ сделать джиттер — передать аргумент position командам geom_point и geom_line функции, которая добавляет случайный джиттер, как это (источник: Ответ @erocoar)

position = ggplot2::position_jitterdodge(dodge.width = 0.75, jitter.width = 0.3, seed = 1)

Таким образом, сами данные не изменяются, а график учитывает детали дрожания.

  • jitterdodge делает уклонение (сдвиг для переменной оси x) и дрожание (небольшой шум для цветных точек)
  • Аргумент seed здесь является ключевым, поскольку он гарантирует, что одни и те же значения случайный возвращаются для точки и функций линии, которые вызывают ее независимо.

Большое спасибо, Прашант! Это именно то, что мне было нужно! Пример действительно ясен, и объяснения действительно помогли мне понять, что мне нужно делать. Очень признателен :)

EllaM 15.05.2022 10:23

Пожалуйста! Если на вопрос дан удовлетворительный ответ, не могли бы вы accept установить его, установив флажок в левом верхнем углу, чтобы вопрос был помечен как решенный для будущих людей, которые найдут этот пост, спасибо!

Prashant Bharadwaj 15.05.2022 23:27

Другие вопросы по теме