Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
142 views
in Technique[技术] by (71.8m points)

plot - How to create a bar graph with scatter for two metrics across three conditions in R

I want to create a somewhat complicated bar graph where I show data about how participants perceived 40 videos. I have a list of video data where the first 10 are categorised as 'neutral', the next ten as 'pleasant', the next ten as 'unpleasant, and the final ten as 'painful'. For each video I have the mean threat and arousal score (taken across all participants). I need to display the mean threat and arousal score for the four categories (so the mean of the means), but also data from the individual (10) videos in each category. I was thinking to show a bar graph with the mean per category for treat and arousal and also has the threat and scores for each video in that category scattered over it. So there will be 4 sets of 2 bar graphs of the mean (arousal & threat), each with scatter. I hope this makes sense.

Here is my dataframe:

structure(list(`YouTube Video` = c(2, 4, 6, 23, 13, 84, 1, 27, 
89, 82, 79, 78, 88, 87, 68, 75, 69, 81, 70, 85, 62, 14, 52, 60, 
17, 21, 41, 50, 57, 65, 37, 39, 33, 29, 12, 28, 56, 35, 54, 64
), Description = c("single touch with finger", "repeated tap with finger (slow)", 
"single touch with flat hand", "single push with a spoon", "single touch with pen", 
"single touch with cotton bud", "Repeated touch with finger (fast)", 
"single push with a plastic whisk", "single touch with plastic brush", 
"repeated touch with cotton bud", "long stroke with soft brush all over the hand", 
"single stroke top to bottom with soft brush", "repeated stroke with plastic brush", 
"single stroke top to bottom with plastic brush", "stroke top to bottom with shawl", 
"(long) stroke with multiple fingers all over the hand", "stroke with soft sock", 
"single stroke top to bottom with cotton pad", "(long) stroke with finger all over the hand", 
"touch top to bottom with fabric", "touch top to bottom with scissors", 
"repeated touch with pencil", "touch top to bottom with hammer", 
"single push with tip of pencil", "repeated touch with rolling pin", 
"repeated touch with metal chopstick", "injection with blunt syringe", 
"single (long) hard push with thumb", "single touch with nail file", 
"stroke top to bottom with stanley knife", "single stab with nail file", 
"single stab with scissors", "scratch top to bottom with scissors", 
"single pinch with tweezers", "repeated touch with nail file", 
"single injection with sharp needle", "repeated touch with nail file", 
"single punch with hand", "repeated touch with knife", "repeated touch with screwdriver"
), `URL embedded` = c("https://www.youtube-nocookie.com/embed/DGrxS_mWwDg", 
"https://www.youtube-nocookie.com/embed/4LCl3lFTI5A", "https://www.youtube-nocookie.com/embed/hZUtrE-RKm4", 
"https://www.youtube-nocookie.com/embed/PP-1YXwLlRY", "https://www.youtube-nocookie.com/embed/9kbi3SeqTvA", 
"https://www.youtube-nocookie.com/embed/FrptTIFnmBw", "https://www.youtube-nocookie.com/embed/mvZ-J93FhB8", 
"https://www.youtube-nocookie.com/embed/oMD7Mx59g8g", "https://www.youtube-nocookie.com/embed/xidtijNKyyQ", 
"https://www.youtube-nocookie.com/embed/eUFhskpG23o", "https://www.youtube-nocookie.com/embed/yTOtXyxZwwA", 
"https://www.youtube-nocookie.com/embed/qWqE4EwoQhE", "https://www.youtube-nocookie.com/embed/ZqdKx5F1Znk", 
"https://www.youtube-nocookie.com/embed/LiRUSe-EkBU", "https://www.youtube-nocookie.com/embed/oAppP1G7v_8", 
"https://www.youtube-nocookie.com/embed/oqKfHwrQwDA", "https://www.youtube-nocookie.com/embed/Q5HmjP90gNg", 
"https://www.youtube-nocookie.com/embed/qhjl0GC5rCg", "https://www.youtube-nocookie.com/embed/Uh_zkgSw54c", 
"https://www.youtube-nocookie.com/embed/VTlA9jr738k", "https://www.youtube-nocookie.com/embed/CuAHBe4I_Ow", 
"https://www.youtube-nocookie.com/embed/X-3k3azNHMI", "https://www.youtube-nocookie.com/embed/4hoUl6LOHA8", 
"https://www.youtube-nocookie.com/embed/6EntuJ9nykI", "https://www.youtube-nocookie.com/embed/n5aF28PZAcU", 
"https://www.youtube-nocookie.com/embed/bK1XMN1WLEs", "https://www.youtube-nocookie.com/embed/7Mld2Gte0zI", 
"https://www.youtube-nocookie.com/embed/IFMtXP4F--I", "https://www.youtube-nocookie.com/embed/NZQmIbMjej0", 
"https://www.youtube-nocookie.com/embed/cuI6qKt53ns", "https://www.youtube-nocookie.com/embed/_EdsOk7w9l4", 
"https://www.youtube-nocookie.com/embed/DF77B8-cgNs", "https://www.youtube-nocookie.com/embed/u8zIL3z18QQ", 
"https://www.youtube-nocookie.com/embed/-t4gHLk4yCY", "https://www.youtube-nocookie.com/embed/VfbW0tYdwZQ", 
"https://www.youtube-nocookie.com/embed/5fg_D5MPGTo", "https://www.youtube-nocookie.com/embed/vDCH3xNFTss", 
"https://www.youtube-nocookie.com/embed/0mHsdkv9hzM", "https://www.youtube-nocookie.com/embed/T-SrpmKS1ts", 
"https://www.youtube-nocookie.com/embed/k5WDZ5hIijY"), Neutral = c(85, 
76, 76, 76, 75, 74, 70, 70, 70, 69, 8, 6, 14, 14, 12, 16, 14, 
26, 29, 30, 4, 21, 29, 28, 19, 22, 8, 11, 8, 9, 2, 1, 5, 2, 2, 
6, 5, 8, 4, 6), Pleasant = c(8, 12, 14, 9, 4, 22, 8, 9, 29, 24, 
90, 89, 85, 84, 80, 75, 72, 71, 66, 66, 4, 1, 2, 1, 2, 5, 2, 
4, 0, 2, 1, 2, 1, 1, 1, 0, 1, 0, 1, 1), Unpleasant = c(8, 11, 
10, 15, 21, 4, 22, 20, 1, 6, 2, 5, 1, 2, 5, 9, 14, 1, 5, 4, 81, 
68, 62, 62, 61, 61, 61, 60, 59, 59, 14, 16, 28, 36, 38, 40, 40, 
45, 52, 50), Painful = c(0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 
0, 0, 2, 0, 0, 1, 0, 0, 11, 10, 6, 9, 18, 11, 29, 25, 34, 30, 
82, 80, 66, 60, 59, 54, 54, 48, 42, 42), `Mean Threat` = c("1.4", 
"1.5", "1.6", "1.5", "1.9", "1.4", "1.8", "1.8", "1.3", "1.5", 
"1.3", "1.2", "1.3", "1.2", "1.2", "1.5", "1.5", "1.4", "1.5", 
"1.2", "5.6", "3.2", "5.2", "2.9", "4.0", "3.4", "5.6", "3.5", 
"5.5", "6.6", "8.0", "7.8", "7.1", "4.5", "6.3", "6.7", "6.2", 
"5.0", "6.5", "5.4"), `Mean Arousal` = c("1.7", "1.9", "2.2", 
"2.1", "1.8", "2.0", "2.0", "2.3", "2.2", "2.0", "5.3", "4.8", 
"4.5", "3.9", "4.0", "4.5", "4.6", "3.3", "4.2", "3.2", "4.7", 
"3.2", "4.2", "3.0", "3.4", "3.1", "5.2", "3.8", "4.4", "5.3", 
"6.6", "6.2", "6.0", "4.9", "5.2", "6.5", "4.8", "4.0", "5.1", 
"4.6"), total_pts_sensations = c(55, 56, 90, 104, 47, 38, 48, 
52, 43, 38, 162, 139, 137, 131, 143, 177, 151, 117, 164, 82, 
116, 75, 105, 67, 75, 61, 133, 109, 123, 150, 196, 191, 182, 
141, 151, 148, 181, 77, 134, 128), MeanIntensity = c(2.8, 2.7, 
3.2, 3.2, 3.5, 2.6, 3.2, 2.9, 3.4, 2.8, 3.6, 3.6, 3.7, 3.5, 3.7, 
3.9, 3.6, 3.6, 3.6, 3.4, 3.8, 3.2, 3.7, 3.7, 3.3, 3.6, 4.4, 3.7, 
3.8, 4.2, 5, 4.8, 4.4, 4, 4.1, 3.9, 4.8, 3.7, 4, 4)), spec = structure(list(
    cols = list(Video_YouTube = structure(list(), class = c("collector_double", 
    "collector")), Video_Questionnaire = structure(list(), class = c("collector_double", 
    "collector")), Description = structure(list(), class = c("collector_character", 
    "collector")), `URL embedded` = structure(list(), class = c("collector_character", 
    "collector")), Neutral = structure(list(), class = c("collector_logical", 
    "collector")), Pleasant = structure(list(), class = c("collector_logical", 
    "collector")), Unpleasant = structure(list(), class = c("collector_logical", 
    "collector")), Painful = structure(list(), class = c("collector_logical", 
    "collector")), `Mean Threat` = structure(list(), class = c("collector_logical", 
    "collector")), `Mean Arousal` = structure(list(), class = c("collector_logical", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1), class = "col_spec"), row.names = c(NA, 
-40L), class = "data.frame")
question from:https://stackoverflow.com/questions/66055901/how-to-create-a-bar-graph-with-scatter-for-two-metrics-across-three-conditions-i

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'd suggest something different: plot the individual points as a "jitter" and add a line to show the means per category, with facets for score type.

First create some fake data according to your description (note - done before data was added to your question):

set.seed(1001)
dataset <- data.frame(video = 1:40,
                  category = rep(c("neutral", "pleasant", "unpleasant", "painful"), each = 10),
                  threat = sample(1:10, 40, replace = TRUE),
                  arousal = sample(1:10, 40, replace = TRUE))

We need some tidyverse packages:

library(tidyr) # to reshape the data
library(ggplot2)

Then reshape and plot:

dataset %>% 
  pivot_longer(cols = c("threat", "arousal")) %>% 
  ggplot(aes(category, value)) + 
  geom_jitter(aes(color = category), width = 0.2) + 
  stat_summary(geom = "crossbar", color = "red", fun = mean) + 
  facet_wrap(~name) + 
  guides(color = FALSE) +
  theme_bw()

Result:

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...