每列最频繁的元素

时间:2019-04-27 06:45:24

标签: r matrix stata

我有以下矩阵:

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是变量名。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

使用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.

答案 2 :(得分:0)

可以在这样的基础上完成

 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)))
相关问题