【问题标题】:Sort matrix (or data.frame) on amount of unique values per column根据每列唯一值的数量对矩阵(或 data.frame)进行排序
【发布时间】:2013-02-21 03:24:35
【问题描述】:

如何在data.frame 中的reorder 列上计算每列的唯一值总数?举个例子:

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)的解决方案,与是否有列名无关。

【问题讨论】:

  • 您是在询问重新排序列还是排序列?
  • 重新排列列,我会更新。
  • Dualinity,我已经编辑了帖子以澄清一些事情。
  • 谢谢,您提出了一个更笼统、更恰当的问题。

标签: r sorting dataframe matrix


【解决方案1】:

这样的?

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

编辑:您在帖子中的示例似乎有列名,但您在 cmets 中提供的这个没有。请确保正确生成示例。

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

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

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

【讨论】:

  • +1 啊,比你快 16 秒,但答案不是很好!
  • 我得到一个空矩阵
  • 你的矩阵有column names吗?
  • X &lt;- cbind(1, rnorm(10), 1:10)
  • 是的,我的错。我只是添加名称以便能够更轻松地解释事情,但我想它会改变问题。谢谢。
【解决方案2】:

另一个使用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

EDIT测试性能:

我在一个有 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-16
    • 2019-03-28
    • 2015-10-12
    • 2014-01-22
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多