按每列唯一值的数量对矩阵(或数据框)进行排序

4
如何按照每列唯一值的总数重新排列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)?
在这种情况下,获取我们想要的内容并不难,但在我的情况下,我有很多列。有没有一种自动执行此类排序的方法?
此外,我更喜欢使用适用于矩阵的解决方案(除了适用于data.frame之外),无论是否有列名。

你是在询问重新排列列还是对它们进行排序 - Arun
重新排列列,我会更新。 - PascalVKooten
Dualinity,我已经编辑了帖子以澄清一些事情。 - Arun
谢谢,你把它变成了一个更普遍、合适的问题。 - PascalVKooten
2个回答

7

Something like this?

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

如果您的输入是一个矩阵,则:
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]

2
+1 哎呀,我比你快了16秒,但答案不对! - juba
我得到了一个空矩阵。 - PascalVKooten
你的矩阵有“列名”吗? - Arun
X <- cbind(1, rnorm(10), 1:10) - PascalVKooten
是的,我的错。我只是添加了这些名称以便更容易地解释事情,但我想这改变了问题。谢谢。 - PascalVKooten

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(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列的矩阵上进行测试。两种解决方案的时间相当,但 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接