如何高效计算并绘制每位参与者每10试次的反应选择比例分面图
解决方案
第一步:批量预处理全量数据(推荐,效率最高,兼容200+被试)
用dplyr分组操作一次性计算所有被试所有试次块的选择占比,无需循环单个处理:
library(dplyr) library(tidyr) # 全量数据直接处理,无需逐被试筛选 processed_df <- banditData %>% # 按被试分组,为每个被试的试次划分10个一组的块 group_by(participant_num) %>% mutate( # 每10个试次归为一个块,1-10为块1,11-20为块2,以此类推 trial_bin = ceiling(trial / 10), # 绘图用x轴坐标,取每个块的最后一个试次,和原有刻度对齐 plot_x = trial_bin * 10 ) %>% # 按被试、试次块、反应选项分组,统计每组数量 group_by(participant_num, trial_bin, plot_x, resp) %>% summarise(count = n(), .groups = "drop") %>% # 计算每个试次块内两个反应的占比 group_by(participant_num, trial_bin) %>% mutate(resp_prop = count / sum(count)) %>% ungroup() %>% # 把resp值替换为原有bandit命名,对应臂1/臂2 mutate(bandit = ifelse(resp == 0, "臂1", "臂2"))
小提示:如果你的试次编号从0开始,调整
trial_bin = ceiling((trial + 1)/10)即可保证分箱正确。
第二步:分面绘图代码
直接添加分面参数即可,和原有绘图逻辑完全兼容:
ggplot() + # 原有奖励率虚线层,若rewardDF也要分面需要补充participant_num列 geom_line(data=rewardDF,aes(x=Trial,y=pHappy,colour=Bandit), linetype="dashed", size=1.03)+ # 选择比例的点和线,直接用预处理好的processed_df geom_point(data=processed_df,aes(x=plot_x, y=resp_prop,colour=bandit,shape=bandit),size=3)+ geom_line(data=processed_df,aes(x=plot_x, y=resp_prop,colour=bandit),size=1)+ scale_shape_manual(values=SymTypes)+ scale_colour_manual(values=cbPalette)+ labs(col='bandit',y='p(choice)',x='trials')+ scale_x_continuous(breaks = seq(0,200,by=10), limits=c(0,203), expand=c(0,0))+ scale_y_continuous(breaks = seq(0,1,by=0.1), limits=c(0,1.03), expand=c(0.02,0))+ theme_bw() + # 新增分面设置,按被试纵向排列 facet_grid(participant_num ~ .) + # 被试数量多的话可调整height参数控制输出尺寸 ggsave("data/all_subject_pchoice.png", scale=2,dpi = 300, height = 100, limitsize = FALSE)
如果被试太多纵向排列过长,可以改成facet_wrap(~participant_num, ncol = 4)调整列数,按需修改ncol参数即可。
可选:直接在ggplot内计算占比(无需单独预处理)
如果不想单独写预处理代码,可以用stat_summary_bin直接按10试次分箱计算占比:
ggplot(banditData, aes(x = trial, colour = "臂1")) + # 计算resp=0的选择占比,分箱宽度为10 stat_summary_bin(aes(y = as.numeric(resp == 0)), fun = mean, binwidth = 10, geom = "point", size = 3) + stat_summary_bin(aes(y = as.numeric(resp == 0)), fun = mean, binwidth = 10, geom = "line", size = 1) + # 叠加resp=1的选择占比 stat_summary_bin(aes(y = as.numeric(resp == 1), colour = "臂2"), fun = mean, binwidth = 10, geom = "point", size = 3) + stat_summary_bin(aes(y = as.numeric(resp == 1), colour = "臂2"), fun = mean, binwidth = 10, geom = "line", size = 1) + # 其余原有参数不变,添加分面即可 facet_grid(participant_num ~ .) + scale_shape_manual(values=SymTypes)+ scale_colour_manual(values=cbPalette)+ labs(col='bandit',y='p(choice)',x='trials')+ scale_x_continuous(breaks = seq(0,200,by=10), limits=c(0,203), expand=c(0,0))+ scale_y_continuous(breaks = seq(0,1,by=0.1), limits=c(0,1.03), expand=c(0.02,0))+ theme_bw()
内容的提问来源于stack exchange,提问作者Ilaria
相关产品推荐
相关产品推荐

