【问题标题】:How to calculate total and percentage while accounting for another column in R?如何在计算 R 中的另一列时计算总数和百分比?
【发布时间】:2021-05-12 20:09:10
【问题描述】:

所有, 提前致谢。我有这个学校数据集。每个类别(在类别列中)都有一定范围的学生人数(例如,从 30 到 60 名学生),所以我需要计算:

  1. 属于每个类别(从类别 1 到类别 4)的教室总数,以及
  2. 属于该类别的教室的百分比。 例如,有多少教室(NumOfClassrooms 列)属于 Category_4,这些教室占教室总数的百分比是多少?这是我的问题的一个说明性示例:
ID = 1:1050
District = rep(c("AR", "CO", "AL", "KS", "IN", "ME", "KY", "ME", "MN", "NJ"), times = c(80, 120, 100, 110, 120, 100, 100, 120, 100, 100))
schoolName = randomNames::randomNames(1050, ethnicity = 5 ,which.names = "last") 
Grade = rep(c("First", "Second", "Third", "Fourth"), times = c(400, 300, 200, 150))
NumOfClassrooms =  sample(1:6)
StudentNumber = sample(1:90, 5)

AverageNumOfStudents = StudentNumber/NumOfClassrooms

Category = ifelse(AverageNumOfStudents >  0 & AverageNumOfStudents < 10, "category_1", 
                  ifelse(AverageNumOfStudents >=10  & AverageNumOfStudents < 30, "category_2",
                   ifelse(AverageNumOfStudents >=30  & AverageNumOfStudents <= 60, "category_3",
                  ifelse(AverageNumOfStudents > 60 , "category_4", "NA"))))
                  
 dat = data.frame(ID, schoolName, Grade, NumOfClassrooms, StudentNumber, AverageNumOfStudents, Category)

最后,我需要使用以下代码将基于“地区”列的结果划分为单独的 excel 文件(一旦完成上述两个步骤,它应该可以正常工作)。

Final_Divide = Final_df %>%
  dplyr::group_by(District) %>%
  dplyr::ungroup()


list_data <- split(Final_Divide,
                   Final_Divide$District)
options(digits=3)
Map(openxlsx::write.xlsx, list_data, paste0(names(list_data), '.xlsx'))

非常感谢您。

