【问题标题】:R tidyr spread columns across all categories of a given variableR tidyr 在给定变量的所有类别中展开列
【发布时间】:2019-02-25 15:39:18
【问题描述】:

我正在处理一个看起来像这样的数据集。

#Dataframe
df=data.frame(Type=c(1,2,4,5,4,3,3,4,5,1,2,3,2,1,2,3,3,2,1,1,NA),
          Q1=c(1,2,6,8,9,10,2,6,7,4,9,9,1,2,NA,4,3,8,7,6,4),
          Q2=c(1,2,4,NA,8,2,1,2,10,7,5,5,5,8,2,7,4,8,7,5,1))

上下文

数据框由调查问卷的结果组成。

第一列Type表示回答问卷的员工类型,其中1 = 'Worker',2 = 'Factory Lead',3 = 'Administrative Staff',4 = ' Middle Management' & 5 = 'Executive'

第二列和第三列 (Q1 & Q2) 是问题,等级为 1 = 'Strongly Agree' 到 10 (Strongly Disagree)。

我正在努力实现的目标

我想根据分数计算每个Type 的响应总数。 我已经为分数创建了垃圾箱,它们是 -

1) Low 协议 - 分数从 0 到 4

2) Medium 同意 - 5 或 6 分

3) High 同意 - 7 或 8 分

4) Very High 同意 - 9 或 10 分

所以我想计算每个评分箱中每个工人的响应数。

我的尝试

library(dplyr)
library(tidyr)

result=df %>%
gather(Item,response,-1) %>%
filter(!is.na(response)) %>%
group_by(Type,Item) %>%
filter(!is.na(Type)) %>%
summarise(Low=sum(response %in% c(0,1,2,3,4)),
        Medium=sum(response %in% c(5,6)),
        High=sum(response %in% c(7,8)),
        VHigh=sum(response %in% c(9,10)) %>%
spread(Type,-Item)

我的逻辑是我使用tidyr 库和第一个gather 分数来计算总响应。然后展开列,这样我就有了按工人和分数类别的小计。

例如,对于第一季度,Low-WorkerMedium-WorkerHigh-WorkerVery High-WorkerLow-Factory LeadMedium-Factory Lead 的总响应列......等等适用于员工和分数类别的所有组合。

很明显,我的代码有问题。

期望的输出

一个包含 两行Q1 & Q2)和 20 列(针对每个员工分数组合)的数据框。

对此的任何帮助将不胜感激。

