【问题标题】:Mode computation on counted categorical variables计数分类变量的模式计算
【发布时间】:2019-07-10 12:43:57
【问题描述】:

这是我的数据集:

X Totally.Disagree Disagree Agree Totally.agree
0                2        9   111           122
1                2       30   124            88
2                4       31   119            90
3               10       43   138            53
4               33       54    85            72
5               43       79    89            33
6               48       83    94            19
7               51       98    80            15
8               50      102    75            17
9               51       96    80            17

其中 X(因此每行)是一个问题,值是选择该问题答案的人数。我想计算每个问题的模式(选择最多的答案)。

这是我尝试过的:

df <- gather(df,Answer, count, Totally.Disagree:Totally.agree )
df %>% 
  group_by(X, Answer) %>%
  summarise(sum = count)%>%
  summarise(mode = df$Answer[which(df$count== max(df$count))])

但这不起作用,因为max(df$count) 指的是整个数据集,而不仅仅是一个问题。

如果我尝试的方式正确,我现在不这样做。如果你们中的任何一个可以帮助我解决这个问题,我将不胜感激。

【问题讨论】:

    标签: r dplyr categorical-data mode


    【解决方案1】:

    如果您只想要答案本身(没有数字)并且我们可以假设没有平局,那么

    df <- gather(df, Answer, count, Totally.Disagree:Totally.agree)
    df %>% group_by(X) %>% summarise(mode = Answer[which.max(count)])
    # A tibble: 10 x 2
    #        X mode         
    #    <int> <chr>        
    #  1     0 Totally.agree
    #  2     1 Agree        
    #  3     2 Agree        
    #  4     3 Agree        
    #  5     4 Agree        
    #  6     5 Agree        
    #  7     6 Agree        
    #  8     7 Disagree     
    #  9     8 Disagree     
    # 10     9 Disagree
    

    Answer[which.max(count)] 基本上是您打算做的,但不需要df$,因为您希望这些计算按组进行。

    【讨论】:

    • 非常感谢您的回答,它帮助我理解了我所犯的错误!
    【解决方案2】:

    另一种方法可能是:

    df %>%
     mutate(mode = max.col(.[2:length(.)])+1) %>%
     rowwise() %>%
     mutate(mode = names(.)[[mode]]) %>%
     select(X, mode)
    
           X mode         
       <int> <chr>        
     1     0 Totally.agree
     2     1 Agree        
     3     2 Agree        
     4     3 Agree        
     5     4 Agree        
     6     5 Agree        
     7     6 Agree        
     8     7 Disagree     
     9     8 Disagree     
    10     9 Disagree  
    

    这里,它首先识别出计数最多的列的索引,然后根据列索引分配列的名称。

    如果你还想包含数字,你可以试试:

    df %>%
     mutate(mode = max.col(.[2:length(.)])+1) %>%
     rowwise() %>%
     mutate(mode_names =  names(.)[[mode]], 
            mode_numbers = max(!!! rlang::syms(names(.)[2:length(.)]))) %>%
     select(X, mode_names, mode_numbers)
    
           X mode_names    mode_numbers
       <int> <chr>                <dbl>
     1     0 Totally.agree         122.
     2     1 Agree                 124.
     3     2 Agree                 119.
     4     3 Agree                 138.
     5     4 Agree                  85.
     6     5 Agree                  89.
     7     6 Agree                  94.
     8     7 Disagree               98.
     9     8 Disagree              102.
    10     9 Disagree               96.
    

    或者按照你原来的逻辑:

    df %>%
     gather(mode_names, mode_numbers, -X) %>%
     group_by(X) %>%
     filter(mode_numbers == max(mode_numbers)) %>%
     arrange(X)
    
           X mode_names    mode_numbers
       <int> <chr>                <int>
     1     0 Totally.agree          122
     2     1 Agree                  124
     3     2 Agree                  119
     4     3 Agree                  138
     5     4 Agree                   85
     6     5 Agree                   89
     7     6 Agree                   94
     8     7 Disagree                98
     9     8 Disagree               102
    10     9 Disagree                96
    

    【讨论】:

    • 哇,非常感谢您的回答,速度很快,很完整!一位朋友还告诉我关于 argmax() 函数,它给了我行最高值的列号。然后,我可以将列名寻址到列号。它有效,但不如您的解决方案优雅。再次感谢
    • 如果帖子解决了您的问题,请投赞成票并接受它:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多