对每列唯一值的数量排序矩阵(或data.frame)

时间:2013-03-06 11:04:14

标签: r sorting dataframe matrix

如何reorder data.frame列中每列唯一值的总量?举个例子:

var1 var2 var3
  1    1   1
  0    2   2
  1    3   3
  0    4   1
  1    5   2

有没有办法像var2, var3, var1那样自动重新排序(因为唯一值的长度分别为5,3和2,或相反,2 3 5)?

在这种情况下,获得我们想要的东西并不困难,但在我的情况下,我有很多专栏。有没有办法自动进行这种排序?

另外,我希望有一个适用于matrix的解决方案(除data.frame之外),与是否有列名无关。

2 个答案:

答案 0 :(得分:7)

这样的东西?

df[names(sort(sapply(df, function(x) length(unique(x))), decreasing = TRUE))]

#   var2 var3 var1
# 1    1    1    1
# 2    2    2    0
# 3    3    3    1
# 4    4    1    0
# 5    5    2    1

如果您的输入是matrix,那么:

m[, names(sort(apply(m, 2, function(x) 
       length(unique(x))), decreasing = TRUE))] 

应该有用。

#      var2 var3 var1
# [1,]    1    1    1
# [2,]    2    2    0
# [3,]    3    3    1
# [4,]    4    1    0
# [5,]    5    2    1

修改:帖子中的示例似乎有列名,但是您在评论中提到的这个名称却没有。请确保正确生成示例。

X <- cbind(1, rnorm(10), 1:10)

由于您不能指望列名,因此您必须返回索引。试试这个(当然,如果你有列名,它会起作用):

m[, sort(apply(X, 2, function(x) 
         length(unique(x))), decreasing = TRUE, index.return = TRUE)$ix]

答案 1 :(得分:5)

使用order

的另一种解决方案
dat[,order(apply(dat,2,function(x) length(unique(x))),decreasing = TRUE)]
  var2 var3 var1
1    1    1    1
2    2    2    0
3    3    3    1
4    4    1    0
5    5    2    1

现在,如果我们删除了colnames,我们就会得到一个好的结果但是有一个警告

 colnames(dat) <- NULL
 dat[,order(apply(dat,2,function(x) length(unique(x))),decreasing = TRUE)]
  NA NA NA
1  1  1  1
2  2  2  0
3  3  3  1
4  4  1  0
5  5  2  1

编辑测试效果:

我在1000列的矩阵上进行测试。 2个解决方案时间具有可比性,order略有增益。

X <- matrix(rnorm(100*1000),ncol=1000,nrow=100)
Arun <- function() X[, sort(apply(X, 2, function(x) 
  length(unique(x))), decreasing = TRUE, index.return = TRUE)$ix]

AgStudy <- function()  X[,order(apply(X,2,function(x) length(unique(x))),decreasing = TRUE)]

library(microbenchmark)

microbenchmark(Arun(),AgStudy())

Unit: milliseconds
       expr      min       lq   median       uq      max
1 AgStudy() 28.04634 32.37105 34.73820 36.49930 129.6048
2    Arun() 31.15476 32.97180 36.24027 37.91584 132.3871