【问题讨论】:

    标签: r tidyr data-manipulation spread


    【解决方案1】:

    创建分数数据框

    library(tidyr)
    library(dplyr)
    df <- data_frame(type=c(1,2,4,5,4,3,3,4,5,1,2,3,2,1,2,3,3,2,1,1,NA),
                     q1=c(1,2,6,8,9,10,2,6,7,4,9,9,1,2,NA,4,3,8,7,6,4),
                     q2=c(1,2,4,NA,8,2,1,2,10,7,5,5,5,8,2,7,4,8,7,5,1))
    
    scores <- data_frame(score = 0:10,
                         scorebin = c(rep("Low", 5),
                                      rep("Medium", 2),
                                      rep("High", 2),
                                      rep("Very High", 2)))
    

    以长格式收集数据。加入分数数据框以添加scorebin 列。按itemtypescorebin 分组,并统计每组下的答案数。

    df2 <- df %>%
        gather(item, score, -type) %>% 
        left_join(scores, by = "score") %>% 
        group_by(item, type, scorebin) %>% 
        summarise(n = n()) %>% 
        unite(employeescore, type, scorebin)
    

    employeescore 更改为具有有序水平的因子 这样它们就不会按字母顺序显示(高、低、中) 但顺序正确(低、中、高)。

    employeescoreorder <- scores %>% 
        distinct(scorebin) %>% 
        merge(distinct(df, type)) %>% 
        unite(employeescore, type, scorebin)
    df2$employeescore <- factor(df2$employeescore, 
                                levels = employeescoreorder$employeescore)
    

    以宽格式展开数据框,得到 20 列。

    df2 %>% 
        spread(employeescore, n)
    
    # A tibble: 2 x 20
    # Groups:   item [2]
       item `1_Low` `1_Medium` `1_High` `2_Low` `2_Medium` `2_High` `2_Very High` `4_Low`
    * <chr>   <int>      <int>    <int>   <int>      <int>    <int>         <int>   <int>
    1    q1       3          1        1       2         NA        1             1      NA
    2    q2       1          1        3       2          2        1            NA       2
    # ... with 11 more variables: `4_Medium` <int>, `4_High` <int>, `4_Very High` <int>,
    #   `5_High` <int>, `5_Very High` <int>, `3_Low` <int>, `3_Medium` <int>, `3_High` <int>,
    #   `3_Very High` <int>, NA_Low <int>, `<NA>` <int>
    

    【讨论】:

      【解决方案2】:

      像这样?

       df%>%
         mutate(Type_real=case_when(
                   Type==1~"Worker",
                   Type==2~"Factory Lead",
                   Type==3~"Administrative Staff",
                   Type==4~"Middle Management",
                   Type==5~"Executive"),
               Score=case_when(
                   Q1<5~"Low",
                   Q1>=5 & Q1<=6~"Medium",
                   Q1>=7 & Q1<=8~"High",
                   Q1>8~"Very High"))%>%
         na.omit()%>%
         group_by(Type_real,Score)%>%
         summarise(count=n())
      # A tibble: 11 x 3
      # Groups:   Type_real [?]
         Type_real            Score     count
         <chr>                <chr>     <int>
       1 Administrative Staff Low           3
       2 Administrative Staff Very High     2
       3 Executive            High          1
       4 Factory Lead         High          1
       5 Factory Lead         Low           2
       6 Factory Lead         Very High     1
       7 Middle Management    Medium        2
       8 Middle Management    Very High     1
       9 Worker               High          1
      10 Worker               Low           3
      11 Worker               Medium        1
      

      【讨论】:

        【解决方案3】:

        另一个类似于 Paul Rougieux 但没有连接的解决方案是:

        df %>% 
          mutate(Type = case_when(Type == 1 ~ "Worker",
                                  Type == 2 ~ "Factory Lead",
                                  Type == 3 ~ "Administrative Staff",
                                  Type == 4 ~ "Middle Management",
                                  Type == 5 ~ "Executive")) %>% 
          mutate_at(c("Q1", "Q2"), 
                    funs(case_when(. %in% 1:4 ~ "Low",
                                   . %in% 5:6 ~ "Medium",
                                   . %in% 7:8 ~ "High",
                                   . %in% 9:10 ~ "Very High"))) %>%
          gather(Questions, Score, Q1:Q2) %>% 
          unite(Type_Score, Type, Score, sep = "_") %>% 
          count(Questions, Type_Score) %>% 
          spread(Type_Score, n)
        
        # A tibble: 2 x 21
        #   Questions `Administrative~ `Administrative~ `Administrative~ `Administrative~ Executive_High Executive_NA `Executive_Very~ `Factory Lead_H~
        #   <chr>                <int>            <int>            <int>            <int>          <int>        <int>            <int>            <int>
        # 1 Q1                      NA                3               NA                2              2           NA               NA                1
        # 2 Q2                       1                3                1               NA             NA            1                1                1
        # ... with 12 more variables: `Factory Lead_Low` <int>, `Factory Lead_Medium` <int>, `Factory Lead_NA` <int>, `Factory Lead_Very High` <int>,
        #   `Middle Management_High` <int>, `Middle Management_Low` <int>, `Middle Management_Medium` <int>, `Middle Management_Very High` <int>,
        #   NA_Low <int>, Worker_High <int>, Worker_Low <int>, Worker_Medium <int>
        

        【讨论】:

          猜你喜欢
          • 2015-04-11
          • 2021-07-09
          • 2018-02-11
          • 1970-01-01
          • 2017-03-27
          • 1970-01-01
          • 2016-10-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多