如何有效地计算每列 R 中的唯一值数量

how to count number unique values in each column, R, efficiently

我的目标是查找我的数据框中每一列有多少个唯一值,这是我想出的结果

### df is a data frame, 32 named columns, millions of rows 

test1 <- sapply(df, function(x) length(unique(x)))

### I get a named integer from the above command 

test2 <- data.frame(names(test1), test1)

### now I get a data frame, with row names

row.names(test2) <- NULL

### to get rid of the row names 

test3 <- test2[order(test1),]

### finally I get a what I want     

我的问题是,如何以更少的步骤完成此操作???

我不确定这是否是您想要的。 请提供您的数据集样本(dput

假设您要计算数据 mtcars 的唯一值的数量。

library(tidyr)
library(dplyr)

mtcars %>% 
  gather() %>% 
  group_by(key) %>% 
  summarise( ndist = n_distinct(value) ) %>% 
  arrange(desc(ndist))  

这会给你

    key ndist
1  qsec    30
2    wt    29
3  disp    27
4   mpg    25
5    hp    22
6  drat    22
7  carb     6
8   cyl     3
9  gear     3
10   vs     2
11   am     2

基数 R 中的一次调用:

#using the same column names as in your example
test1 <- data.frame(names.test1 = colnames(mtcars), 
                    test1=sapply(mtcars, function(x) length(unique(x))),
                    row.names=NULL)

输出:

> test1
   names.test1 test1
1          mpg    25
2          cyl     3
3         disp    27
4           hp    22
5         drat    22
6           wt    29
7         qsec    30
8           vs     2
9           am     2
10        gear     3
11        carb     6

这将需要手动排序,尽管@BenBolker 在评论中提到:

test1 <- test1[order(test1$test1),])

但是,您可以使用 data.table:

做一个有序的单行
library(data.table)
test1 <- data.table(names.test1 = colnames(mtcars), 
                    test1=sapply(mtcars, function(x) length(unique(x))),
                    key='test1')

> test1
    names.test1 test1
 1:          vs     2
 2:          am     2
 3:         cyl     3
 4:        gear     3
 5:        carb     6
 6:          hp    22
 7:        drat    22
 8:         mpg    25
 9:        disp    27
10:          wt    29
11:        qsec    30

这就是你的意思吗?

    test1 <- sort(sapply(df, function(x) length(unique(x))), decreasing = T)
    data.frame(names(test1), test1, row.names = NULL)