【问题标题】:Most frequent element per column每列最常见的元素
【发布时间】:2019-04-27 06:45:23
【问题描述】:

我有以下矩阵:

set.seed(3690)

example = matrix(sample(1:10, 100, replace = TRUE), nrow = 10)

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    4    4    2    7    2    2    3    8    2     5
 [2,]    7    3    2    6    6    5    7    8    1     3
 [3,]    7    5    7    9    4    9    4    8    2     7
 [4,]    5    3    4    2    1    5    9   10    9     5
 [5,]    9   10    7    2    7    4    9    1    1     9
 [6,]    2    3    5    1    2    8    1    5    9     4
 [7,]    5    4   10    5    9   10    1    6    1    10
 [8,]    6    3    9    7    1    1    9    2    1     7
 [9,]    5    9    4    8    9    9    5   10    5     4
[10,]   10    1    4    7    3    2    3    5    4     5

如何在 R 中找到每列最频繁出现的 10(或顶部 5)元素?

这就是我在 Stata 中的编码方式:

tempvar freq
generate byte `freq'=1

sort serial t0400_0415_d1-t0345_0400_d7

collapse (count) `freq' serial,  by(t0400_0415_d1-t0345_0400_d7) 
list, sepby(`freq')

gsort -`freq' t0400_0415_d1-t0345_0400_d7
generate rank=_n
keep if rank<=20
drop `freq'

sort  t0400_0415_d1-t0345_0400_d7
tempfile top20 
save `"`top20'"'

sort rank t0400_0415_d1-t0345_0400_d7 
list rank t0400_0415_d1-t0345_0400_d7 

请注意,t0400_0415_d1 - t0345_0400_d7 是变量名。

【问题讨论】:

  • 虽然这不是你的问题,但我注意到你的 Stata 代码没有定义一个最小的、完整的、可验证的示例。无论如何,使用contract 比使用collapse 更直接。

标签: r matrix stata


【解决方案1】:

可以这样在base中完成:

 sapply(1:ncol(example), function(x) rev(tail(names(sort(table(example[,x]))), 2)))

如果你想知道频率然后忽略names()

sapply(1:ncol(example), function(x) rev(tail(sort(table(example[,x])), 2)))

【讨论】:

    【解决方案2】:

    tidyverse 的一种可能是:

    example %>%
     data.frame() %>%
     gather(var, val) %>%
     count(var, val) %>%
     arrange(var, desc(n)) %>%
     group_by(var) %>%
     slice(1:5)
    
       var     val     n
       <chr> <int> <int>
     1 X1       10     3
     2 X1        6     2
     3 X1        7     2
     4 X1        2     1
     5 X1        3     1
     6 X10       6     2
     7 X10      10     2
     8 X10       1     1
     9 X10       2     1
    10 X10       4     1
    

    使用slice(),您可以选择每列中最常出现的前 n 个(这里是前 5 个)元素。

    或者,如果您想要所有列中出现频率最高的 n 个元素:

    example %>%
     data.frame() %>%
     gather(var, val) %>%
     count(val) %>%
     arrange(desc(n)) %>%
     slice(1:5)
    
        val     n
      <int> <int>
    1     5    15
    2     2    13
    3     4    11
    4     7    11
    5     8    11
    

    【讨论】:

      【解决方案3】:

      使用base 包:

      set.seed(1)
      example <- matrix(sample(101:110, 500, replace = TRUE), nrow = 50)
      # changed 1:10 to 101:110; changed 100 to 500 and nrow = 10 to 50
      
      mostFreqVals <- function(x,k) {
          tbl <- table(x)
          as.integer(names(tbl)[order(-tbl)][1:k])
      }
      apply(example, 2, mostFreqVals, k=3)  # change k to 5, 10 or whatever
      # 1st column is c(108,107,104)
      

      您可以手动验证以上代码。

      # -- Verify the first column --
      table(example[,1])
      # 101 102 103 104 105 106 107 108 109 110 
      #   3   4   5   6   5   4   7   8   4   4 
      # Frequency order: 108, 107, 104, (103, 105), ...
      # You need tie-breaking.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-03
        • 2018-09-27
        • 2015-02-21
        • 2021-04-10
        相关资源
        最近更新 更多