首页 > 解决方案 > r - 使用循环为多对变量创建单向方差分析、汇总统计和绘图

问题描述

我是新来的,对编程很陌生,所以任何帮助都将不胜感激。

我有一个数据框 df1,它看起来像这样:

图片 情感 性别 类型 审判 Attr_scores Fear_scores Appr_scores 避免分数
1 快乐的 男性 人类 第一的 11 3 21 21
2 伤心 男性 人类 第一的 12 6 22 22
3 中性的 男性 人类 第一的 13 2 23 23
4 快乐的 男性 卡通片 第一的 14 3 24 24
5 伤心 男性 卡通片 第一的 15 6 25 25
6 中性的 男性 卡通片 第一的 16 2 26 26
7 快乐的 男性 动物 第一的 17 3 27 27
8 伤心 男性 动物 第一的 18 6 28 28
9 中性的 男性 动物 第一的 19 2 29 29
10 快乐的 女性 人类 第一的 20 3 21 30
11 伤心 女性 人类 第一的 21 6 22 31
12 中性的 女性 人类 第一的 22 2 23 32
13 快乐的 女性 卡通片 第一的 23 3 24 33
14 伤心 女性 卡通片 第一的 24 6 25 34
15 中性的 女性 卡通片 第一的 25 2 26 35
16 快乐的 女性 动物 第一的 26 3 27 36
17 伤心 女性 动物 第一的 27 6 28 37
18 中性的 女性 动物 第一的 28 2 29 38

这是生成它的代码:

Picture <- c(1:18)
Emotion <- rep(c('happy','sad','neutral'),times=6)
Gender <- rep(c('male','female'),each=9)
Type <- rep(c('human','cartoon','animal','human','cartoon','animal'),each=3)
Trial <- rep(c('first'),times=18)
Attr_scores <- c(11:28)
Fear_scores <- rep(c(3,6,2),times=6)
Appr_scores <- rep(c(21:29),times=2)
Avoid_scores <- c(21:38)
df1<-data.frame(Picture,Emotion,Gender,Type,Trial,Attr_scores,Fear_scores,Appr_scores,Avoid_scores)

我需要获取几对变量(一个自变量 + 一个因变量,例如 Emotion + Attr_scores、Emotion + Fear_scores、Gender + Attr_scores、Gender + Avoid_scores),并对它们中的每一个:1)运行汇总统计(比较均值和SDs),2)运行单向方差分析,3)创建散点图。

到目前为止,我已经为第一对变量(Gender + Attr_scores)创建了代码。这是代码:

# Summary Statistics 
library(dplyr)
group_by(df1, Gender) %>%
  summarise(
    N = n(),
    Mean = mean(Attr_scores, na.rm = TRUE),
    Sd = sd(Attr_scores, na.rm = TRUE)
  )
# ANOVA
res.aov <- aov(Attr_scores ~ Gender, data = df1)
summary(res.aov)
#Plot
gender_attr_plot <- ggplot(df1, aes(x=Gender, y=Attr_scores)) + 
  geom_jitter(position=position_jitter(0.2))+ 
  stat_summary(fun.data=mean_sdl, fun.args = list(mult = 1), 
               geom="pointrange", color="red")
ggsave("gender_attr_plot.png", gender_attr_plot, width = 1600, height = 900, units = "px")

我可以为每对额外的变量复制粘贴代码并每次手动更改变量名称,但这似乎是一种非常低效的做事方式。此外,如果我需要对任何额外的变量对运行相同的分析,我将不得不再次复制整个代码来执行此操作。

我想要做的是创建一个带有变量对的表或嵌套列表(如果需要额外的变量对,以后可以轻松更新)并编写一个循环来遍历这些变量对并执行所有 3 个操作(汇总统计、方差分析和绘图)。

我认为它应该看起来像这样(这与实际的工作代码相去甚远,只是给出一个大致的想法):

variables <- list(
c(Gender, Attr_scores),
c(Gender, Fear_scores), 
c(Type, Appr_scores), 
c(Emotion, Avoid_scores))

for(i in variables){
  library(dplyr)
  group_by(df1, variables,'[[',1) %>%
    summarise(
      N = n(),
      Mean = mean(variables,'[[',2, na.rm = TRUE),
      Sd = sd(variables,'[[',2, na.rm = TRUE)
    )
  res.aov <- aov(variables,'[[',2 ~ variables,'[[',1, data = df1)
  summary(res.aov)
  plot <- ggplot(df1, aes(x=variables,'[[',1, y=variables,'[[',2)) + 
    geom_jitter(position=position_jitter(0.2))+
    stat_summary(fun.data=mean_sdl, fun.args = list(mult = 1),
                 geom="pointrange", color="red")
  ggsave("??????.png", plot, width = 1600, height = 900, units = "px")
}

显然,这是行不通的,我一直在互联网上搜索解决方案,但我对 R 的了解还不足以弄清楚如何使其工作。非常感激任何的帮助!

标签: rdataframeloopsanova

解决方案


这是您的任务的一个可能的解决方案:我稍微修改了您的代码并my_function使用此函数创建了一个函数,您可以获得一对数据集的所需输出。结果以列表形式返回!

library(dplyr)
library(ggplot2)


my_function <- function(df, x, y) { 
# Summary
  a <- group_by(df, {{x}}) %>% 
    summarise(
      N = n(),
      Mean = mean({{y}}, na.rm = TRUE),
      Sd = sd({{y}}, na.rm = TRUE)
    )
# ANOVA
  res.aov <- aov({{y}} ~ {{x}}, data = df)
  b <- summary(res.aov)
# Plot
c <- ggplot(df1, aes(x={{x}}, y={{y}})) + 
  geom_jitter(position=position_jitter(0.2))+ 
  stat_summary(fun.data=mean_sdl, fun.args = list(mult = 1), 
               geom="pointrange", color="red")
  ggsave(paste0(deparse(substitute(x)), "_",
               deparse(substitute(y)), ".png"), width = 1600, height = 900, units = "px")
  
  output<-list(a,b,c)
  return(output)
  
  }

# cases 1 - 4
my_function(df1, Gender, Attr_scores)
my_function(df1, Gender, Avoid_scores)
my_function(df1, Emotion, Attr_scores)
my_function(df1, Emotion, Fear_scores)

推荐阅读