【问题标题】:How to calculate means for nested groups and count number of observations in R如何计算嵌套组的平均值并计算 R 中的观察次数
【发布时间】:2021-05-06 20:31:19
【问题描述】:

所有(R 用户), 非常感谢您提前。我有一个数据集,其中包含来自多个州的学生分数。每个州都有不同的学校(本例中为 10 所学校),每所学校必须是“公立”或“私立”;和三个项目的考试成绩。我需要计算每个项目的每个学校的平均值,并显示学校的类型,然后将结果保存到 excel 文件中以导出它们。

excel文件的预期结果将包括:

  1. 州名列,
  2. 学校名称列(每个州列 10 所学校),
  3. 学校类型列(表示“公立”或“私立”),
  4. 每所学校的学生人数,
  5. item1 的平均值,
  6. item2 的平均值,并且
  7. item3 的平均值。
library(randomNames)

# example to demonstrate the general concept): 
ID = 1:50
states = rep(c("TS", "NE", "AR", "MO", "WA"),times = c(10, 10, 10, 10, 10))
schools = randomNames::randomNames(50) ## 5 first last names separated by a space
type = rep(c("private", "public"),times = c(20,30))
item1 = rnorm(50, mean=25, sd=5)
item2 = rnorm(50, mean=30, sd=5)
item3 = rnorm(50, mean=15, sd=5)
df = data.frame(ID, states, schools, type, item1, item2, item3)

然后我需要将它保存到excel文件中以使用以下代码分别导出每个状态:

# this below code works fine, I'm just adding it to explain the full concept. 

list_data <- split(df, df$states)
Map(openxlsx::write.xlsx, list_data, paste0(names(list_data), '.xlsx'))

非常感谢。

【问题讨论】:

    标签: r data-analysis


    【解决方案1】:

    您可以使用 dplyrtidyr 包做到这一点:

    library(dplyr)
    library(tidyr)
    
    df %>% 
      dplyr::group_by(states, schools, type) %>% 
      dplyr::summarize(across(tidyr::starts_with("item"), ~ mean(.)),
                       students = n()) %>%
      dplyr::ungroup()
    
       states schools             type   item1 item2 item3 students
       <chr>  <chr>               <chr>  <dbl> <dbl> <dbl>    <int>
     1 AR     al-Hosein, Zubaida  public  23.4  35.1 15.4         1
     2 AR     al-Mohamed, Raadiya public  24.5  30.8 13.5         1
     3 AR     Bluford, Sage       public  29.9  32.4  9.49        1
     4 AR     Covarrubias, Julio  public  19.8  27.8 15.2         1
     5 AR     el-Gad, Naaila      public  27.0  33.5 19.5         1
     6 AR     el-Mansour, Fawzia  public  34.4  25.4 17.9         1
     7 AR     el-Sadri,  Sakeena  public  24.7  30.5 13.9         1
     8 AR     Ewers, Benjamin     public  18.3  33.6 13.5         1
     9 AR     Rivas, Joel         public  16.8  25.1 20.5         1
    10 AR     Wilson, Reneisha    public  28.9  28.5 18.5         1
    # ... with 40 more rows
    

    如果您有其他以item 开头的列名,那么您可以将行across(tidyr::starts_with(.... 更改为item1 = mean(item1) 等等。

    学生的计数假定学校和州内的每一行都是学生,并且给定学校的类型不会改变。

    【讨论】:

    • 非常感谢,它工作得很好,除了我仍然需要帮助的唯一小部分是:1\ 列有不同的名称,即它们不以“item”开头,以及 2 ) 它们有不同的 col 编号(例如 col3、col8、col19 等)。
    • starts_with("item") 更改为starts_with("col")。数字无关紧要。它将在名称以“col”开头的任何列上执行该函数。
    • 抱歉,我的意思是不同的名称,列的名称开始不同(例如,item3、midterm、final、quiz 等)。
    • 然后按照我发布的建议:删除across(tidyr::starts_with(....), ...) 并在summarize 函数中将其替换为item3 = mean(item3), midterm = mean(midterm), ...
    • 如果你知道列位置并且它是固定的,那么你可以调整代码如下:across(c(5, 6, 7), mean)
    猜你喜欢
    • 2017-09-04
    • 1970-01-01
    • 2021-02-26
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    相关资源
    最近更新 更多