如何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
之外),与是否有列名无关。
答案 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