【问题讨论】:

    标签: r


    【解决方案1】:

    在您的代码之前设置随机种子以实现可重复性:

    set.seed(42)
    # Your code creating dat
    Table1 <- xtabs(NumOfClassrooms~Category, dat)
    Table1
    # Category
    # category_1 category_2 category_4 
    #       1925       1575        175 
    
    Table2 <- prop.table(Table1)
    round(Table2, 4)   # Proportions
    # Category
    # category_1 category_2 category_4 
    #     0.5238     0.4286     0.0476 
    round(Table2 * 100, 2)   # Percent
    # Category
    # category_1 category_2 category_4 
    #      52.38      42.86       4.76 
    

    如果我们在dat 中包含District

    dat <- data.frame(ID, District, schoolName, Grade, NumOfClassrooms, StudentNumber, AverageNumOfStudents, Category)
    Table3 <- xtabs(NumOfClassrooms~District+Category, dat)
    addmargins(Table3)
    #         Category
    # District category_1 category_2 category_4  Sum
    #      AL         187        149         16  352
    #      AR         143        121         14  278
    #      CO         220        180         20  420
    #      IN         220        180         20  420
    #      KS         198        166         19  383
    #      KY         187        148         17  352
    #      ME         407        329         36  772
    #      MN         176        153         17  346
    #      NJ         187        149         16  352
    #      Sum       1925       1575        175 3675
    

    按地区划分的行百分比:

    round(prop.table(Table3, 1) * 100, 2)
    #         Category
    # District category_1 category_2 category_4
    #       AL      53.12      42.33       4.55
    #       AR      51.44      43.53       5.04
    #       CO      52.38      42.86       4.76
    #       IN      52.38      42.86       4.76
    #       KS      51.70      43.34       4.96
    #       KY      53.12      42.05       4.83
    #       ME      52.72      42.62       4.66
    #       MN      50.87      44.22       4.91
    #       NJ      53.12      42.33       4.55
    

    【讨论】:

    • 非常感谢,@dcarlson。这很好,如果我们可以添加百分比,这将是一个完美的解决方案,有没有一种有效的方法可以做到这一点?
    • 只需使用round(prop.table(Table3, 1) * 100, 2) 作为行边距。
    • 非常感谢,@dcarlson。
    【解决方案2】:

    这是使用tidyverse的可能解决方案

    dat %>% 
      mutate("Total Classrooms" = n()) %>% 
      group_by(Category) %>% 
      mutate("Number of Classrooms in Category" = n(),
             "Category Percentage" = `Number of Classrooms in Category`/`Total Classrooms` * 100) 
    

    这会给我们:

    # Groups:   Category [3]
          ID District schoolName  Grade NumOfClassrooms StudentNumber AverageNumOfStude~ Category  `Total Classroom~ `Number of Classrooms in~ `Category Percent~
       <int> <chr>    <chr>       <chr>           <int>         <int>              <dbl> <chr>                 <int>                     <int>              <dbl>
     1     1 AR       Svyatetskiy First               5            87              17.4  category~              1050                       525               50  
     2     2 AR       Booco       First               1            79              79    category~              1050                       175               16.7
     3     3 AR       Jones       First               6            49               8.17 category~              1050                       350               33.3
     4     4 AR       Sapkin      First               3             5               1.67 category~              1050                       350               33.3
     5     5 AR       Fosse       First               2            35              17.5  category~              1050                       525               50  
     6     6 AR       Vanwagenen  First               4            87              21.8  category~              1050                       525               50  
     7     7 AR       Orth        First               5            79              17.4  category~              1050                       525               50  
     8     8 AR       Moline      First               1            49              79    category~              1050                       175               16.7
     9     9 AR       Bradford    First               6             5               8.17 category~              1050                       350               33.3
    10    10 AR       Wollman     First               3            35               1.67 category~              1050                       350               33.3
    # ... with 1,040 more rows
    

    如果您需要仅包含类别/# 个教室/百分比数据的单独表格:

    dat %>% 
      mutate("Total Classrooms" = n()) %>% 
      group_by(Category) %>% 
      mutate("Number of Classrooms in Category" = n(),
             "Category Percentage" = `Number of Classrooms in Category`/`Total Classrooms` * 100) %>% 
      select(Category, "Number of Classrooms in Category", "Category Percentage") %>% 
      unique()
    

    这给了我们:

    # A tibble: 3 x 3
    # Groups:   Category [3]
      Category   `Number of Classrooms in Category` `Category Percentage`
      <chr>                                   <int>                 <dbl>
    1 category_2                                525                  50  
    2 category_4                                175                  16.7
    3 category_1                                350                  33.3
    

    请注意,在您的帖子中,这段代码有点多余:

    Final_Divide = Final_df %>%
      dplyr::group_by(District) %>%
      dplyr::ungroup()
    

    如果您先group,然后立即ungroup,您实际上只是在这样做:

    Final_Divide <- Final_df
    

    您还可以考虑添加 split(.$District) 以将您的数据转换为一个列表,所有这些都包含在一段代码中:

    dat %>% 
      mutate("Total Classrooms" = n()) %>% 
      group_by(Category) %>% 
      mutate("Number of Classrooms in Category" = n(),
             "Category Percentage" = `Number of Classrooms in Category`/`Total Classrooms` * 100) %>% 
      split(.$District)
    

    【讨论】:

    • 非常感谢@Matt。在我将代码从n() 更改为sum(NumOfClassrooms) 后,它运行良好。但是,当我按“地区”划分文件时,我仍然只错过了一个问题#2,代码当前计算的是国家级别(即包括所有州)的类数,而不是州级别。换句话说,当我打开 AK.xlsx(即阿肯色州数据文件)时,我可以看到最后两列(总计和百分比)与其他州的文件相同。如何分别计算每个州的总数和百分比?再次感谢。
    猜你喜欢
    • 2022-01-14
    • 2019-02-22
    • 1970-01-01
    • 2019-01-26
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多